Se connecter avec
S'enregistrer | Connectez-vous

Consolidation qui plante

Dernière réponse : dans Programmation

Bonjour à tous,
Je reviens avec ma macro consolidation et un nouveau pb.

Je consolide environ 50 fichiers avec le code ci-dessous. Le souci est que je dois avoir atteint une certaine limite, parce qu'il ne fonctionne plus correctement. Il me fait la première zone nickel ("estimé") mais les 3 autres ne sont pas faites correctement voire pas du tout (mauvais chiffres comparés avec une autre méthode). Je dois donc faire ces zones une par une (6 mn à chaque fois) pour avoir les bonnes données...

Et il y a pas 5mn, je viens de me rendre compte que si j'arrête la macro disons au bout de 1mn, mes chiffres sont consolidés et sont bons.. incroyable, non ?!

Quelqu'un aurait-il une idée de la source du pb ?? Jusqu'à combien de fichiers peut-on consolider d'un coup?

Merci d'avance pour vos éclairages.

  1. Option Explicit
  2.  
  3. Private Sub CommandButton1_Click()
  4. Dim Chemin As String, pays_source As String, i As Integer, j As Integer
  5. 'Boucler sur les fichiers pays du répertoire
  6. Chemin = ActiveWorkbook.Path
  7. pays_source = Dir(Chemin & "\" & "* 3 YP by CBU.xls")
  8.  
  9. Application.ScreenUpdating = False
  10. Do While pays_source <> ""
  11. 'Estimé
  12. Range("C13:X50").Consolidate Sources:= _
  13. "'" & Chemin & "\" & "[* 3 YP by CBU.xls]TAX'!R66C3:R103C24", _
  14. Function:=xlSum
  15.  
  16. 'Budget
  17. Range("Z13:AU50").Consolidate Sources:= _
  18. "'" & Chemin & "\" & "[* 3 YP by CBU.xls]TAX'!R66C26:R103C47", _
  19. Function:=xlSum
  20.  
  21. '2011-2012
  22. Range("AW13:BR50").Consolidate Sources:= _
  23. "'" & Chemin & "\" & "[* 3 YP by CBU.xls]TAX'!R66C49:R103C70", _
  24. Function:=xlSum
  25.  
  26. '2012-2013
  27. Range("BT13:CO50").Consolidate Sources:= _
  28. "'" & Chemin & "\" & "[* 3 YP by CBU.xls]TAX'!R66C72:R103C93", _
  29. Function:=xlSum
  30. Loop
  31. 'effacer les pourcentages apparus
  32. For i = 0 To 4
  33. For j = 0 To 4
  34. Range(Cells(13, 2 * i + 23 * j + 15), Cells(37, 2 * i + 23 * j + 15)).ClearContents
  35. Next
  36. Next
  37. Application.ScreenUpdating = True
  38. End Sub

Autres pages sur : consolidation plante

Lassé par la pub ? Créez un compte

Meilleure solution

Expert Programmation

C'est presque très bien fait.
Il manque le On Error GoTo 0 pour remettre les choses en place à l'issue et surtout, il faut sortir l'instruction On Error Resume Next de la boucle, juste avant le Do.

Mais sinon, qu'est-ce que c'est moche. Beurk. :vomi: 
Faire planter l'application exprès ! :pfff: 

  1. Option Explicit
  1. Function EstOuvert(wb_name As String) As Boolean
  2. Dim wb As Workbook
  3. EstOuvert = False
  4.  
  5. For Each m_wb In Workbooks
  6. If wb.Name = wb_name Then
  7. EstOuvert = True
  8. Exit For
  9. End If
  10. Next
  11. End Function
  1. Private Sub Workbook_BeforeClose(Cancel As Boolean)
  2. Dim pays_source As String, wb As Workbook, ouvert As Boolean
  3.  
  4. pays_source = Dir(ActiveWorkbook.Path & "\" & "* 3 YP by CBU.xls")
  5. Do While pays_source <> ""
  6. If EstOuvert("pays_source") Then Workbooks(pays_source).Close
  7. pays_source = Dir()
  8. Loop
  9. End Sub


Ce n'est pas comme si ce n'était pas un problème récurrent. Ici, la même chose mais pour les feuilles !

BSalut Zeb, le forum,
c'est assez incroyable.

Bon comme je ne me laisse pas abattre, j'ai essayé autre chose! J'ai repris en partie le code que tu avais posté Zeb sur un ancien topic a propos de la macro consolidation. Elle marche bien, les chiffres sont consolidés correctement pour les 4 périodes. Mais du coup j'aimerais l'améliorer.

Ah et oui, les lignes 35à 38 ne s'éxecutent pas. Ma macro s'arrête sur le dernier fichier ouvert, du coup je reste avec mes 50 fichiers ouverts ! Por que?

  1. Option Explicit
  2.  
  3. Private Sub CommandButton5_Click()
  4. Dim Chemin As String, pays_source As String, i As Integer, j As Integer
  5. 'Boucler sur les fichiers pays du répertoire
  6. Chemin = ActiveWorkbook.Path
  7. pays_source = Dir(Chemin & "\" & "* 3 YP by CBU.xls")
  8.  
  9. Application.ScreenUpdating = False
  10. Do While pays_source <> ""
  11. Workbooks.Open Chemin & "\" & pays_source
  12. pays_source = Dir()
  13. Loop
  14.  
  15. 'Estimé
  16. Range("C13:X50").Consolidate Sources:= _
  17. "'" & Chemin & "\" & "[* 3 YP by CBU.xls]OMB'!R66C3:R103C24", _
  18. Function:=xlSum
  19.  
  20. 'Budget
  21. Range("Z13:AU50").Consolidate Sources:= _
  22. "'" & Chemin & "\" & "[* 3 YP by CBU.xls]OMB'!R66C26:R103C47", _
  23. Function:=xlSum
  24.  
  25. '2011-2012
  26. Range("AW13:BR50").Consolidate Sources:= _
  27. "'" & Chemin & "\" & "[* 3 YP by CBU.xls]OMB'!R66C49:R103C70", _
  28. Function:=xlSum
  29.  
  30. '2012-2013
  31. Range("BT13:CO50").Consolidate Sources:= _
  32. "'" & Chemin & "\" & "[* 3 YP by CBU.xls]OMB'!R66C72:R103C93", _
  33. Function:=xlSum
  34.  
  35. Do While pays_source <> ""
  36. Workbooks(pays_source).Close
  37. pays_source = Dir()
  38. Loop
  39. Application.ScreenUpdating = False
  40. For i = 0 To 4
  41. For j = 0 To 4
  42. Range(Cells(13, 2 * i + 23 * j + 15), Cells(37, 2 * i + 23 * j + 15)).ClearContents
  43. Next
  44. Next
  45. Application.ScreenUpdating = True
  46. End Sub

Donc j'aimerais faire un appel de "procedure générale" a savoir 'louverture des fichiers. Comme ça, une fois ouverts, je peux faire marcher mes 4 macros (sur 4 feuilles différentes). Je place ça sur "Thisworkbook" ? ou sur un module ?

Xie xie (pour diversifier)
Expert Programmation

Mais qu'est-ce que tu fiches ? Ta boucle commencée ligne 10 (Do..) devrait s'arrêter ligne 38 (Loop...). Or Ligne 13 tu l'arrêtes, et ligne 35 tu la recommences, dans le vide, forcément. Relis ton code.

Quand on gère plusieurs feuilles, plusieurs classeurs, on précise systématiquement le classeur et la feuille !

Fais des sous-procédures pour te simplifier la vie. Ça allonge le code, mais ça le rend plus compréhensible. N'ai-je pas déjà dit de simplifier chaque gros problème en petits problèmes, puis de les résoudre un par un.

  1. Sub ConsolideClasseur(nomfichier As String, nomsources As String)
  2. Dim wb As Workbook
  3. Dim ws As Worksheet
  4.  
  5. Set wb = Workbooks.Open(nomfichier)
  6. Set ws = wb.Worksheets(1)
  7.  
  8. ' // Estimé, Budget, 2011-2012, 2012-2013
  9. ws.Range("C13:X50" ).Consolidate Sources:= "'" & nomsources & "'!R66C3:R103C24", Function:=xlSum
  10. ws.Range("Z13:AU50" ).Consolidate Sources:= "'" & nomsources & "'!R66C26:R103C47", Function:=xlSum
  11. ws.Range("AW13:BR50" ).Consolidate Sources:= "'" & nomsources & "'!R66C49:R103C70", Function:=xlSum
  12. ws.Range("BT13:CO50" ).Consolidate Sources:= "'" & nomsources & "'!R66C72:R103C93", Function:=xlSum
  13.  
  14. wb.Close SaveChanges:=True
  15. End Sub
  1. Dim Chemin As String
  2. Chemin = ActiveWorkbook.Path
  3. pays_source = Dir(Chemin & "\" & "* 3 YP by CBU.xls" )
  4. Do While pays_source <> ""
  5. ConsolideClasseur pays_source, Chemin & "\" & "[* 3 YP by CBU.xls]OMB"
  6. pays_source = Dir()
  7. Loop

Bonsoir bonsoir
Alors voila ce que j'ai fait:
- j'ai crée un bouton "ouvrir les fichiers" dans chaque feuille. J'ai normalement à l'utiliser 1 seule fois ET ensuite je consolide.
- j'ai fait une procedure evenementielle: a la sortie de mon classeur consolidé, hop la je ferme tous les classeurs source.

Exemple pour 1 feuille (parmi lles 4)
  1. Option Explicit
  2.  
  3. Private Sub CommandButton2_Click()
  4. Dim Chemin As String, pays_source As String
  5. 'Boucler sur les fichiers pays du répertoire
  6. Chemin = ActiveWorkbook.Path
  7. pays_source = Dir(Chemin & "\" & "* 3 YP by CBU.xls")
  8.  
  9. Application.ScreenUpdating = False
  10. If MsgBox("Ceci va ouvrir tous les fichiers pays Phase 1. Continuer ?", vbYesNo) <> vbYes Then
  11. Exit Sub
  12. End If
  13. Do While pays_source <> ""
  14. Workbooks.Open Chemin & "\" & pays_source
  15. pays_source = Dir()
  16. Loop
  17. Application.ScreenUpdating = True
  18. End Sub
  19.  
  20. Private Sub CommandButton1_Click()
  21. Dim Chemin As String, pays_source As String, i As Integer, j As Integer
  22. 'Boucler sur les fichiers pays du répertoire
  23. Chemin = ActiveWorkbook.Path
  24. pays_source = Dir(Chemin & "\" & "* 3 YP by CBU.xls")
  25.  
  26. Application.ScreenUpdating = False
  27. Do While pays_source <> ""
  28.  
  29. 'Estimé
  30. Range("C13:X50").Consolidate "'" & Chemin & "\" & "[* 3 YP by CBU.xls]TAX'!R66C3:R103C24", xlSum
  31.  
  32. 'Budget
  33. Range("Z13:AU50").Consolidate "'" & Chemin & "\" & "[* 3 YP by CBU.xls]TAX'!R66C26:R103C47", xlSum
  34.  
  35. '2011-2012
  36. Range("AW13:BR50").Consolidate "'" & Chemin & "\" & "[* 3 YP by CBU.xls]TAX'!R66C49:R103C70", xlSum
  37.  
  38. '2012-2013
  39. Range("BT13:CO50").Consolidate "'" & Chemin & "\" & "[* 3 YP by CBU.xls]TAX'!R66C72:R103C93", xlSum
  40.  
  41. pays_source = Dir()
  42. Loop
  43.  
  44. For i = 0 To 4
  45. For j = 0 To 4
  46. Range(Cells(13, 2 * i + 23 * j + 15), Cells(37, 2 * i + 23 * j + 15)).ClearContents
  47. Next
  48. Next
  49. Application.ScreenUpdating = True
  50. End Sub

Et fermeture
  1. Option Explicit
  2.  
  3. Private Sub Workbook_BeforeClose(Cancel As Boolean)
  4. Dim Chemin As String, pays_source As String
  5. 'Boucler sur les fichiers pays du répertoire
  6. Chemin = ActiveWorkbook.Path
  7. pays_source = Dir(Chemin & "\" & "* 3 YP by CBU.xls")
  8.  
  9. 'If workbooks(pays_source) = open Then
  10. Do While pays_source <> ""
  11. Workbooks(pays_source).Close
  12. pays_source = Dir()
  13. Loop
  14. End If
  15. End Sub
Pour la fermeture, j'ai un souci ligne 9. Si je n'ai aucun fichier source ouvert (consultation simple de mon fichier), bé ça plante! normal. Comment eviter cela ? (du style a si un pays_source est ouvert, ferme le, sinon rien)

Sinon le reste marche, et la conso est quand même très rapide une fois que tous les classeurs sont ouverts.

Par contre je ne comprends toujours pas pourquoi, avec 10, 20, 30 classeurs source la fonction consolidate marchait très bien sans avoir à ouvrir les fichiers (et ça mettait 2-3mn à tout casser). Maintenant ça mets 10mn pour un travail imparfait :??: 

Merci à tous!

Expert Programmation

Ta fermeture ne peut pas fonctionner !
Il faut mettre le If dans la boucle Do While, m'enfin !

Pour vérifier si un classeur est ouvert :
  1. Dim wb As Workbook
  2. Dim ouvert As Boolean
  3.  
  4. ouvert = False
  5. For Each wb In Workbooks
  6. If wb.Name = "nom du classeur" Then
  7. ouvert = True
  8. Exit For
  9. End If
  10. Next

Bonjour le forum,

Merci Zeb pour cet indice. J'ai essayé et reéssayé de me servir de ton dernier post, mais pas moyen d'aboutir à qqch de bon.
Soit je n'avais qu'un seul fichier "pays" pris en compte (le premier de la boucle), soit rien du tout.
Egalement en utilisant "wb.Name", c'est d'abord "Me" qui entre dans la boucle et qu'il faut donc exclure. Mais après je n'arrivais pas à boucler sur les fichiers pays ouverts.

Donc j'ai fais ça et ça marche !!
  1. Option Explicit
  2.  
  3. Private Sub Workbook_BeforeClose(Cancel As Boolean)
  4. Dim Chemin As String, pays_source As String, wb As Workbook, ouvert As Boolean
  5. 'Boucler sur les fichiers pays du répertoire
  6. Chemin = ActiveWorkbook.Path
  7. pays_source = Dir(Chemin & "\" & "* 3 YP by CBU.xls")
  8.  
  9. Application.ScreenUpdating = False
  10. Do While pays_source <> ""
  11. On Error Resume Next
  12. Workbooks(pays_source).Close
  13. pays_source = Dir()
  14. Loop
  15. Application.ScreenUpdating = True
  16. End Sub
Est-e que ça à l'air bon, ou mélange des genres ?
Merci

Salut salut
Bon ben écoute Zeb, comme d'hab (je peux maintenant le dire), c'est nickel, ça marche aussi très bien. *Du bon boulot !* :sol: 

Quand tu dis que c'est moche (cf ton dernier post), qu'est ce qui ne va pas dans "l'esthetique" du code?
Expert Programmation

Pour sortir de chez toi, tu pètes toutes les portes, y compris les portes de placard et tu regardes ce qu'il y a derrière ou tu réfléchis en te disant qu'avec la clef de la porte d'entrée, ça peut suffire ?
:D 

En fait, dans ton code, tu fais planter l'application exprès et ensuite tu gères l'erreur. Sauf que globalement, c'est une façon très moche de faire. Imagine qu'une erreur autre que celle que tu penses gérer survienne ? Par exemple, Workbooks(pays_source).Close pourrait planter non parce que le classeur n'existe pas, mais parce qu'une modif a été apportée, qu'il faut enregistrer et que le disque est plein, ou autre. Bref, tu ne gères en fait plus rien, tu passes outre ! C'est moche, quoi.

Une bonne façon de programmer, c'est d'accepter le Pire c'est mieux. C'est une façon de considérer que l'élégance du code consomme beaucoup de temps et donc d'argent, et qu'il faut mieux faire un truc crade mais qui marche dans 99% des cas, plutôt que d'attendre la perfection. Pour le 1% restant, un expert règlera le problème à prix d'or certes, mais si rarement qu'on rentrera dans les frais.

Ceci est donc à réserver à ceux qui programment très bien et depuis fort longtemps. Car il faut savoir éviter de nombreux pièges, souvent récurrents pour atteindre un niveau de % de risque honnête.

A suivre ce bon principe, le débutant négligeant économisera sa peine et produira rapidement et à moindre coût un programme qui marchera à ... 9%. Il faudra soit payer pour tout refaire, soit s'attacher les services d'un expert fort coûteux pour gérer les innombrables erreurs - c'est mon job actuel [:patch]

Donc si tu veux continuer à profiter de mes conseils, je te propose d'oublier un temps le worse is better, et d'apprendre à faire les choses proprement, ou du moins à le me laisser croire ;) 

En voilà de sages paroles. Je reconnais bien là l'attachement de l'expert pedadgogue à diffuser son message de "bien faire et proprement s'il vous plait" !
Je suis egalement partisan du travail bien fait, donc tant qu'à faire, une ptite question un peu naïve du débutant que je suis ne fait pas de mal pour recadrer le contexte et faire avancer les choses :) 
Merci du conseil avisé, pour ma part, je vais m'attacher à appliquer le concept du faire bien tout court!


zeb a dit :
A suivre ce bon principe, le débutant négligeant économisera sa peine et produira rapidement et à moindre coût un programme qui marchera à ... 9%. Il faudra soit payer pour tout refaire, soit s'attacher les services d'un expert fort coûteux pour gérer les innombrables erreurs - c'est mon job actuel [:patch]


Oui, mais si tous les débutants font directement les choses proprement, il n'y aura plus de boulot pour toi Zeb, ou alors tu deviendras beaucoup moins coûteux :lol:  :lol: 
Lassé par la pub ? Créez un compte