MACRO - Problème de restitution d'un tableau mémoire
Bonjour à tous,
Tout d'abord, je vais commencer par remercier l'intégralité des personnes actives de ce site. J'ai pendant plusieurs années été un grand lecteur des problèmes et des solutions proposées par la plupart d'entre vous. Ce n'est qu'aujourd'hui que j'ai ouvert un compte utilisateur puisque je me heurte à un problème auquel je ne trouve aucune solution...
Avant de poursuivre, je vais vous expliquer brièvement le but de la macro que j'essaye de faire fonctionner. Cette macro, toute simple, met en mémoire un tableau (appelons le Tableau1), ouvre un autre fichier excel, met en mémoire un autre tableau (Tableau2) et effectue des renseignements de valeurs du Tableau2 vers le Tableau1. Une fois l'intégralité de Tableau1 balayé, la macro restitue les données mise en mémoire en dur, dans le fichier lui même.
Pour information, la macro appelée en début de ce code et nommée "DECLARATIONS.VARIABLES_PUBLIQUES" est une macro qui recherche le nom des en-têtes de colonne à l'aide d'une fonction .Find. Cela permet de "variabiliser" les numéro de colonne sans avoir à déclarer les numéros eux mêmes en début de macro, et aussi de rajouter ou déplacer des colonnes à convenance sans contraintes (dés lors que le nom des en-têtes sont respectés). Cette macro fonctionne très bien et assigne tous les numéro de colonne au bonnes colonnes, le problème ne vient donc pas de là.
Voici le code de cette macro:
Sub HISTORIQUES_INVENTAIRES()
Dim ADRESSE_FICHIER, NOM_FICHIER, NOM_APPRO, TYPE_FICHIER, MATRICE, HISTORIQUE, FirstAddress As Variant
Dim COMPTEUR_MATRICE As Long, COMPTEUR_HISTORIQUE As Long, OCCURENCE As Integer
Call DECLARATIONS.VARIABLES_PUBLIQUES
'=====================================================================================
'IMPORTATION DES INFORMATIONS RELATIVES AUX INVENTAIRES DEPUIS L'HISTORIQUE INVENTAIRE
'=====================================================================================
ADRESSE_FICHIER = ThisWorkbook.Sheets("PARAMETRES").Cells(13, 5)
NOM_FICHIER = ThisWorkbook.Sheets("PARAMETRES").Cells(13, 17)
TYPE_FICHIER = ThisWorkbook.Sheets("PARAMETRES").Cells(13, 19)
ThisWorkbook.Sheets("MATRICE").Activate
MATRICE_LAST_L = ThisWorkbook.Sheets("MATRICE").Range("A1048576").End(xlUp).Row
MATRICE_LAST_C = ThisWorkbook.Sheets("MATRICE").Range("A9").CurrentRegion.Columns.Count
MATRICE = Range(Cells(1, MATRICE_REFERENCE), Cells(10000, MATRICE_LAST_C)).Value
OCCURENCE = 0
[i]'OUVRE LE FICHIER HISTORIQUE INVENTAIRE[/i]
Historique_Inventaire = ADRESSE_FICHIER & NOM_FICHIER & TYPE_FICHIER
Set H_I = Workbooks.Open(Historique_Inventaire, ReadOnly:=True)
HISTORIQUE_LAST_L = Range("A" & Rows.Count).End(xlUp).Row + 1
HISTORIQUE = ActiveWorkbook.Sheets("historique inventaire").Range("A2:N" & HISTORIQUE_LAST_L).Value
With Range(Cells(2, 1), Cells(HISTORIQUE_LAST_L, 1))
[i]'DEBUTE LA BOUCLE DE RECHERCHE DES INVENTAIRES PAR REFERENCE
[/i]
For COMPTEUR_MATRICE = 9 To MATRICE_LAST_L
For COMPTEUR_HISTORIQUE = 2 To HISTORIQUE_LAST_L - 1
If Val(HISTORIQUE(COMPTEUR_HISTORIQUE, 1)) = MATRICE(COMPTEUR_MATRICE, MATRICE_REFERENCE) Then
OCCURENCE = OCCURENCE + 1
MATRICE(COMPTEUR_MATRICE, MATRICE_NB_INV) = OCCURENCE
If HISTORIQUE(COMPTEUR_HISTORIQUE, 13) > MATRICE(COMPTEUR_MATRICE, MATRICE_DDI) Then
MATRICE(COMPTEUR_MATRICE, MATRICE_DDI) = HISTORIQUE(COMPTEUR_HISTORIQUE, 13)
MATRICE(COMPTEUR_MATRICE, MATRICE_REDRESSEMENT) = HISTORIQUE(COMPTEUR_HISTORIQUE, 8)
End If
End If
Next COMPTEUR_HISTORIQUE
OCCURENCE = 0
If COMPTEUR_MATRICE = MATRICE_LAST_L Then GoTo 1
Next COMPTEUR_MATRICE
End With
1 ThisWorkbook.Sheets("MATRICE").Activate
[b]Range(Cells(1, MATRICE_REFERENCE), Cells(10000, MATRICE_LAST_C)).Value = MATRICE[/b]
[i]'DATE DE DERNIER IMPORTATION DE L'HISTORIQUE INVENTAIRE = AUJOURD'HUI[/i]
ThisWorkbook.Sheets("PARAMETRES").Cells(35, 19) = Date
[i]'FERMETURE DE L'HISTORIQUE INVENTAIRE[/i]
H_I.Saved = False
H_I.Close SaveChanges:=False
End SubLe problème intervient à la ligne en gras. Lors de la restitution des données, une erreur 1004 "Erreur définie par l'application ou par l'objet." apparaît. Lorsque je regarde ce qu'il en est dans mon tableau1, les valeurs ont bien été restituées mais seulement jusqu'à la ligne 3296 (sur 5296). Et c'est là que la cause du problème est introuvable et que je m'en remets aux idées brillantes pas d'entre vous.
J'espère avoir été assez éloquent dans mon explication et répondrait à toutes vos questions pour faire avancer ce problème.
Merci par avance !
Excellement, Tobi
Bonjour Tobi et bienvenue sur le forum,
Si ta macro tourne sur près de 4.000 lignes je pense qu'il sera extrêmement difficile de t'aider à la débeuger sans avoir un fichier sous la main. Néanmoins, je te propose de réaliser les actions suivantes afin d'essayer de comprendre ce qui ne fonctionne pas.
1) Ajoute plusieurs espions sur les éléments suivants
- MATRICE(3295)
- MATRICE(3296)
2) Mets un point d'arrêt sur la ligne qui pose problème (pour cela il suffit de placer le curseur sur la ligne et d'appuyer sur la touche F9. Un point rouge apparaîtra sur la gauche de la ligne.
3) Lancer le programme et regarder le contenu de ton tableau à ces deux lignes.
Si tu as absolument besoin de faire tourner cette macro, tu peux temporairement remplacer la ligne actuelle beugée par une ligne du type:
Dim i as Long, j as Long
For i = LBound(MATRICE,1) to UBound(MATRICE,1)
For j = LBound(MATRICE,2) to UBound(MATRICE,2)
Cells(i + ..., j + ....).Value = MATRICE(i,j)
Next j
Next iBonjour,
N'ajoute pas d'autres mises en forme dans la mise en forme Code, il nous faut les enlever une par une.
Je suis étonné qu'il ne t'inscrive pas qu'une seule valeur. Il faut tailler la plage destination.
Essaie avec :
Range(Cells(1, MATRICE_REFERENCE), Cells(10000, MATRICE_LAST_C)).Resize(UBound(MATRICE, 1), UBound(MATRICE, 2)).Value = MATRICEeric
edit: en fait non.
Range(Cells(1, MATRICE_REFERENCE), Cells(10000, MATRICE_LAST_C)) devrait bien désigner la plage
bonjour
essayer de vérifier la déclaration de tableau en cause
essayer par msgbox uBound(tableau)
@ AMIR: Merci pour cette réponse. Un UBound(tableau) me reporte bien la dernière ligne active du tableau (la 10000ème), mais j'ai bien souvent moins de 10000 lignes comportant des valeur à traiter.
@eriiic: Merci pour cette bonne idée. Je n'avais pas pensé au Resize pour augmenter ma plage de valeur mais malheureusement l'erreur est la même. La restitution des valeurs bloque à la 3296ème ligne et la 1004 réapparaît...
@d3d9x: Vous êtes mon sauveur d'aujourd'hui ! Merci aussi pour votre réponse et l'explication associée.
J'avais déjà effectué un step by step qui m'avait permit de voir que les renseignements de valeurs se font pour chaque ligne du Tableau1, 3296, 3297 et le reste également. C'était vraiment au moment de basculer les valeurs mise en mémoire en dur sur le fichier que la 1004 apparaissait.
Cependant le code que vous m'avez proposé m'a permit de mettre en évidence la source de l'erreur:
Dim i as Long, j as Long
For i = LBound(MATRICE,1) to UBound(MATRICE,1)
For j = LBound(MATRICE,2) to UBound(MATRICE,2)
Cells(i + ..., j + ....).Value = MATRICE(i,j)
Next j
Next iAvec ce code, j'ai pu observé sur quelle cellule exactement l'erreur survenait. Il s'avère que c'était un problème vraiment sournois. Une ligne entière était au format date mais écrit en 41XXX et non en JJ/MM/AA, ce qui était déjà difficilement décelable au milieu de plusieurs nombre. Si la macro n'arrivait pas à restituer les valeurs, c'est parce qu'elle devait effectuer plusieurs opérations entre deux nombres. Sauf que sur cette ligne, elle effectuait des opérations (type division) entre un nombre (au format standard) et un autre nombre (au format date). Je pense que c'est l'opération entre les deux formats distincts qui a généré mon erreur (erreur que je n'avais clairement jamais rencontré ni en pratique ni sur des forums).
Voilà, merci à tous de m'avoir aidé dans la résolution de ce problème et j'espère pouvoir vous rendre la pareil à l'avenir !
Excellement, Tobi