une instruction ultra basique ne s'excecute pas, sans message d'erreur. je craque >_<

insosama

XLDnaute Nouveau
bonjour

je seche depuis plusieurs jours sans trouver de bonne solution.
mon code bloque sur une broutille sans nom :

sh.Cells(RowCall, cl).value = MaVariable

Sh contenant un worksheet, rowcall et cl un integer désignant une ligne et une colonne. ma variable etant un variant (chaine de texte, nombre, on ne sait pas exactement ce que l'utilisateur utilisera)

en mode pas a pas, avec un espion, TOUTE ces variables sont bonnes / retourne ce qu'elles doivent retourner.

pourtant le code, arrivé sur cette ligne, cesse de s'executer et ne va jamais a la suivante, sans le moindre message d'erreur.
ce n'est pas non plus un soucis de boucle sans fin ou autre. je suis dans un simple for / next, et le code plante dès la premiere occurence.
j'ai un "option explicit", donc toute mes variables sont propre.
aucune gestion d'erreure, donc encore moins de "on error resume next".
aucun "goto".

comme a aucun moment j'utilise de "focus" différent (pas de select, pas d'activate, pas de copy paste, je désigne toujours les cellules, y compris d'autres pages, par leur références variable complete), le soucis a priori ne vient pas non plus d'ici. j'ai donc meme tenté de virer la référence a SH, puisque normalement ma page de calcul reste "la prioritaire". meme bilan.
j'ai isolé le code dans une nouvelle fonction (ne sachant plus quoi inventer)
meme bilan

je ne sais plus quoi inventer.



je vais détailler un peu plus le contenu du programme :
ce que je vous montre ici est la version condensé : elle présente l'ensemble des bouts de codes ou des structure appellante des fichiers excel, des range, etc ... existe. en gros, tout ce qui pourrait comporter des "select" caché ou autre qui posent soucis.
tout le reste du code est un traitement d'array qui n'a rien a voir avec excel. l'ensemble, a part la ligne incriminé, fonctionne PARFAITEMENT.
chaque variable contient à la fin (car la ligne de code est à la fin) ce qu'elle est sencé contenir.
l'ensemble du code se comporte scrupulesement comme je l'avais prévus.


j'initie mon code (qui est une fonction dans un module), par la sauvegarde de la source de la demande : ligne de la cellule ou la formule appellante est executé, worksheet (donc nom de la feuille et nom du fichier)

Code:
Dim sh As Worksheet
Dim RowCall As Integer

Set sh = Workbooks(Application.Caller.Worksheet.Parent.Name).Worksheets(Application.Caller.Worksheet.Name)
    RowCall = Application.Caller.Row

Application.Caller.Worksheet.Parent.Name => renvois le nom du fichier (nom seul)
Application.Caller.Worksheet.Name => renvois le nom de la page
Application.Caller.Row => renvois la ligne appellante (cellule ou se trouve la formule)

j'ai aussi tenté a un moment de ne pas sauvegarder un "worksheet", mais uniquement les noms.

Code:
Dim sh As string
dim Xl as string
Dim RowCall As Integer

    Xl = Application.Caller.Worksheet.Parent.Name
    sh = Application.Caller.Worksheet.Name
    RowCall = Application.Caller.Row

dans ce cas, plus tard, je tappais un workbooks(Xl).Worksheets(sh).cells(RowCall, cl).value = mavariable.
meme résultat.

s'ensuite ensuite un code ou je déclare un "adresse()". c'est un array, et c'est lui, mon "mavariable".
cet array est rempli a un certain moment en ouvrant nombre de fichier excel externe (qui ne sont a ce moment la pas ouvert).
chaque fichier est ouvert un a un, des données sont ajoutées dans des cellules. puis le calcul est lancé, et les résultat (contenu dans certaines cellules bien déterminé) est récupéré.

le adresse est un "array" de variable de type personnalisé. il contient notament un adresse().resultat() as variant qui comporte le résultat.
elle comporte aussi les référence des cellules et des fichiers qui doivent etre ouvert, qu'est ce qui doit etre ecrit, et ou, et ou doit etre récupéré le ou les résultat.
le premier array (adresse()) correspond a chaque fichier excel ouvert
le second (resultat()) correspond a chaque cellule extraite dans ce fichier (il peut donc y en avoir plusieurs)
d'autres arguments permettent de récuperer les adresse et le contenu des cellules a remplir, et les adresse des cellules a récuperer.
l'ensemble de ce scann est réalisé dans une fonction séparé, appelé donc par la fonction principale.
l'ensemble marche "au poil".

Code:
Public Function ImportData(adresse() As cellule)
    
    'ouvre chaque fichier excel, modifie dans chacune le contenue de toute les cellule consigne, puis sauve le résultat donné dans des cellule résultat.
    
    Dim oFSO As Scripting.FileSystemObject
    Dim i, j, lg, cl As Integer
    Dim NomFichier, NomTable As String
    Dim XlApp As Object
    Dim Feuille As Worksheet

    Set oFSO = New Scripting.FileSystemObject
    Set XlApp = CreateObject("excel.application")    
    
    For i = 1 To UBound(adresse)
        XlApp.Workbooks.Open adresse(i).DirFile 'l'adresse du fichier a ouvrir
        'on écrit les valeurs

            NomFichier = oFSO.GetFileName(adresse(i).DirFile) 'le nom du fichier seul. de type "monfichier.xls"
            NomTable = adresse(i).IndexTable(j) 'le nom de la table seule "feuill1" par exemple

        For j = 1 To adresse(i).nbin
            lg = adresse(i).ligne(j) 'la premiere cellule ou doit etre écrite une donnée
            cl = adresse(i).Colonne(j)
            XlApp.Workbooks(NomFichier).Worksheets(NomTable).Cells(lg, cl).value = adresse(i).valeur(j) 'on l'ecrit.
        Next

        'on lance le calcul sur chaque feuille. les fichiers excel cible devront en tenir compte.
        For Each Feuille In XlApp.Workbooks(oFSO.GetFileName(adresse(i).DirFile)).Worksheets
            Feuille.Calculate
        Next Feuille

        For j = 1 To adresse(i).nbout 'et maintenant on scann les cellules de résultat
            adresse(i).resultat(j) = XlApp.Workbooks(oFSO.GetFileName(adresse(i).DirFile)).Worksheets(adresse(i).IndexTable(j)).Cells(adresse(i).LigneResult(j), adresse(i).ColonneResult(j)).value
        Next

        XlApp.Workbooks(oFSO.GetFileName(adresse(i).DirFile)).Close False 'ferme sans demander d'enregistrer, et sans enregistrer.

    Next
    
    Set XlApp = Nothing 'on vide la variable
    
End Function


à ce stade, donc, adresse() contient plusieurs résultat.

ces résultat devraient ensuite normalement etre copié dans des cellules sur la meme ligne que la cellule contenant la formule (notez donc bien que la formule ne retourne pas ces résultat, puisqu'il y en a PLUSIEURS, mais les écrit dans d'autres cellule)

chaque resultat dispose aussi d'un "nom".
ce nom est cherché dans une plage de titre de colonne, pour trouver l'adresse complete (ligne de la formule, colonne portant le nom du résultat), puis le résultat est noté.

plage sortie est donc un range qui contient tout les titres des colonnes ou l'ont veu faire apparaitre les résultats.

je vous fait grace de certains calculs intermédiaire; ils sont normalement entre l'appel de la fonction "importdata", visible ci dessous, et entre les deux boucles suivantes.
cette partie du code fonctionne, mais je ne peu la montrer pour des raisons de confidentialité.
pour résumer rapidement, il s'agit tout simplement de grouper les résultats de plusieurs fichiers différents dans un résultat commun si ils portent le meme nom, en appliquant une regle mathématique selon une consigne (adition, max, moyenne, etc ...)



Code:
    ImportData adresse  

    'il y a ici des codes pour réorganiser les résultats normalement

    For i = 1 To UBound(adresse)
        'et ici aussi.
        For j = 1 To adresse(i).nbout

            Nom = adresse(i).NomResult(j)
            
            
            For Each cel In PlageSortie
                
                If cel.value = Nom Then
                    cl = cel.Column
                    sh.Cells(RowCall, cl).value = adresse(i).resultat(j)
                    Exit For
                End If
                
            Next
        Next
        
    Next
    
    
    Set sh = Nothing
    
End Function


c'est donc ici que ca coince :

sh.Cells(RowCall, cl).value = adresse(i).resultat(j)

toute la variable sont pourtant bonne
mais le code ne va pas plus loin.

voila, je vois pas quoi faire, ni ce qui pourrait en etre la cause. c'est l'angoisse.
planter sur un vulgaire cells(r,c). la base, quoi.


toute aide, idée, sacrifice de poulet un soir de pleine lune est bon a prendre.


cordialement.
 
Dernière édition:

insosama

XLDnaute Nouveau
Re : une instruction ultra basique ne s'excecute pas, sans message d'erreur. je craqu

oui, c'est un type personnalisé.
il a été verrifié, debuggé, il fonctionne.
en tout cas, peu avant la "fameuse ligne", un espion me permet d'attester que l'ensemble des valeurs attendue sont bien la ou ... attendu. donc que j'ai a priori aucun soucis avec ca.

c'est d'ailleurs ce qui est (etait, puisque j'ai contourné le soucis actuellement) rageant : tout fonctionne, seul l'affichage du résultat final pour l'utilisateur ne fonctionne pas.

meme si j'ai réglé le soucis, je suis toujours interressé pour savoir d'ou vient mon probleme. car j'ai solutionné en changeant mon cahier des charges initial. si je savais faire "comme c'etait prévu pour à l'origine", ca serait quand meme un sacré plus.

à l'origine, la cellule ou la formule se lance aurait du n'afficher qu'une copie des "inputs" et la date du dernier calcul valide. aujourd'hui j'ai ces infos, et plein d'autre, de sorte que c'est totalement illisible pour l'utilisateurs. il faut donc sacrifier des colonnes pour éclater les données a coup de "split".

concernant la structure :

Code:
public type cellule
     DirFile as string
     IndexTable(100) as variant
     ligne(100) as integer
     colonne(100) as integer
     valeur(100) as variant
     nbin as integer
     ligneresult(100) as integer
     colonneresult(100) as integer
     resultat(100) as variant
     nomresult(100) as variant
     nbout as integer
end type

l'adresse est donc un tableau de "cellule".
chaque cellule (qui porte un terme assez impropre, reste de mes premieres reflexion sur la macro) est en fait un fichier excel a ouvrir.
on trouve donc l'adresse du fichier, et, en gros, l'ensemble des données necessaires pour savoir ou écrire quoi, et ou chercher les résultat, avant de fermer le fichier.

c'est le role du début de la procédure de renseigner convenablement l'array de cellule nommé "adresse", avant de le lancer a une fonction qui n'a que pour but d'interpreter cet array et de le remettre à jour / actualiser avec les résultat souhaité.

le role donc de la fonction :
Public Function ImportData(adresse() As cellule)

comme je suis en byref, adresse est la fois ma variable "in" et "out" pour la fonction.

la fonction est totalement écrite dans mes premiers mails, ensuite.

et très rapidement, suite a un petit traitement de donnée (de donnée, ce n'est qu'un traitement de chaine de carra !) le résultat doit etre ensuite affiché, en scannant l'array "adresse" en en se concentrant sur le contenu des variables de résultat.
et c'est la que ca plante.

c'est le fonctionnement de "comment" j'entre les donnée dans cet array, et les petits traitement de chaine de carra que j'ai supprimé, qui sont réellement "innovant", et donc que je ne peu présenter ici.

toutefois, ils sont tout a fait indépendant d'excel, puisque ce n'est qu'un traitement d'array / de chaine "string", et ils fonctionnent parfaitement.
le soucis est quelque part dans ce que je montre ici.

peut etre lié a "l'import" qui fait perdre le focus non a la feuille, mais carrément a l'appli.
de toute les idée, je pense que c'est la plus pertinente.
comme je créé un objet "excel" puis je le vide en cours d'execution de tout le code
entre le début (ou le focus est sur la page ou se trouve la formule)
le milieux, ou je créé un objet excel, j'ouvre plein de page en "caché", que je ferme en mettant a jour "array", avant de vider l'objet excel
et la fin, ou le fait est que quoi que je fasse, je n'arrive plus a dialoguer avec excel ...
le plus logique est de penser qu'en vidant l'objet excel (voir dans la fonction dont on vient de parler) je vide aussi le "liens" avec le fichier d'origine

mais je ne sais pas faire autrement que charger de la sorte pour faire mon scann de fichier distant
il faut bien le vider, si on ne veu pas surcharger la mémoire betement
et je ne sais pas "recreer" un lien ensuite

la seule solution que je vois éventuellement, c'est de creer un objet excel dès le début de la fonction (celle de l'ensemble de la formule), qui pointe sur l'excel courrant. mais ca, je ne sais pas faire (mais ca doit etre pourtant faisable !)
puis de vider cet objet à la toute fin, c'est a dire ... apres la formule qui présentement ne fonctionne pas.

je pense que c'est a la fois la solution, et l'explication la plus probable de mon soucis.
MAIS je ne sais pas creer un objet excel pointant sur ... lui meme.

merci en tout cas pour ton interet.

cordialement.

cordialement.
 

PMO2

XLDnaute Accro
Re : une instruction ultra basique ne s'excecute pas, sans message d'erreur. je craqu

Bonjour,

Je ne suis pas en situation et cela m'est donc indébrouillable.
Je mets malgré tout un code qui n'est pas une piste mais plutôt un pied à l'étrier. S'il peut éveiller quelque chose et vous aider (???).
J'ai virer le FSO.
Bon courage.
Code:
Public Function ImportData(adresse() As cellule)

'ouvre chaque fichier excel, modifie dans chacune le contenue de toute les cellule consigne,
'puis sauve le résultat donné dans des cellule résultat.

'Dim oFSO As Object 'Scripting.FileSystemObject
Dim i As Long, j As Long, lg As Long, cl As Integer
Dim NomFichier, NomTable As String
Dim XlApp As Object
Dim Feuille As Worksheet

Dim WB As Workbook
Dim WS As Worksheet


'Set oFSO = New Scripting.FileSystemObject
Set XlApp = CreateObject("excel.application")

For i = 1 To UBound(adresse)
   Set WB = XlApp.Workbooks.Open(adresse(i).DirFile) 'l'adresse du fichier a ouvrir
    'on écrit les valeurs

        NomFichier = WB.Name 'oFSO.GetFileName(adresse(i).DirFile) 'le nom du fichier seul. de type "monfichier.xls"
        NomTable = adresse(i).IndexTable(j) 'le nom de la table seule "feuill1" par exemple '/// au premier passage de la boucle i    j=0 mais après ???

    For j = 1 To adresse(i).nbin
        lg = adresse(i).ligne(j) 'la premiere cellule ou doit etre écrite une donnée
        cl = adresse(i).colonne(j)
        WB.Worksheets(NomTable).Cells(lg, cl).Value = adresse(i).valeur(j) 'on l'ecrit.
    Next j

    'on lance le calcul sur chaque feuille. les fichiers excel cible devront en tenir compte.
    For Each Feuille In WB.Worksheets
        Feuille.Calculate
    Next Feuille

    For j = 1 To adresse(i).nbout 'et maintenant on scann les cellules de résultat
        adresse(i).resultat(j) = WB.Worksheets(adresse(i).IndexTable(j)).Cells(adresse(i).ligneresult(j), adresse(i).colonneresult(j)).Value
    Next j

    WB.Close False 'ferme sans demander d'enregistrer, et sans enregistrer.

Next i

XlApp.Quit
Set XlApp = Nothing 'on vide la variable

End Function
 

Discussions similaires

Statistiques des forums

Discussions
315 098
Messages
2 116 189
Membres
112 679
dernier inscrit
Yupanki