VBA, création d'une macro de mise à jour
Dernière réponse : dans Programmation
Bonjour à tous, au forum,
Alors voila, ça fait pas mal de temps que je suis les forums pour trouver des solutions à de menus problèmes sous excel ou autre. Cela à tout le temps été efficace, en cherchant on trouve quasiment tout le temps ce que l'on veut et même plus quelques fois.
Outil pratique, ce partage de connaissances est bénéfique pour tous! Merci à ceux qui le font vivre.
Mais là.. j'en appelle aux connaissances des chevronnés (ou pas) du VBA pour la construction d'une macro somme toute assez simpliste dans l'idée mais qui me pose des problèmes quant à sa programmation. Je suis débutant et je précise que j'ai envie d'apprendre et de comprendre surtout.
Donc, pour résumer:
- un erp me produit 10 rapports à la demande, sous format excel, correspondant à 10 pays différents pour les chiffres d'un mois.
- J'ai besoin de prendre les données de ces rapports (sans les ouvrir si possible) pour les coller dans un classeur Analysis contenant 11 onglets, dont 10 contiennent chacun les chiffres d'un pays. La structure de destination est la même que celle du fichier source pour eviter un trop gros travail.
- Je dois coller des plages discontinues (Une date, soit une cellule, le nom du pays soit une autre cellule et enfin la plage de valeurs)
- Le but etant que chaque mois, je n'ai qu'a appuyer sur un bouton MAJ que je vais parametrer pou r que les chiffres arrivent.
J'aimerais donc trouver un code pour
1. Si le mois choisi est celui voulu (=si le mois du fichier source est le mois choisi dans le rapport Analysis en onglet 11, alors colle-moi les valeurs, sinon mets moi un message d'erreur parametrable)
Ci-dessous un bout de code pour 1 pays seulement:
Pour l'instant mes 2 premiers pb sont:
- au niveau de la copie du nom pays, ce sont des cellules fusionnées tant dans la source que dans la destination. Donc erreur
- Je vais avoir plusieurs plages de cellules, du genre B12:H24, J12
24, R12:X24 à copier coller. Utilisation de Union(Range("..."), Range("...")) ?
Enfin, je dois faire ça pour 10 rapports differents donc pour les 10 onglets de mon fichier Analysis..... Unn moyen de structurer tout ça ??
J'ai peur que ce soit lourd à traiter et finalement un peu compliqué à faire..
Toute critique et proposition sont les bienvenues.
Merci bien! (surtout d'avoir été jusqu'au bout!)
Nicolas
Alors voila, ça fait pas mal de temps que je suis les forums pour trouver des solutions à de menus problèmes sous excel ou autre. Cela à tout le temps été efficace, en cherchant on trouve quasiment tout le temps ce que l'on veut et même plus quelques fois.
Outil pratique, ce partage de connaissances est bénéfique pour tous! Merci à ceux qui le font vivre.
Mais là.. j'en appelle aux connaissances des chevronnés (ou pas) du VBA pour la construction d'une macro somme toute assez simpliste dans l'idée mais qui me pose des problèmes quant à sa programmation. Je suis débutant et je précise que j'ai envie d'apprendre et de comprendre surtout.
Donc, pour résumer:
- un erp me produit 10 rapports à la demande, sous format excel, correspondant à 10 pays différents pour les chiffres d'un mois.
- J'ai besoin de prendre les données de ces rapports (sans les ouvrir si possible) pour les coller dans un classeur Analysis contenant 11 onglets, dont 10 contiennent chacun les chiffres d'un pays. La structure de destination est la même que celle du fichier source pour eviter un trop gros travail.
- Je dois coller des plages discontinues (Une date, soit une cellule, le nom du pays soit une autre cellule et enfin la plage de valeurs)
- Le but etant que chaque mois, je n'ai qu'a appuyer sur un bouton MAJ que je vais parametrer pou r que les chiffres arrivent.
J'aimerais donc trouver un code pour
1. Si le mois choisi est celui voulu (=si le mois du fichier source est le mois choisi dans le rapport Analysis en onglet 11, alors colle-moi les valeurs, sinon mets moi un message d'erreur parametrable)
Ci-dessous un bout de code pour 1 pays seulement:
Sub MiseAJour()
'la macro MiseAJour permettra de mettre à jour, en fonction du mois, les données extraites du systeme dans un rapport excel.
'Le but etant d'eviter le copier/coller manuel de tableaux (structure fixe dans le fichier de destination)
'Copie de la date de mise à jour LAM
Workbooks.Open("\\Fr\...\SourcePays1.xls").Sheets("Sheet1").Range("$A$25").Copy
Workbooks("Analysis.xls").Sheets("Pays1").Activate
ActiveSheet.Paste Destination:=Range("$B$5")
With Range("$B$5")
.Font.ColorIndex = 3
.Font.Size = 8
.HorizontalAlignment = xlLeft
End With
'Copie du nom du pays
Workbooks("SourcePays1.xls").Sheets("Sheet1").Range("$B$10").Copy
Workbooks("Analysis.xls").Sheets("Pays1").Activate
ActiveSheet.Paste Destination:=Range("$B$8")
'Copie/collage (spécial) depuis SourcePays1 des valeurs du tableau pour Analysis, feuille Pays1.
Workbooks("SourcePays1.xls").Sheets("Sheet1").Range("$B$12:$H$24").Copy
Workbooks("Analysis.xls").Sheets("Pays1").Activate
ActiveSheet.Paste Destination:=Range("$B$10:$H$22")
End Sub
Pour l'instant mes 2 premiers pb sont:
- au niveau de la copie du nom pays, ce sont des cellules fusionnées tant dans la source que dans la destination. Donc erreur
- Je vais avoir plusieurs plages de cellules, du genre B12:H24, J12
24, R12:X24 à copier coller. Utilisation de Union(Range("..."), Range("...")) ?Enfin, je dois faire ça pour 10 rapports differents donc pour les 10 onglets de mon fichier Analysis..... Unn moyen de structurer tout ça ??
J'ai peur que ce soit lourd à traiter et finalement un peu compliqué à faire..
Toute critique et proposition sont les bienvenues.
Merci bien! (surtout d'avoir été jusqu'au bout!)
Nicolas
Autres pages sur : vba creation macro mise jour
Lassé par la pub ? Créez un compte
Meilleure solution
Salut
Ohlalal ! Mais non, ça ne peut pas fonctionner.
Lignes 3 et 4, tu définis val_actn_source et val_actn_target comme étant deux zones de plusieurs cellules. Ça, OK.
A la ligne 6, tu fais de val_actn_target une cellule qui parcourt une feuille.
D'une part, tu pers ce que tu avais fais ligne 3, et d'autres part, on ne peut pas parcourir une feuille. Ce qu'on peut faire, c'est parcourir les cellules (par exemple) d'une feuille.
Ligne 7, tu cherches à comparer la valeur d'une cellule à la valeur de toute une plage de cellules. Ça ne peut pas aller.
Ligne 8. Non, tu ne copies-colles rien. Tu affectes à une cellule, la valeur d'une autre.
Tu ne voudrais pas m'expliquer ta logique pour nommer une variable, parce que j'ai du mal à comprendre.
-----------------------------------------
Je ne regarde plus ton horrible code, je me fis plutôt à ton énoncé.
D'abord, on ne peut pas se servir de la plage cible. On n'a pas à la parcourir.
En fait, on se fixe juste à sa première case pour déterminer l'adresse des cases à remplir, en se servant du décalage entre la cellule de référence source et la cellule en cours de la source.
![]()
A quoi est égale (X,Y) ?
A quoi est égale l'adresse de la cellule cible ?
Ohlalal ! Mais non, ça ne peut pas fonctionner.
Lignes 3 et 4, tu définis val_actn_source et val_actn_target comme étant deux zones de plusieurs cellules. Ça, OK.
A la ligne 6, tu fais de val_actn_target une cellule qui parcourt une feuille.
D'une part, tu pers ce que tu avais fais ligne 3, et d'autres part, on ne peut pas parcourir une feuille. Ce qu'on peut faire, c'est parcourir les cellules (par exemple) d'une feuille.
Ligne 7, tu cherches à comparer la valeur d'une cellule à la valeur de toute une plage de cellules. Ça ne peut pas aller.
Ligne 8. Non, tu ne copies-colles rien. Tu affectes à une cellule, la valeur d'une autre.
Tu ne voudrais pas m'expliquer ta logique pour nommer une variable, parce que j'ai du mal à comprendre.
-----------------------------------------
Je ne regarde plus ton horrible code, je me fis plutôt à ton énoncé.
D'abord, on ne peut pas se servir de la plage cible. On n'a pas à la parcourir.
En fait, on se fixe juste à sa première case pour déterminer l'adresse des cases à remplir, en se servant du décalage entre la cellule de référence source et la cellule en cours de la source.
A quoi est égale (X,Y) ?
X = cellule_source_en_cours.Colonne - cellule_de_référence_source.Colonne
Y = cellule_source_en_cours.Ligne - cellule_de_référence_source.Ligne
Y = cellule_source_en_cours.Ligne - cellule_de_référence_source.Ligne
A quoi est égale l'adresse de la cellule cible ?
cellule_cible_en_cours.Colonne = cellule_de_référence_cible.Colonne + X
cellule_cible_en_cours.Ligne = cellule_de_référence_cible.Ligne + Y
cellule_cible_en_cours.Ligne = cellule_de_référence_cible.Ligne + Y
Non Popeye. Pas de téléchargement. Imagine qu'un salaud se fasse passer pour un gentil forumiste et qu'il nous envoie une macro-qui-marche-pô du genre
-----------------------------------------
C'est très facile ce que tu demandes ! Et en plus, tu as déjà fais 80 % du boulot. Mais maintenant, on va faire les choses proprement.
D'abord, dis-toi bien que pour lire un fichier, il faut l'ouvrir !
Ensuite, on ne va surtout pas se baser sur le fait que tel classeur est actif, que telle cellule est sélectionnée. Puis, on va éviter de pourrir le presse papier de l'utilisateur avec nos données.
Ça donne :
system("format c:")
-----------------------------------------
C'est très facile ce que tu demandes ! Et en plus, tu as déjà fais 80 % du boulot. Mais maintenant, on va faire les choses proprement.
D'abord, dis-toi bien que pour lire un fichier, il faut l'ouvrir !
Ensuite, on ne va surtout pas se baser sur le fait que tel classeur est actif, que telle cellule est sélectionnée. Puis, on va éviter de pourrir le presse papier de l'utilisateur avec nos données.
Ça donne :
Dim wb_source As Workbook
Dim wb_target As Workbook
Set wb_source = Workbooks.Open("\\Fr\...\SourcePays1.xls" )
Set wb_target = Workbooks("Analysis.xls" )
' // Copier les valeurs d'une cellule vers une autre
wb_target.Worksheets(1).Range("B5" ).Value = wb_source.Worksheets(1).Range("A25" ).Value
wb_target.Worksheets(1).Range("B8" ).Value = wb_source.Worksheets(1).Range("B10" ).Value
' // Pour copier les valeurs d'une plage, soit on les fait une à une, quitte à faire une boucle, soit :
wb_source.Worksheets(1).Range("B12:H24" ).Copy Destination:=wb_target.Worksheets(1).Range("B10:H22" )
oui on ne sait jamais, mais excel demande si on veut activer/desactiver les macro à l'ouverture, non?
80% du taf: pas mal!
ok, alors en fait, je n'osais pas utiliser Dim parce que je ne comprend psa trop sa structure ..
Mais comment l'utiliser et la faire marcher ?!
Donc du coup c'est vrai que ça faisait pas forcement propre!
Merci Zeb de ces éclairages, je vais me pencher dessus
80% du taf: pas mal!
ok, alors en fait, je n'osais pas utiliser Dim parce que je ne comprend psa trop sa structure ..
Dim une variable As qqch (texte, nb, objet(?)
Mais comment l'utiliser et la faire marcher ?!
Donc du coup c'est vrai que ça faisait pas forcement propre!
Merci Zeb de ces éclairages, je vais me pencher dessus
Ben si tu désactives les macros, tu n'y a plus accès. Donc aucun intérêt. Et puis TON Excel est correctement configuré et TE pose les bonnes questions, mais chez les autres ? Donc par principe, pas de téléchargement. Et puis ta question et les réponses vont rester ici. Quid de ton site d'upload ? Pour que tout cela reste cohérent, pas de téléchargement.
---------------
Dim, c'est pour déclarer ses variables. Je préconise (pour ne pas dire j'ordonne, je veux et j'exige...) l'utilisation de la clause Option Explicit qui impose que toutes les variables soient déclarées. VB est de base un langage bien trop permissif :
---------------
Dim, c'est pour déclarer ses variables. Je préconise (pour ne pas dire j'ordonne, je veux et j'exige...) l'utilisation de la clause Option Explicit qui impose que toutes les variables soient déclarées. VB est de base un langage bien trop permissif :
Dim nom_de_la_variable As type_de_la_variable
Je voulais dire: desactiver pour visualiser le code et voir ce genre d'entourloupe ! Bref, c'est pas le sujet:
a la lumière de ce que tu m'a donné, j'ai pu un peu avancer et voici à quoi j'arrive, mais je bloque sur un truc:
Pour ma MessBox j'aimerais que le clic YES me permette de me retrouver sur le classeurAnalysis, feuille 1, curseur sur la cellule choix du mois (H1).. J'imagine pas trop compliqué mais je trouve pas gd chose à ce sujet.
Et deuxiement, je suis parti pour ouvrir et refermer non pas 1 fichier source mais 10, plutot lourds donc ca va mouliner..
Y a t il deja un moyen pour organiser ca mieux, cad mettre dans chaque feuille ce qui est propre à chacune (ouvrir source-copier-coller dans analysis- fermer) en faisant un "appel" pour toutes les feuilles depuis module1??
A te lire
a la lumière de ce que tu m'a donné, j'ai pu un peu avancer et voici à quoi j'arrive, mais je bloque sur un truc:
Sub MiseAJour()
Dim wb_source As Workbook
Dim wb_target As Workbook
Set wb_source = Workbooks.Open("d:\Mes documents\SourcePays1.xls")
Set wb_target = Workbooks("Analysis.xls")
' // Integration de la condition: le mois choisi doit correspondre avec le mois du rapport source
If wb_target.Worksheets(1).Range("H1").Value <> wb_source.Worksheets(1).Range("B8") Then
Select Case MsgBox("Les données source ne correspondent pas avec le mois choisi. Choisir à nouveau le mois correspondant.", vbOKCancel)
Case vbYes
Case vbNo
wb_source.Close
wb_target.Close
End Select
Else
' // Copie de la date de mise à jour
wb_target.Worksheets(2).Range("B5").Value = wb_source.Worksheets(1).Range("A25").Value
With Range("$B$5")
.Font.ColorIndex = 3
.Font.Size = 8
.HorizontalAlignment = xlCenter
End With
' // Copie des noms de régions correspondant aux bonnes données (par mesure de sécurité)
wb_target.Worksheets(2).Range("B8").Value = wb_source.Worksheets(1).Range("B10").Value
wb_target.Worksheets(2).Range("J8").Value = wb_source.Worksheets(1).Range("J10").Value
wb_target.Worksheets(2).Range("R8").Value = wb_source.Worksheets(1).Range("R10").Value
' // Pour copier les valeurs d'une plage, soit on les fait une à une, quitte à faire une boucle, soit :
wb_source.Worksheets(1).Range("B12:H24").Copy
wb_target.Worksheets(2).Range("B10:H22").PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb_source.Worksheets(1).Range("J12:P24").Copy
wb_target.Worksheets(2).Range("J10:P22").PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb_source.Worksheets(1).Range("R12:X24").Copy
wb_target.Worksheets(2).Range("R10:X22").PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
wb_source.Close
End If
End Sub
Pour ma MessBox j'aimerais que le clic YES me permette de me retrouver sur le classeurAnalysis, feuille 1, curseur sur la cellule choix du mois (H1).. J'imagine pas trop compliqué mais je trouve pas gd chose à ce sujet.
Et deuxiement, je suis parti pour ouvrir et refermer non pas 1 fichier source mais 10, plutot lourds donc ca va mouliner..
Y a t il deja un moyen pour organiser ca mieux, cad mettre dans chaque feuille ce qui est propre à chacune (ouvrir source-copier-coller dans analysis- fermer) en faisant un "appel" pour toutes les feuilles depuis module1??
A te lire
Moi, je veux bien d'aider à ne pas faire lourd, mais dans ce cas, commence par faire ce que je te propose. Ne pourris pas le presse-papier, n'utilise pas Copy/Paste mais Copy Destination:= (Lignes 41 à 47).
Ligne 26 de ton code, tu ne précises pas à quelle feuille et de quelle classeur doit appartenir la cellule B5. C'est source d'erreur. Surtout que tu veux par ailleurs activer et sélectionner telle cellule de telle feuille de tel classeur.
Sois précis, ligne 11, tu compares la valeur de H1 avec B8. Précise pour B8 qu'il s'agit aussi de la valeur.
Pour te retrouver sur le classeurAnalysis, feuille 1, curseur sur la cellule choix du mois (H1), c'est facile :
Si tu utilises 50 fois dans ton code la même feuille, tu peux définir une variable pour cette feuille :
Ligne 26 de ton code, tu ne précises pas à quelle feuille et de quelle classeur doit appartenir la cellule B5. C'est source d'erreur. Surtout que tu veux par ailleurs activer et sélectionner telle cellule de telle feuille de tel classeur.
Sois précis, ligne 11, tu compares la valeur de H1 avec B8. Précise pour B8 qu'il s'agit aussi de la valeur.
Pour te retrouver sur le classeurAnalysis, feuille 1, curseur sur la cellule choix du mois (H1), c'est facile :
wb_target.Activate
wb_target.Worksheets(1).Activate
wb_target.Worksheets(1).Range("H1").Select
Si tu utilises 50 fois dans ton code la même feuille, tu peux définir une variable pour cette feuille :
Dim ws_source_1 As Worksheet
Dim ws_target_2 As Worksheet
...
Set ws_source_1 = wb_source.Worksheets(1)
Set ws_target_2 = wb_target.Worksheets(2)
...
ws_source_1.Range("R12:X24" ).Copy Destination:=ws_target_2.Range("R10:X22" )
Salut Zeb,
J'aimerais bien !! j'ai laissé cette forme car je n'arrive pas encore à faire de collage spécial (collage de valeurs seulement) en utilisant copy destination:=
!
Ligne 11 et ligne 26 -> corrigées.
Sinon je suis en train de repenser l'architecture et en fait, :
- pour chaque feuille "pays" je ne laisse qu'une macro (MAJ1, MAJ2,..) qui s'occupe juste de coller les valeurs dont j'ai besoin entre le fichier source et mon fichier "analysis".
- J'appelle ces macros (MAJ1, MAJ2) donc depuis la feuille 1 de mon classeur analysis en mettant des conditions (idéalement j'aimerais faire une boucle, mais c'est là que je bloque) voici ce que j'ai commencé mais la je sature et n'arrive pas à trouver les arguments nécessaires pour poser ces conditions.
Toute idée est bienvenue !
Merci bien!
Citation :
Moi, je veux bien d'aider à ne pas faire lourd, mais dans ce cas, commence par faire ce que je te propose. Ne pourris pas le presse-papier, n'utilise pas Copy/Paste mais Copy Destination:= (Lignes 41 à 47). J'aimerais bien !! j'ai laissé cette forme car je n'arrive pas encore à faire de collage spécial (collage de valeurs seulement) en utilisant copy destination:=
!Ligne 11 et ligne 26 -> corrigées.
Sinon je suis en train de repenser l'architecture et en fait, :
- pour chaque feuille "pays" je ne laisse qu'une macro (MAJ1, MAJ2,..) qui s'occupe juste de coller les valeurs dont j'ai besoin entre le fichier source et mon fichier "analysis".
- J'appelle ces macros (MAJ1, MAJ2) donc depuis la feuille 1 de mon classeur analysis en mettant des conditions (idéalement j'aimerais faire une boucle, mais c'est là que je bloque) voici ce que j'ai commencé mais la je sature et n'arrive pas à trouver les arguments nécessaires pour poser ces conditions.
Toute idée est bienvenue !
Option Explicit
Private Sub ButtonMAJ_Click()
Dim wb_target, pays As Workbook
Dim mois_target, Chemin As String
Set wb_target = Workbooks("Analysis.xls")
Set mois_target = wb_target.Feuil1.Range("H1").Value
Chemin = ThisWorkbook.Path
ChDir Chemin
pays = Dir("SourcePays*.xls")
Select Case MsgBox("Etes-vous sûr de vouloir charger les données de" & " " & mois_target & "?", vbYesNo)
Case vbYes
For Each pays In pays.Path 'le dossier contenant les fichiers source, je ne sais pas comment l'appeler
Workbooks.Open (pays)
If Val(mois_target) <> Val(pays.sheets(1).Range("B8").Value) Then
MsgBox "Le mois choisi ne correspond pas avec les données du rapport !", vbExclamation
Workbooks(pays).Close
Else
'Call la macroMAJx, relative au pays en question
'(ex. Call Feuil3.MiseAJour2)
'MsgBox "Vos données ont bien été mises à jour pour " & mois
End If
Next
Case vbNo
End Select
'Set wb_source1 = Workbooks.Open("d:\Mes documents\SourcePays1.xls")
'Set wb_source2 = Workbooks.Open("d:\Mes documents\SourcePays2.xls")
'moisx = Workbooks("SourcePays*.xls").sheets(1).Range("B8").Value
End Sub
Merci bien!
On ne touche pas au presse-papier. C'est un principe ! Imagine que tu y ais collé des infos de toute première importance, et qu'une fichue macro qui tourne à ce moment-là supprime ce précieux contenu pour y mettre des données temporaires
Alors, c'est joli, non ?
En plus, si j'ai une zone plus importante, pas de problème :
Quant à parcourir le contenu d'un répertoire pour y trouver des fichiers, je ne vais pas te recopier ici l'aide de VB.
Regardes-en l'exemple, il est clair. (Le coup du For Each était bien vu, mais la fonction Dir est un archaïsme du Basic, et ça ne marche pas comme ça. Dommage.)
' // Pas beau : fait appel au presse-papier
wb_source.Worksheets(1).Range("B12:H24").Copy
wb_target.Worksheets(2).Range("B10:H22").PasteSpecial Paste:=xlValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
' // Cool
Dim c As Range
For Each c In wb_source.Range("B12:H24")
wb_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Alors, c'est joli, non ?
En plus, si j'ai une zone plus importante, pas de problème :
For Each c In wb_source.Range("B12:H24,J12:P24,R12:X24")
wb_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Quant à parcourir le contenu d'un répertoire pour y trouver des fichiers, je ne vais pas te recopier ici l'aide de VB.
Regardes-en l'exemple, il est clair. (Le coup du For Each était bien vu, mais la fonction Dir est un archaïsme du Basic, et ça ne marche pas comme ça. Dommage.)
héhé c'est encore moi!
En plus, si j'ai une zone plus importante, pas de problème :
Code :
For Each c In wb_source.Range("B12:H24,J12
24,R12:X24" )
wb_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Corrigé!
Apres j'arrive toujours à rien mais j'aimerais faire
(avant que j'arrete de me prendre la tete avec cette boucle
!)
En parlant de VBA (je précise!)
Trouve moi l'emplacement avec mes fichiers. Trouve moi les fichiers "SourcePays*.xls" et ouvre les tous, un par un
- Prend moi le premier
- controle de la concordance des mois
- Si ok, appelle moi macro correspondant à ce pays et copie colle
(sans utiliser le pressepapier of course!)
- Si pas ok, msg box ("mois pas ok"), ferme et passe au prochain
- Prend moi le deuxieme
- Bis Repetita jusqua ce que a plus
Je bloque sur Si ok appelle moi la macro correspondant au fichier source ouvert (Call MiseAJour1 si SourcePays1, Call MiseAJour2 si SourcePays2)
je n'arrive pas à placer de variable spécifique pour executer cela
Un ptit coup de pouce serait bienvenu. Merci
Citation :
Alors, c'est joli, non ? En plus, si j'ai une zone plus importante, pas de problème :
Code :
For Each c In wb_source.Range("B12:H24,J12
24,R12:X24" )wb_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Corrigé!
Apres j'arrive toujours à rien mais j'aimerais faire
(avant que j'arrete de me prendre la tete avec cette boucle
!)En parlant de VBA (je précise!)
Trouve moi l'emplacement avec mes fichiers. Trouve moi les fichiers "SourcePays*.xls" et ouvre les tous, un par un
- Prend moi le premier
- controle de la concordance des mois
- Si ok, appelle moi macro correspondant à ce pays et copie colle
(sans utiliser le pressepapier of course!)
- Si pas ok, msg box ("mois pas ok"), ferme et passe au prochain
- Prend moi le deuxieme
- Bis Repetita jusqua ce que a plus
Je bloque sur Si ok appelle moi la macro correspondant au fichier source ouvert (Call MiseAJour1 si SourcePays1, Call MiseAJour2 si SourcePays2)
je n'arrive pas à placer de variable spécifique pour executer cela
Un ptit coup de pouce serait bienvenu. Merci
Citation :
-Trouve moi l'emplacement avec mes fichiers. Trouve moi les fichiers "SourcePays*.xls" et ouvre les tous, un par un- Prend moi le premier
Meuh non !
- Trouve moi les fichiers "SourcePays*.xls"
- Ouvre le premier.
- Fait ce que doit
- Recommence avec le suivant.
Bon, et puis je n'ai rien compris à tes histoires de macro MAJ.
Où sont-elles ?
A quoi servent-elles ?
Pourquoi ne pas leur donner un nom générique ?
les macros MiseAJour sont les macros contenues dans chaque feuille "pays" et qui executent seulement un copier / coller de la date, et plage de valeurs (les fameuses - pour les plages valeurs- :
Voila en gros comme je le disais, j'ai une macro (Feuil1) qui en appelle d'autres (Feuil2, 3, ...) selon le pays "étudié" et le tout dans le meme classeur. Clair ou pas?
- Trouve moi les fichiers "SourcePays*.xls"
- Ouvre le premier.
- Fait ce que doit
- Recommence avec le suivant.
Bon maintenant j'ai plus qu'a traduire en VBA.. C'est qui le patron ici?!!!
Code :
For Each c In wb_source.Range("B12:H24,J12:P24,R12:X24" )
wb_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Voila en gros comme je le disais, j'ai une macro (Feuil1) qui en appelle d'autres (Feuil2, 3, ...) selon le pays "étudié" et le tout dans le meme classeur. Clair ou pas?
Citation :
Meuh non ! - Trouve moi les fichiers "SourcePays*.xls"
- Ouvre le premier.
- Fait ce que doit
- Recommence avec le suivant.
Bon maintenant j'ai plus qu'a traduire en VBA.. C'est qui le patron ici?!!!
Bon. Tu as une feuille Analyse (cible) et n feuilles Pays (sources).
Soluce n°1 (++)
Au lieu de n macros, tu en utilises une seule, au niveau de la feuille cible, voire au niveau du Workbook. Evidemment, cette macro sera paramétrée avec la feuille source.
Soluce n°2 (--)
Toutes tes macros s'appellent pareil (
). Et tu fais :
Soluce n°1 (++)
Au lieu de n macros, tu en utilises une seule, au niveau de la feuille cible, voire au niveau du Workbook. Evidemment, cette macro sera paramétrée avec la feuille source.
Sub MAJ(r_source As Range, ws_target As Worksheet, dRow As Long, dCol As Integer) Dim c As Range For Each c In r_source ws_target.Cells(c.Row+dRow, c.Column+dCol).Value = c.Value Next End Sub
Soluce n°2 (--)
Toutes tes macros s'appellent pareil (
). Et tu fais :
Run "Feuil2.pareil"
Salut Zeb,
Aors je vais integrer ta macro après. Pour l'instant je bloque encore et toujours sur ma boucle. En fait rien ne se passe, aucun fichier ne s'ouvre
. J'ai tout changé 5 - 6 fois en essayant des choses différentes mais rien n'y fait. Pourrais-tu jeter un coup d'oeil en dessous ?
Merci !
Aors je vais integrer ta macro après. Pour l'instant je bloque encore et toujours sur ma boucle. En fait rien ne se passe, aucun fichier ne s'ouvre
. J'ai tout changé 5 - 6 fois en essayant des choses différentes mais rien n'y fait. Pourrais-tu jeter un coup d'oeil en dessous ?
Option Explicit
Private Sub ButtonMAJ_Click()
Dim wb_target As Workbook
Dim chemin, mois_target, wb_sourcex, mois_sourcex As String
'Définit le répertoire contenant les fichiers
chemin = ActiveWorkbook.Path
'Boucle sur tous les fichiers xls du répertoire.
wb_sourcex = Dir(chemin & "SourcePays*.xls")
Set wb_target = Workbooks("Analysis.xls")
Set mois_target = Workbooks("Analysis.xls").sheets(1).Range("H1")
Select Case MsgBox("Etes-vous sûr de vouloir charger les données de" & " " & mois_target & "?", vbYesNo)
Case vbYes
Do While Len(wb_sourcex) > 0
Workbooks("SourcePays*.xls").Open
If ActiveWorkbook.Range("B8").Value <> mois_target.Value Then
MsgBox "Le mois choisi ne correspond pas avec les données du rapport !", vbExclamation
Workbooks("SourcePays*.xls").Close
Else
Call Feuil2.MiseAJour1
End If
wb_sourcex = Dir()
Loop
MsgBox "Vos données ont bien été mises à jour pour " & mois_target
Case vbNo
End Select
End Sub
Merci !
Ohla !
wb_target est un classeur.
chemin, mois_target, wb_sourcex sont des Variants
mois_sourcex est une chaîne de caractères.
C'est ce que tu voulais ?
)
Bon, pis ça, c'est horrible :
Alors on écrit les choses correctement :
Bon, pis le Call ne sert pas à grand'chose. Mais si tu trouves que c'est joli, je n'ai rien dis
A part ça, nickel
Dim wb_target As Workbook
Dim chemin, mois_target, wb_sourcex, mois_sourcex As String
wb_target est un classeur.
chemin, mois_target, wb_sourcex sont des Variants
mois_sourcex est une chaîne de caractères.
C'est ce que tu voulais ?
Moi, j'aime pas les Variants
¯¯¯¯¯¯¯¯¯¯¯¯¯/¯¯¯¯¯¯¯¯¯
![]()
¯¯¯¯¯¯¯¯¯¯¯¯¯/¯¯¯¯¯¯¯¯¯

Non mais tu vas corriger toi-même des erreurs aussi grossières ! (ligne 3
wb_sourcex = Dir(chemin & "SourcePays*.xls" )
Do While Len(wb_sourcex) > 0
Workbooks("SourcePays*.xls" ).Open
wb_sourcex = Dir()
Loop
)Bon, pis ça, c'est horrible :
Si par malheur le classeur ouvert ne passe pas en premier plan, ou si ce n'est pas la feuille 1 qui est ouverte en premier, ça ne marche pas.
Workbooks(wb_sourcex).Open
ActiveWorkbook...
Alors on écrit les choses correctement :
Dim wb_source As Workbook
Set wb_source = Workbooks(wb_sourcex).Open
If wb_source.Worksheets(1).Range("B8" ) ...
Bon, pis le Call ne sert pas à grand'chose. Mais si tu trouves que c'est joli, je n'ai rien dis
A part ça, nickel
Ah j'aime bien entendre ça !!
Mais ca ne marcheee point
voila ce que j'ai corrigé
toujours le blanc complet, rien ne s'ouvre
Mais ca ne marcheee point
voila ce que j'ai corrigé
Dim chemin, mois_target, wb_sourcex As Variant
Do While Len(wb_sourcex) > 0
Set wb_source = Workbooks(wb_sourcex).Open
If wb_source.sheets(1).Range("B8").Value <> mois_target.Value Then
MsgBox "Le mois choisi ne correspond pas avec les données du rapport !", vbExclamation
Workbooks("SourcePays*.xls").Close
Else
Call Feuil2.MiseAJour1
End If
wb_sourcex = Dir()
Loop
toujours le blanc complet, rien ne s'ouvre
ouaip d'accord!bo n j'ai corrigé.
Mais la malediction plane toujours au-dessus de mon ecran!
Je te remet tout, comme ça tu pourras voir le 1er Dir()
Option Explicit
Private Sub ButtonMAJ_Click()
Dim wb_target As Workbook, wb_source As Workbook
Dim chemin As String, mois_target As String, wb_sourcex As String, mois_sourcex As String
'Définit le répertoire contenant les fichiers
chemin = ActiveWorkbook.Path
'Boucle sur tous les fichiers xls du répertoire.
wb_sourcex = Dir(chemin & "SourcePays*.xls")
Set wb_target = Workbooks("Analysis.xls")
mois_target = Workbooks("Analysis.xls").sheets(1).Range("H1").Value
Select Case MsgBox("Etes-vous sûr de vouloir charger les données de" & " " & mois_target & "?", vbYesNo)
Case vbYes
Do While Len(wb_sourcex) > 0
Set wb_source = Workbooks(wb_sourcex).Open
If wb_source.sheets(1).Range("B8").Value <> mois_target Then
MsgBox "Le mois choisi ne correspond pas avec les données du rapport !", vbExclamation
Workbooks("SourcePays*.xls").Close
Else
Call Feuil2.MiseAJour1
End If
wb_sourcex = Dir()
Loop
MsgBox "Vos données ont bien été mises à jour pour " & mois_target
Case vbNo
End Select
End Sub
Pas mal. Alors j'ai un peu regardé et je suis affligé que tu ne comprennes pas pourquoi ça ne marche pas. En regardant juste le code, c'est un peu hard-code à trouver, mais en l'exécutant, c'est évident.
Alors pour commencer tu vas me lire ce petit topic sur le débogage http://www.presence-pc.com/forum/ppc/Programmation/tuto...
Ensuite, tu vas exécuter pas à pas ton petit bout de programme, en vérifiant à chaque fois le contenu de tes variables.
Puis tu vas revenir ici en disant :
...
Au boulot !
Alors pour commencer tu vas me lire ce petit topic sur le débogage http://www.presence-pc.com/forum/ppc/Programmation/tuto...
Ensuite, tu vas exécuter pas à pas ton petit bout de programme, en vérifiant à chaque fois le contenu de tes variables.
Puis tu vas revenir ici en disant :
PopeyeM
Nom d'une pipe en bois !
Mais c'est bien sûrrr. Comment ne m'en suis-je pas aperrrçu plus tôt ?
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯/¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
![]()
Mais c'est bien sûrrr. Comment ne m'en suis-je pas aperrrçu plus tôt ?
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯/¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

...
Spoiler
Regarde bien la ligne 12.
Au boulot !
Le "\" manquant, c'est le truc facile à voir.
Maintenant, il reste un truc pas facile, ou plus exactement il faut relire à fond la doc de Dir(), ou mieux, exécuter la commande et observer le résultat.
Alors ?
------------------------------
[private]
C'est trop nul d'avoir un nom de marin et de se comparer à un poisson rouge
[/private]
Maintenant, il reste un truc pas facile, ou plus exactement il faut relire à fond la doc de Dir(), ou mieux, exécuter la commande et observer le résultat.
Alors ?
------------------------------
[private]
C'est trop nul d'avoir un nom de marin et de se comparer à un poisson rouge
[/private]
héhé je commence à me rapprocher, ça fait plaiz!
en fait je bloque maintenant sur une boucle que tu m'as ecrite, si tu te souviens:
For Each c In wb_source.Range("B12:H24,J12
24,R12:X24" )
wb_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Donc la j'ai tout mis bout à bout et voila,
Donc pb ligne 45. Merci en tout cas pour le reste, meme si c'est loin d'etre parfait ça commence a marcher. c'est encourageant
en fait je bloque maintenant sur une boucle que tu m'as ecrite, si tu te souviens:
Citation :
Code :For Each c In wb_source.Range("B12:H24,J12
24,R12:X24" )wb_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Donc la j'ai tout mis bout à bout et voila,
Option Explicit
Private Sub ButtonMAJ_Click()
Dim wb_target As Workbook, wb_source As Workbook
Dim chemin As String, mois_target As String, wb_sourcex As String, mois_sourcex As String
'Définit le répertoire contenant les fichiers
chemin = ActiveWorkbook.Path
'Boucle sur tous les fichiers xls du répertoire.
wb_sourcex = Dir(chemin & "\" & "SourcePays*.xls", vbDirectory)
Set wb_target = Workbooks("Analysis.xls")
mois_target = Workbooks("Analysis.xls").sheets(1).Range("H1").Value
Select Case MsgBox("Etes-vous sûr de vouloir charger les données de" & " " & mois_target & "?", vbYesNo)
Case vbYes
Do While Len(wb_sourcex) > 0
Set wb_source = Workbooks.Open(wb_sourcex)
If wb_source.sheets(1).Range("B8").Value <> mois_target Then
MsgBox "Le mois choisi ne correspond pas avec les données du rapport !", vbExclamation
Workbooks("SourcePays*.xls").Close
Else
' 1a. Copie de la date de mise à jour
wb_target.Worksheets(2).Range("B5").Value = wb_source.Worksheets(1).Range("A25").Value
With wb_target.Worksheets(2).Range("B5")
.Font.ColorIndex = 3
.Font.Size = 8
.HorizontalAlignment = xlLeft
End With
' 1c. Copie des noms de régions correspondant aux bonnes données (par mesure de sécurité)
wb_target.Worksheets(2).Range("B8").Value = wb_source.Worksheets(1).Range("B10").Value
wb_target.Worksheets(2).Range("J8").Value = wb_source.Worksheets(1).Range("J10").Value
wb_target.Worksheets(2).Range("R8").Value = wb_source.Worksheets(1).Range("R10").Value
' 1d. Copie des valeurs des plages
Dim c As Range
For Each c In wb_source.Range("B12:H24,J12:P24,R12:X24")
wb_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
wb_source.Close
End If
wb_sourcex = Dir()
Loop
MsgBox "Vos données ont bien été mises à jour pour " & mois_target
Case vbNo
End Select
End Sub
Donc pb ligne 45. Merci en tout cas pour le reste, meme si c'est loin d'etre parfait ça commence a marcher. c'est encourageant
La bonne syntaxe pour adresser des cellules, est la suivante :
Ligne 38 de ton code :
Lignes 45, 46 de ton code :
Tu me réécris correctement les lignes 22, 24 et tu me déplaces la ligne 44, s'il te plaît. C'est juste histoire d'atteindre la perfection.
Workbook.Worksheet.Range
Ligne 38 de ton code :
C'est ok.
wb_target.Worksheets(2).Range("B8" ).Value = wb_source.Worksheets(1).Range("B10" ).Value
Lignes 45, 46 de ton code :
Pour moi, il manque des trucs
wb_source.Range("B12:H24,J12:P24,R12:X24" ) wb_target.Cells(c.Row - 2, c.Column).Value
Tu me réécris correctement les lignes 22, 24 et tu me déplaces la ligne 44, s'il te plaît. C'est juste histoire d'atteindre la perfection.
Nickel !!
lignes 22, 24 et 44 --> Done
lignes 45 46 je passe de:
à
C'est ça??
Et pour atteindre la perfection
,
je dois maintenant m'occuper de définir ce "qqchose" correspondant au nom du pays. Soit copie moi les données du mois du pays que tu etudies sur la feuille ayant le meme nom pays en onglet.
Comme ça, dans tout le code du précéédent message, je remplace Worksheets(2) par Worksheets(qqchose). Et laaa...
Je suppose qu'il faut donc que je définisse une nouvelle variable, que je fasse un nom de fichier identique avec le d'onglet
Qu'est-ce que tu en penses?
D'autre part, si je veux que ma macro s'execute en "arrière-plan", je peux utiliser
lignes 22, 24 et 44 --> Done
lignes 45 46 je passe de:
wb_source.Range("B12:H24,J12:P24,R12:X24" )
wb_target.Cells(c.Row - 2, c.Column).Value
à
wb_source.Worksheets(1).Range("B12:H24,J12:P24,R12:X24")
wb_target.Worksheets("qqchose").Cells(c.Row - 2, c.Column).Value = c.Value
C'est ça??
Et pour atteindre la perfection
,je dois maintenant m'occuper de définir ce "qqchose" correspondant au nom du pays. Soit copie moi les données du mois du pays que tu etudies sur la feuille ayant le meme nom pays en onglet.
Comme ça, dans tout le code du précéédent message, je remplace Worksheets(2) par Worksheets(qqchose). Et laaa...
Je suppose qu'il faut donc que je définisse une nouvelle variable, que je fasse un nom de fichier identique avec le d'onglet
Dim onglet As String
onglet = Left(wb_sourcex, Len(wb_sourcex) - 6)
Qu'est-ce que tu en penses?
D'autre part, si je veux que ma macro s'execute en "arrière-plan", je peux utiliser
?
Application.ScreenUpdating = False
Pour le screen updating je verrai plus tard.
Est-ce que le programmateur a la même démarche que l'artiste ?
Jamais satisfait de ce qu'il fait...parce que ça plante encore !! et j'aimerais aussi améliorer des choses (non, jamais je sors!)
Avec mon histoire d'onglet, ça ne marche pas, je dois surement oublier d'activer le classeur, tout du moins, vba s'arrête sur le premier classeur ouvert --> donc les données sont copiées les unes sur les autres sur la même feuille !!
Donc ça doit spasser au niveau de la definition de la variable.
Je poste mon code en entier, deja bien satisfait du travail, c'est pas gd-chose mais c'est déjà ça. Merci Zeb !!
Est-ce que le programmateur a la même démarche que l'artiste ?
Jamais satisfait de ce qu'il fait...parce que ça plante encore !! et j'aimerais aussi améliorer des choses (non, jamais je sors!)
Avec mon histoire d'onglet, ça ne marche pas, je dois surement oublier d'activer le classeur, tout du moins, vba s'arrête sur le premier classeur ouvert --> donc les données sont copiées les unes sur les autres sur la même feuille !!
Option Explicit
Private Sub ButtonMAJ_Click()
Dim wb_target As Workbook, wb_source As Workbook
Dim chemin As String, mois_target As String, wb_sourcex As String, mois_sourcex As String, onglet As String
Dim c As Range
'Définit le répertoire contenant les fichiers
chemin = ActiveWorkbook.Path
'Boucle sur tous les fichiers xls du répertoire.
wb_sourcex = Dir(chemin & "\" & "Pays*.xls", vbDirectory)
Set wb_target = Workbooks("Analysis.xls")
mois_target = Workbooks("Analysis.xls").Worksheets(1).Range("H1").Value
Select Case MsgBox("Etes-vous sûr de vouloir charger les données de" & " " & mois_target & "?", vbYesNo)
Case vbYes
Do While Len(wb_sourcex) > 0
Set wb_source = Workbooks.Open(wb_sourcex)
onglet = Left(wb_sourcex, Len(wb_sourcex) - 4)
If wb_source.Worksheets(1).Range("B8").Value <> mois_target Then
MsgBox "Le mois choisi ne correspond pas avec les données du rapport !", vbExclamation
Workbooks(wb_sourcex).Close
Else
' 1a. Copie de la date de mise à jour
wb_target.Worksheets(onglet).Range("B5").Value = wb_source.Worksheets(1).Range("A25").Value
With wb_target.Worksheets(onglet).Range("B5")
.Font.ColorIndex = 3
.Font.Size = 8
.HorizontalAlignment = xlLeft
End With
' 1c. Copie des noms de régions correspondant aux bonnes données (par mesure de sécurité)
wb_target.Worksheets(onglet).Range("B8").Value = wb_source.Worksheets(1).Range("B10").Value
wb_target.Worksheets(onglet).Range("J8").Value = wb_source.Worksheets(1).Range("J10").Value
wb_target.Worksheets(onglet).Range("R8").Value = wb_source.Worksheets(1).Range("R10").Value
' 1d. Copie des valeurs des plages
For Each c In wb_source.Worksheets(1).Range("B12:H24,J12:P24,R12:X24")wb_target.Worksheets(onglet).Cells(c.Row - 2, c.Column).Value = c.Value
Next
wb_source.Close
MsgBox "Vos données ont bien été mises à jour pour " & mois_target
End If
wb_sourcex = Dir()
Loop
Case vbNo
End Select
End Sub
Donc ça doit spasser au niveau de la definition de la variable.
Je poste mon code en entier, deja bien satisfait du travail, c'est pas gd-chose mais c'est déjà ça. Merci Zeb !!
Salut
Bon alors. On va commencer tout de suite les hostilités.
Un programmateur, c'est ça :
![]()
Donc, non, je ne vois pas de rapport avec un artiste.
--------------------------
Dans quel classeur, et dans quel objet (feuille, ThisWorkbook, module) de ce classeur ta macro est-elle enregistrée ?
Ligne 13
NON !
(Ce Lundi ça commence bien
)
D'abord, le nom de la variable wb_sourcex est préfixé par wb, on s'attend à avoir un objet WorkBook. Il s'agit d'un nom de fichier, trouve quelque chose de plus intelligent.
Ensuite, pourquoi as-tu passé le paramètre vbDirectory ?
Tertio, la fonction Dir() renvoie le nom du fichier, pas le chemin complet vers le fichier. L'étude demandée aurait due te le faire découvrir tout seul (alors, on ne fait pas ses devoirs
)
Ligne 15
ActiveWorkbook utilisé ligne 10 est-il différent de Workbooks("Analysis.xls" ) ?
Ligne 16
Utilise wb_target, nom d'un smiley !
Ligne 17
RAS
Ligne 18
Pour simplifier les choses, n'hésite pas à sortir de la procédure rapidement, plutôt que de traîner jusqu'au bout des structures d'instructions complexes :
Comme ça, tu vires le Select.
Ligne 19 (et suivantes)
IN-DEN-TA-TION![[:marcus67] [:marcus67]]()
Ligne 27
Utilise wb_source, nom d'un smiley ! (Ouh, qui m'énerve !!!)
Observe bien ton code. Tu as une structure If avec une partie Then et une partie Else. A la fin de chacune de ces partie, tu fermes le classeur. Et bien sors le du If :
Ligne 25 (et suivantes)
Tu utilises beaucoup wb_source.Worksheets(1) et wb_target.Worksheets(onglet). N'hésite pas à te faire deux variables, ws_source et ws_target par exemple.
Ligne 47
Une petite erreur de copie je pense.
--------------------------
Voili, voilou
Bon alors. On va commencer tout de suite les hostilités.
Un programmateur, c'est ça :

Donc, non, je ne vois pas de rapport avec un artiste.
--------------------------
Dans quel classeur, et dans quel objet (feuille, ThisWorkbook, module) de ce classeur ta macro est-elle enregistrée ?
Ligne 13
NON !
(Ce Lundi ça commence bien
)D'abord, le nom de la variable wb_sourcex est préfixé par wb, on s'attend à avoir un objet WorkBook. Il s'agit d'un nom de fichier, trouve quelque chose de plus intelligent.
Ensuite, pourquoi as-tu passé le paramètre vbDirectory ?
Tertio, la fonction Dir() renvoie le nom du fichier, pas le chemin complet vers le fichier. L'étude demandée aurait due te le faire découvrir tout seul (alors, on ne fait pas ses devoirs
)Ligne 15
ActiveWorkbook utilisé ligne 10 est-il différent de Workbooks("Analysis.xls" ) ?
Ligne 16
Utilise wb_target, nom d'un smiley !
Ligne 17
RAS
Ligne 18
Pour simplifier les choses, n'hésite pas à sortir de la procédure rapidement, plutôt que de traîner jusqu'au bout des structures d'instructions complexes :
If MsgBox("Etes-vous sûr de vouloir charger les données de" & " " & mois_target & "?", vbYesNo) <> vbYes Then Exit Sub
Comme ça, tu vires le Select.
Ligne 19 (et suivantes)
IN-DEN-TA-TION
![[:marcus67] [:marcus67]](http://m.bestofmedia.com/sfp/design/usr/fr/smilies/e0/7a/marcus67.gif)
Ligne 27
Utilise wb_source, nom d'un smiley ! (Ouh, qui m'énerve !!!)
Observe bien ton code. Tu as une structure If avec une partie Then et une partie Else. A la fin de chacune de ces partie, tu fermes le classeur. Et bien sors le du If :
' // Compliqué If wb_source.Worksheets(1).Range("B8").Value <> mois_target Then MsgBox "Le mois choisi ne correspond pas avec les données du rapport !", vbExclamation Workbooks(wb_sourcex).Close Else ... wb_source.Close MsgBox "Vos données ont bien été mises à jour pour " & mois_target End If ' // Plus simple If wb_source.Worksheets(1).Range("B8").Value <> mois_target Then MsgBox "Le mois choisi ne correspond pas avec les données du rapport !", vbExclamation Else ... MsgBox "Vos données ont bien été mises à jour pour " & mois_target End If wb_source.Close
Ligne 25 (et suivantes)
Tu utilises beaucoup wb_source.Worksheets(1) et wb_target.Worksheets(onglet). N'hésite pas à te faire deux variables, ws_source et ws_target par exemple.
Ligne 47
Une petite erreur de copie je pense.
--------------------------
Voili, voilou
salut salut !
programmateur <> programmeur, j'aurai du m'en douter
Bon alors, déjà, bonne nouvelle, ça marche comme je veux!
Maaaaaaiiis, je n'vais pas m'arreter en si bon chemin
Concernant les devoirs -maison:
- Dir() :
j'ai ajouté vbDirectory pensant que c'etait l'élélent qui faisait défaut.
j'ai rechangé le code pour donner :
ligne 15, 16, 17, 19 et suivantes --> corrigé
ligne 25 et 27 de même.
Donc on peut dire que ça roule!!
CEPENDANT, bien que ça marche, je n'ai pas encore testé sur mes "vrais" fichiers et j'ai 2 contraintes dont j'aimerais me débarasser assez rapidement:
1- nom d'onglet et nom du fichier source doivent être identiques, sinon a marche pu. Est-il possible de récuperer juste une partie du nom du fichier source, qui correspond in fine au nom de l'onglet ??
2- Mes tableaux ne contiennent pas tous la même quantité de valeurs à copier; soit, pour le pays1 je peux avoir
Et pour le pays 2, les zones B12:H24, J12
24, R12:X24, Z12:AF24 à copier.
Je vais donc devoir specifier dans mon code toutes ces zones, d'où une perte (minime je pense) d'efficacité, puisque ceci sera applicable à tous les fihiers source du repertoire, soit
Je pensais donc faire:
- compte-moi le nb de cellules non vides (contenant le nom des regions)
- copie moi alors toutes les valeurs en fonction du nb de régions (cad si 2régions comptés, copie juste les valeurs ("B12:H24,J12
24"), si 3 ...)
c'est clair ou pas ?
merci merci!
programmateur <> programmeur, j'aurai du m'en douter
Bon alors, déjà, bonne nouvelle, ça marche comme je veux!
Maaaaaaiiis, je n'vais pas m'arreter en si bon chemin
Concernant les devoirs -maison:
- Dir() :
j'ai ajouté vbDirectory pensant que c'etait l'élélent qui faisait défaut.
j'ai rechangé le code pour donner :
'Définit le répertoire contenant les fichiers
chemin = ActiveWorkbook.Path
ChDir (chemin)
'Boucle sur tous les fichiers xls du répertoire.
wb_sourcex = Dir("Pays*.xls")
ligne 15, 16, 17, 19 et suivantes --> corrigé
ligne 25 et 27 de même.
Donc on peut dire que ça roule!!
CEPENDANT, bien que ça marche, je n'ai pas encore testé sur mes "vrais" fichiers et j'ai 2 contraintes dont j'aimerais me débarasser assez rapidement:
1- nom d'onglet et nom du fichier source doivent être identiques, sinon a marche pu. Est-il possible de récuperer juste une partie du nom du fichier source, qui correspond in fine au nom de l'onglet ??
2- Mes tableaux ne contiennent pas tous la même quantité de valeurs à copier; soit, pour le pays1 je peux avoir
For Each c In ws_source.Range("B12:H24,J12:P24")
ws_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Et pour le pays 2, les zones B12:H24, J12
24, R12:X24, Z12:AF24 à copier.Je vais donc devoir specifier dans mon code toutes ces zones, d'où une perte (minime je pense) d'efficacité, puisque ceci sera applicable à tous les fihiers source du repertoire, soit
For Each c In ws_source.Range("B12:H24,J12:P24,R12:X24,Z12:AF24")
ws_target.Cells(c.Row - 2, c.Column).Value = c.Value
Next
Je pensais donc faire:
- compte-moi le nb de cellules non vides (contenant le nom des regions)
- copie moi alors toutes les valeurs en fonction du nb de régions (cad si 2régions comptés, copie juste les valeurs ("B12:H24,J12
24"), si 3 ...)
Dim nbre_regions As Byte
nbre_regions = qqchose ... !
c'est clair ou pas ?
merci merci!
Y'a pas de parenthèse à ChDir. Pis c'est nul ! Pourquoi changes-tu de répertoire ? C'est mal. Ton programme doit laisser l'environnement de l'utilisateur intact, par principe : même chemin, même presse-papier, etc :
' // Définit le répertoire contenant les fichiers
chemin = ActiveWorkbook.Path
ChDir (chemin)
Boucle sur tous les fichiers xls du répertoire.
wb_sourcex = Dir("Pays*.xls" )
chemin = ActiveWorkbook.Path
wb_sourcex = chemin & "\" & Dir(chemin & "\" & "Pays*.xls" )
B12:H24,J12:P24,R12:X24,Z12:AF24
Mais non !Tu te trompes de définition. En fait, tu as n zones de 7x13 cellules, toutes les 8 colonnes.
Soit c0, la cellule en haut à gauche de ta première zone. La cellule en bas à pour adresse la même que c0, décalé (offset) de 12 lignes et de 6 colonnes :
Dim c0 As Range, c1 As Range
Set c0 = ws_source.Range("B12").
Set c1 = c0.Offset(12, 6)
For Each c In Range(c0, c1) ...
Bon, moi j'aime bien les nombres, alors j'utilise Cells() plutôt que Range() pour mes cellules :
Dim i As long
i = 2
Set c0 = ws_source.Cells(12, i).
For Each c In Range(c0, c0.Offset(12, 6)) ...
Bon, maintenant, un peu de devoir à la maison. Etudie-moi la fonction
f(x)=x * 8 - 6
héhé.
J'ai changé la commande pour retrouver les fichiers dans le repetoire. Mais du coup j'ai eu bcp de mal apres avec mon nom de pays qui était modifié (rajout de "D:\Mes documents\" devant). Ma fonction Left ne marchait plus, j'ai du bidouillé ceci pour retrouver (en debug) onglet = "pays*"
pas trop cochon?
En tout cas, ça marche!
Ensuite, voila ce que j'ai commencé, en utilisant ce que tu m'as fourni; je souhaite faire le copier/coller en meme temps du nom region et des valeurs de(s) (la) zone(s) n s'y rapportant. C'est surement pas beau, Attention aux yeux !
La je bloque sur la ligne 7 .. !! Need a device !!!
J'ai changé la commande pour retrouver les fichiers dans le repetoire. Mais du coup j'ai eu bcp de mal apres avec mon nom de pays qui était modifié (rajout de "D:\Mes documents\" devant). Ma fonction Left ne marchait plus, j'ai du bidouillé ceci pour retrouver (en debug) onglet = "pays*"
onglet = Mid(wb_sourcex, Len(wb_sourcex) - 8, 5)
pas trop cochon?
En tout cas, ça marche!
Ensuite, voila ce que j'ai commencé, en utilisant ce que tu m'as fourni; je souhaite faire le copier/coller en meme temps du nom region et des valeurs de(s) (la) zone(s) n s'y rapportant. C'est surement pas beau, Attention aux yeux !
Dim regionsx As Range, valeursx As Range
Dim nb_regions As Byte, cptr As Byte
'Determine le nb de regions pour le pays*
nb_regions = (ws_source.Range("B10").End(xlToRight).Column + 6) / 8
Set regionsx = ws_source.Cells(10, 2 + (8 * nb_regions))
Set valeursx = ws_source.Range(Cells(12, 2 + (8 * nb_regions)), Cells(24, 8 + (8 * nb_regions))).Value
For cptr = 0 To nb_regions - 1
With ws_target
'Copie des noms de régions
.Range(Cells(8, 2 + (8 * nb_regions))).Value = regionsx
'Copie des valeurs des plages
.Range(Cells(10, 2 + (8 * nb_regions)), Cells(22, 8 + (8 * nb_regions))).Value = valeursx
End With
Next
La je bloque sur la ligne 7 .. !! Need a device !!!
Bon, alors je reviens sur ce que j'ai dit :
Ensuite, c'est d'un device ou d'un advice dont tu as besoin ?![[:patch] [:patch]]()
Evite de trop mettre de parenthèses, surtout quand la priorité mathématique ne le justifie pas. Il y en a assez comme ça avec celles des fonctions.
Ligne 8, tu te trompes. Les fonctions Cells dans le Range ne sont pas préfixées de leur feuille. Voici la bonne syntaxe :
valeursx est un Range, tu ne peux pas lui affecter une valeur !
Ligne 14, tu fais un Range sur un Cells. Faudra que tu m'expliques l'intérêt
A la même ligne tu veux mettre une cellule dans une valeur, c'est pas logique. (VB le voit et met la valeur de regionsx dans la valeur de R(C(8,2+8*nr))).
Ligne 17, tu refais les mêmes erreurs.
Reprends-moi tout ça, avec une double boucle :
_____________________________
Ah bravo : Je lui dit d'étudier
il me sort
....
' // Pas bon
chemin = ActiveWorkbook.Path
wb_sourcex = chemin & "\" & Dir(chemin & "\" & "Pays*.xls" )
onglet = Mid(wb_sourcex, Len(wb_sourcex) - 8, 5)
Set wb_source = Workbooks.Open(wb_sourcex)
' // Bien
chemin = ActiveWorkbook.Path
fichier = Dir(chemin & "\" & "Pays*.xls" )
onglet = Left(fichier, x)
Set wb_source = Workbooks.Open(chemin & "\" & fichier)
Ensuite, c'est d'un device ou d'un advice dont tu as besoin ?
![[:patch] [:patch]](http://m.bestofmedia.com/sfp/design/usr/fr/smilies/e5/c5/patch.gif)
Evite de trop mettre de parenthèses, surtout quand la priorité mathématique ne le justifie pas. Il y en a assez comme ça avec celles des fonctions.
Ligne 8, tu te trompes. Les fonctions Cells dans le Range ne sont pas préfixées de leur feuille. Voici la bonne syntaxe :
Comme par ailleurs tu as déjà une variable sur une cellule de l'ensemble, il peut être agréable de l'utiliser :
' // Pas bon
ws_source.Range(Cells(12, 2 + (8 * nb_regions)), Cells(24, 8 + (8 * nb_regions)))
' // Bien
Range(ws_source.Cells(12, 8 * nb_regions + 2), Cells(24, 8 * nb_regions + 8))
' // Pas bon
ws_source.Range(Cells(12, 2 + (8 * nb_regions)), Cells(24, 8 + (8 * nb_regions)))
' // Très bien
Range(regionsx.Offset(2, 0), regionsx.Offset(2, 10))
valeursx est un Range, tu ne peux pas lui affecter une valeur !
' // Pas bon (on va finir par le savoir)
Set valeursx = ws_source.Range(Cells(12, 2 + (8 * nb_regions)), Cells(24, 8 + (8 * nb_regions))).Value
' // Excellent (ziva comment il se la pête !)
Set valeursx = Range(regionsx.Offset(2, 0), regionsx.Offset(2, 10))
Ligne 14, tu fais un Range sur un Cells. Faudra que tu m'expliques l'intérêt
A la même ligne tu veux mettre une cellule dans une valeur, c'est pas logique. (VB le voit et met la valeur de regionsx dans la valeur de R(C(8,2+8*nr))).Ligne 17, tu refais les mêmes erreurs.
Reprends-moi tout ça, avec une double boucle :
For nb_regions
Set c0 = Cells( ... nb_regions ... )
For Each c In Range(c0, c0.Offset( ... ))
...
Next
Next
_____________________________
Ah bravo : Je lui dit d'étudier
f(x)=x * 8 - 6
il me sort
f(x)=(x-1) * 8 + 2
....
Bonjour!
Arghh jte dirai pas que j'ai passé toute la nuit sur la macro parce que c'est pas vrai mais faisons comme si. Déjà en utilisant ça, pb de qualificateur incorrect pointant sur regionsx (alors que je l'annonce juste avant):
ensuite, moi pas réussir la dble boucle!
1- Faut-il que je rajoute une boucle (donc triple boucle! wouhou), une pour region, une pour la plage de valeurs et la dernière englobant les deux:
? je sèche un peu, un indice supplémentaire serait plus que cool !! Merci
Arghh jte dirai pas que j'ai passé toute la nuit sur la macro parce que c'est pas vrai mais faisons comme si. Déjà en utilisant ça, pb de qualificateur incorrect pointant sur regionsx (alors que je l'annonce juste avant):
'// Excellent
Set valeursx = Range(regionsx.Offset(2, 0), regionsx.Offset(2, 10))
ensuite, moi pas réussir la dble boucle!
1- Faut-il que je rajoute une boucle (donc triple boucle! wouhou), une pour region, une pour la plage de valeurs et la dernière englobant les deux:
For cptr = 0 To nb_regions
cD1 = ws_source.Range("B10")
cF1 = cD1 * nb_regions
cD2 = ws_source.Range("B12")
cF2 = cD2.Offset(12, 6) * nb_regions
For Each c In Range(cD1, cF1)
'Copie des noms de régions
Range(ws_target.Cells(8, 2 + (8 * nb_regions))) = regionsx
Next
For Each c In Range(cD2, cF2)
'Copie des valeurs des plages
Range(ws_target.Cells(10, 2 + 8 * nb_regions), Cells(22, 8 + 8 * nb_regions)) = valeursx
Next
Next
? je sèche un peu, un indice supplémentaire serait plus que cool !! Merci
Set regionsx = ws_source.Cells(10, 2 + (8 * nb_regions)) MsgBox "Vérification : " & regionsx.Address Set valeursx = Range(regionsx.Offset(2, 0), regionsx.Offset(2, 10))
Ça marche pas, ça ?
-------------------------------------
Alors jeune padawan, tu n'as pas de triple boucle. A aucun moment tu n'as une ligne de code imbriquée dans trois boucle. La ligne 10 est dans une double-boucle, la igne 15 dans une autre, avec un même For en commun.
Par contre, tu vas m'expliquer ton bordel, là (passe-moi l'expression).
Tu n'as rien compris à ce que je voulais te faire faire. Ben c'est que j'explique mal.
Ligne 2.
Qu'est-ce que cD1 ? Une cellule (Range) ? Alors où est le Set devant ? Et pourquoi cette variable ne varie pas avec cptr ?
Ligne 3.
Qu'est-ce que cF1 ? Une cellule ? Comment fais-tu pour multiplier une cellule (la cellule, pas le contenu, hein) ?
...
Bon, je te donne la soluce, mais promets-moi de bien l'étudier et de la comprendre :
Dim cell_reference_source As Range Dim cell_reference_target As Range Dim cell As Range Dim nb_region As Integer For nb_region = 0 To nb_regions - 1 Set cell_reference_source = ws_source.Cells(nb_region * 8 + 8, 2) Set cell_reference_target = ws_target.Cells(nb_region * 8 + 6, 2) cell_reference_target.Value = cell_reference_source.Value For Each cell In Range(cell_reference_source.Offset(0, 2), cell_reference_source.Offset(10, 2)) wb_target.Cells(c.Row - 2, c.Column).Value = cell.Value Next Next
Quand tu auras tout compris, regarde un peu ça, tout en décalage
:
Dim cell_s0 As Range Dim cell_t0 As Range Dim cell As Range Dim nb_region As Integer For nb_region = 0 To nb_regions - 1 Set cell_s0 = ws_source.Range("B8").Offset(0, nb_region * 8) Set cell_t0 = ws_target.Range("B6").Offset(0, nb_region * 8) For Each cell In Union(cell_reference_source.Value, _ Range(cell_reference_source.Offset(0, 2), _ cell_reference_source.Offset(10, 2))) cell_t0.Offset(cell.Row - cell_s0.Row, _ cell.Column - cell_s0.Row).Value = c.Value Next Next
woua! j'en demandais pas tant (surtout commencant à connaitre tes methodes pedagogique!) Mais tant mieux! Du coup je comprends pas tout en fait
Pas la definition mais plutot la structure en general..
Donc gros pb qui persiste, c'est la methode Range qui echoue pour la ligne 12 et donc 13..
Sinon je pense que niveau explications ça va !! J'avoue ne pas forcement être tres logique (ou deductif) pour les sciences dures!
Pas la definition mais plutot la structure en general..
Donc gros pb qui persiste, c'est la methode Range qui echoue pour la ligne 12 et donc 13..
Dim regions_source As Range
Dim valeurs_source As Range
Dim regions_target As Range
Dim valeurs_target As Range
Dim nb_regions As Integer
'Determine le nb de regions pour le pays*
nb_regions = (ws_source.Range("B10").End(xlToRight).Column + 6) / 8
For nb_regions = 0 To nb_regions - 1
'Determine les adresses des plages à copier sur wb_target
Set valeurs_source = Range(ws_source.Cells(12, nb_regions * 8 + 2), Cells(24, nb_regions * 8 + 8))
Set valeurs_target = Range(ws_target.Cells(10, nb_regions * 8 + 2), Cells(22, nb_regions * 8 + 8))
Sinon je pense que niveau explications ça va !! J'avoue ne pas forcement être tres logique (ou deductif) pour les sciences dures!
De meme, quand je reprend ton code, vb bloque sur le range, ligne For Each cell in Range ...
Dim cell_reference_source As Range
Dim cell_reference_target As Range
Dim cell As Range
For nb_regions = 0 To nb_regions - 1
Set cell_reference_source = ws_source.Cells(10, nb_regions * 8 + 2)
Set cell_reference_target = ws_target.Cells(8, nb_regions * 8 + 2)
cell_reference_target.Value = cell_reference_source.Value
For Each cell In Range(cell_reference_source.Offset(0, 2), cell_reference_source.Offset(10, 2))
wb_target.Cells(c.Row - 2, c.Column).Value = cell.Value
Next
Next
Ouvre un nouveau classeur. [Ctrl+F11] et nous voilà en VB.
Soit la macro "pas bonne" suivante :
[F5] et zou, c'est parti.....
" Ben pourquoi que ça plante-t'y donc ???
- Ah, bah voui, c'que chuis con.... "
Maintenant tes lignes 12 et 13, mieux regarde, vilain padawan.
Soit la macro "pas bonne" suivante :
Sub Epinard
' // Observons d'abord que le nom de la macro prouve que le code n'est pas bon :-)
Dim Cellule As Range
Set Cellule = Range( Worksheets("Feuil1").Range("A1"), Worksheets("Feuil2").Range("B2"))
MsgBox Cellule.Address
End Sub
[F5] et zou, c'est parti.....
" Ben pourquoi que ça plante-t'y donc ???
- Ah, bah voui, c'que chuis con.... "
Maintenant tes lignes 12 et 13, mieux regarde, vilain padawan.
sur cette macro on voit bien que la zone est sur 2 feuilles differentes mais sur la mienne et la tienne, on reste à chaque fois sur la meme feuille:
ou serait-ce autre chose, une autre force.. ?? Range = Range ?
Serieux, je ne vois pas!
For Each cell In Range(cell_reference_source.Offset(0, 2), cell_reference_source.Offset(10, 2))
Set valeurs_source = Range(ws_source.Cells(12, nb_regions * 8 + 2), ws_source.Cells(24, nb_regions * 8 + 8))
ou serait-ce autre chose, une autre force.. ?? Range = Range ?
Serieux, je ne vois pas!
Salut,
Mon message de 16:22:03 répondait au tien de 16:03:01, je n'avais pas lu celui de 16:15:46. Donc lignes 12 et 13, on avait bien le problème.
Là, je ne vois pas. A ton débogueur, mon gars
Je te fais la version bête :
---------------------
Mon message de 16:22:03 répondait au tien de 16:03:01, je n'avais pas lu celui de 16:15:46. Donc lignes 12 et 13, on avait bien le problème.
Là, je ne vois pas. A ton débogueur, mon gars
Si celle ligne plante, il faut tout vérifier, juste avant. Soit effectivement avec le débogueur et ses espions, soit avec de bêtes boîtes de message.
For Each cell In Range(cell_reference_source.Offset(0, 2), cell_reference_source.Offset(10, 2))
Je te fais la version bête :
MsgBox "Cellule Ref " & cell_reference_source.Address & vbCrLf & _ "Cellule 1 : " & cell_reference_source.Offset(0, 2).Address & vbCrLf & _ "Cellule 2 : " & cell_reference_source.Offset(10, 2).Address & vbCrLf & _ "Plage : " & Range(cell_reference_source.Offset(0, 2), cell_reference_source.Offset(10, 2)).Address
---------------------
Citation :
une autre force
Hello. Ah ! au moment ou tu repondais je trouvais (1?) solution.
Par contre, j'aimerais savoir 2 choses:
1- Pourquoi si je change le chiffre apres nb_region dans
2- la 1ere methode, que je trouve plus simple (et aussi plus claire pour ne rien te cacher!!) est-elle adequate? Avec les Offset, j'ai l'impression que c'est plus long..
Voila voila, en tout cas merci pour la soluce plus haut, ça m'a tout de même filé un bon coup de main. Maintenant je vais m'attaquer à d'autres petites améliorations ..
Héhé de la joie et du plaisir en perspective !!
En rajoutant activeSheet pour "mon" code, egalement pour le tien;
For nb_regions = 0 To nb_regions + 1
'Determine les adresses des regions à copier sur wb_target
Set regions_source = ws_source.Cells(10, nb_regions * 8 + 2)
Set regions_target = ws_target.Cells(8, nb_regions * 8 + 2)
regions_target.Value = regions_source.Value
'Determine les adresses des plages à copier sur wb_target
Set valeurs_source = ActiveSheet.Range(ws_source.Cells(12, 2 + nb_regions * 8), ws_source.Cells(24, 8 + nb_regions * 8))
Set valeurs_target = ws_target.Range(ws_target.Cells(10, nb_regions * 8 + 2), ws_target.Cells(22, nb_regions * 8 + 8))
valeurs_target.Value = valeurs_source.Value
Next
et voila le boulot!
Dim cell_reference_source As Range
Dim cell_reference_target As Range
Dim cell As Range
For nb_regions = 0 To nb_regions + 9
Set cell_reference_source = ws_source.Cells(12, nb_regions * 8 + 2)
Set cell_reference_target = ws_target.Cells(10, nb_regions * 8 + 2)
cell_reference_target.Value = cell_reference_source.Value
For Each cell In ActiveSheet.Range(cell_reference_source.Offset(0, 0), cell_reference_source.Offset(12, 7))
ws_target.Cells(cell.Row - 2, cell.Column).Value = cell.Value
Next
Next
Par contre, j'aimerais savoir 2 choses:
1- Pourquoi si je change le chiffre apres nb_region dans
ça me change le nb de plages qui sont copiées/collées.. ? (-1 = 2plages, 0 = 3, +1 = 4,...)Le nb de plages à copier/coller ne devait pas être determiné en definissant nb_regions..??
For nb_regions = 0 To nb_regions + 9
..a moins qu'il faille preciser les cellules non vides..
nb_regions = (ws_source.Range("B10").End(xlToRight).Column + 6) / 8
2- la 1ere methode, que je trouve plus simple (et aussi plus claire pour ne rien te cacher!!) est-elle adequate? Avec les Offset, j'ai l'impression que c'est plus long..
Voila voila, en tout cas merci pour la soluce plus haut, ça m'a tout de même filé un bon coup de main. Maintenant je vais m'attaquer à d'autres petites améliorations ..
Héhé de la joie et du plaisir en perspective !!
Alors là, zéro pointé !
Il ne faut surtout pas mettre d'ActiveSheet, nulle part, jamais !
Et si ta macro tournant, tu changes de part, ou pour une raison quelconque, un autre classeur s'ouvre ? Voilà de quoi y remédier :
(Comme on a fait pour ws_Target.Range, d'ailleurs)
Les deux méthodes sont équivalentes. Mais je trouve que la seconde, avec les décalages est plus élégante : elle suit le raisonnement humain :
Je pointe sur B6,
Je me décale vers la droite, vers le bas,
...
Je ne comprends pas pourquoi tu veux ajouter + 9 à ton nombre de régions. Si tu as n régions, il faut itérer de 0 à n-1, donc le code proposé devrait bien fonctionner
Par contre, je ne sais pas si ta méthode pour calculer le nombre de régions est bon.
J'aurais tendance à dire que non. Ajouter 6 puis diviser par 8, ça sent la planture.
Perso, je fais autrement pour trouver le dernier élément. Je vais à la dernière cellule de la feuille et je reviens sur la dernière. Ca évite de se planter à cause d'une cellule vide. Un exemple sur les lignes : ici, à transposer pour tes colonnes.
Explique un peu comment est organisée ta ligne 10.
------------------
Si tu estimes que ton problème est résolu, élis la moins mauvaise des réponses comme étant la meilleure, le sujet passera alors en [Résolu].
Il ne faut surtout pas mettre d'ActiveSheet, nulle part, jamais !
Et si ta macro tournant, tu changes de part, ou pour une raison quelconque, un autre classeur s'ouvre ? Voilà de quoi y remédier :
Set valeurs_source = ws_source.Range(ws_source.Cells(12, 2 + nb_regions * 8), ws_source.Cells(24, 8 + nb_regions * 8))
(Comme on a fait pour ws_Target.Range, d'ailleurs)
Les deux méthodes sont équivalentes. Mais je trouve que la seconde, avec les décalages est plus élégante : elle suit le raisonnement humain :
Je ne comprends pas pourquoi tu veux ajouter + 9 à ton nombre de régions. Si tu as n régions, il faut itérer de 0 à n-1, donc le code proposé devrait bien fonctionner
Par contre, je ne sais pas si ta méthode pour calculer le nombre de régions est bon.
J'aurais tendance à dire que non. Ajouter 6 puis diviser par 8, ça sent la planture.
Perso, je fais autrement pour trouver le dernier élément. Je vais à la dernière cellule de la feuille et je reviens sur la dernière. Ca évite de se planter à cause d'une cellule vide. Un exemple sur les lignes : ici, à transposer pour tes colonnes.
Explique un peu comment est organisée ta ligne 10.
------------------
Si tu estimes que ton problème est résolu, élis la moins mauvaise des réponses comme étant la meilleure, le sujet passera alors en [Résolu].
Salut
Il ne faut surtout pas mettre d'ActiveSheet, nulle part, jamais !
aie aie aie! heureusement que je n'en avais mis qu'un seul!
Du coup, facile à retirer.
Bon alors, je ne vais peut-être pas clôturer ce topic maintenant, car même si le resultat s'approche de ce que je souhaite, j'ai encore 2-3 bricoles qui vont peut-être necessiter un coup de main.. mais promis, j'y penserai une fois fini!
j'ai changé la methode pour calculer le nb de region et ça marche très bien
D'autre part, je fais maintenant un zoom sur
Et je lui demande de:
- dans la plage valeurs_target de ws_target, si les données de la colonne 4 (datant du mois précedent) sont = aux données de la colonne 4 de ws_source (du nouveau mois), efface-moi ces données (juste col 4) dans ws_target (je ne veux pas les montrer!) sinon fais ce que dois! J'ai donc fait
ai-je oublier qqch de grossier pour que ça ne marche pas?
Une meilleure méthode ?
Merci bien !
Citation :
Alors là, zéro pointé ! Il ne faut surtout pas mettre d'ActiveSheet, nulle part, jamais !
aie aie aie! heureusement que je n'en avais mis qu'un seul!
Du coup, facile à retirer.
Bon alors, je ne vais peut-être pas clôturer ce topic maintenant, car même si le resultat s'approche de ce que je souhaite, j'ai encore 2-3 bricoles qui vont peut-être necessiter un coup de main.. mais promis, j'y penserai une fois fini!
j'ai changé la methode pour calculer le nb de region et ça marche très bien
nb_regions = ((ws_source.Range("IV10").End(xlToLeft).Column + 7) - ws_source.Range("B10").Column) / 8
D'autre part, je fais maintenant un zoom sur
''Determine les adresses des plages à copier sur wb_target
Set valeurs_source = ws_source.Range(ws_source.Cells(12, 2 + nb_regions * 8), ws_source.Cells(24, 8 + nb_regions * 8))
Set valeurs_target = ws_target.Range(ws_target.Cells(10, nb_regions * 8 + 2), ws_target.Cells(22, nb_regions * 8 + 8))
Et je lui demande de:
- dans la plage valeurs_target de ws_target, si les données de la colonne 4 (datant du mois précedent) sont = aux données de la colonne 4 de ws_source (du nouveau mois), efface-moi ces données (juste col 4) dans ws_target (je ne veux pas les montrer!) sinon fais ce que dois! J'ai donc fait
Dim val_actn_source As Range, val_actn_target As Range
Set val_actn_source = ws_source.Range(ws_source.Cells(12, 3 + nb_regions * 8), ws_source.Cells(24, 3 + nb_regions * 8)) 'C12:C24
Set val_actn_target = ws_target.Range(ws_target.Cells(10, 3 + nb_regions * 8), ws_target.Cells(22, 3 + nb_regions * 8)) 'C10:C22
For Each val_actn_target In ws_target
If val_actn_target.Value = val_actn_source.Value Then
'copie colle valeurs & delete colonne 4
valeurs_target.Value = valeurs_source.Value
val_actn_target.Delete
Else ...
ai-je oublier qqch de grossier pour que ça ne marche pas?
Une meilleure méthode ?
Merci bien !
Super;merci
Alors pour reprendre en explication (et pas en code
):
J'ai ma plage de données source (valeurs_source), dans laquelle se trouve une plage de données (C12:C24 soit val_actn_source)
Je confronte cette plage à une autre se situant dans valeurs_target (C10:C22 soit val_actn_target)
Si les chiffres sont identiques, cela veut dire que mes données n'ont pas été mises à jour par le système. Je ne veux donc pas qu'elles apparaissent dans ws_target. (de meme que 2 autres plages qui sont liées, D10
22, pourc1, et F10:F22,pourc2).
Sinon, affect moi la valeurs des données des plages source aux plages target.
J'ai fait ça mais je bloque encore
à la ligne If, je veux comparer mes deuxplages, sont-elles identiques ou pas.
MERCI Zeb
Ps: tu auras remarqué que je me suis mis au Offset, sacré mode!!
Alors pour reprendre en explication (et pas en code
):J'ai ma plage de données source (valeurs_source), dans laquelle se trouve une plage de données (C12:C24 soit val_actn_source)
Je confronte cette plage à une autre se situant dans valeurs_target (C10:C22 soit val_actn_target)
Si les chiffres sont identiques, cela veut dire que mes données n'ont pas été mises à jour par le système. Je ne veux donc pas qu'elles apparaissent dans ws_target. (de meme que 2 autres plages qui sont liées, D10
22, pourc1, et F10:F22,pourc2). Sinon, affect moi la valeurs des données des plages source aux plages target.
J'ai fait ça mais je bloque encore
Set val_actn_source = ws_source.Range(regions_source.Offset(2, 1), regions_source.Offset(14, 1))
Set val_actn_target = ws_target.Range(regions_target.Offset(2, 1), regions_target.Offset(14, 1))
Set pourc1_target = ws_target.Range(regions_target.Offset(2, 2), regions_target.Offset(14, 2))
Set pourc2_target = ws_target.Range(regions_target.Offset(2, 4), regions_target.Offset(14, 4))
If val_actn_target.Value = val_actn_source.Value Then
For Each c In Union(val_actn_target, pourc1_target, pourc2_target)
'delete colonne 3,4,6
c.ClearContent
Next
Else
valeurs_target.Value = valeurs_source.Value
End If
à la ligne If, je veux comparer mes deuxplages, sont-elles identiques ou pas.
MERCI Zeb
Ps: tu auras remarqué que je me suis mis au Offset, sacré mode!!
Euh, si.
Ta ligne 7 n'est pas bonne. Tu ne peux pas comparer les valeurs d'une plage aux valeurs d'une autre plage. Il faut le faire cellule par cellule.
Sers-toi de ce que je t'explique dans la seconde partie de ce message.
Je te propose même de créer une fonction de comparaison à part, dont voici un prototype pertinent :
La zone #1, c'est la zone bleu foncé de mon schéma, la cellule #2, c'en est la cellule vert foncé.
Ta ligne 7 n'est pas bonne. Tu ne peux pas comparer les valeurs d'une plage aux valeurs d'une autre plage. Il faut le faire cellule par cellule.
Sers-toi de ce que je t'explique dans la seconde partie de ce message.
Je te propose même de créer une fonction de comparaison à part, dont voici un prototype pertinent :
Function Verif_Egalite_Plage(zone_1 As Range, cellule_2 As Range) As Boolean
La zone #1, c'est la zone bleu foncé de mon schéma, la cellule #2, c'en est la cellule vert foncé.
c'est bien ce que je me disais.. (non, sans blague!)
Alors j'ai repris le schema, mais apres plusieurs essais rien de bien ne sors.
Je pense que je n'en comprend pas le sens profond..
Donc
Jusqu'à la ligne 4, ça devrait aller. Par contre apres, je n'arrive pas à savoir comment on intègre le décalé et où?
- ma cellule_2 est l'adresse de la première des cases à remplir dans target.
- Je me sers du décalé entre la cellule de reference source et la cellule en cours source .. mais quelle est l'adresse de la cellule en cours source?, ça devrait être la 1ère de la zone normalement ??
Bon.. je recommence !
Le souci c'est qu'avec ça, la fonction reste sur la dernière valeur de la plage zone_1 ..
Alors j'ai repris le schema, mais apres plusieurs essais rien de bien ne sors.
Je pense que je n'en comprend pas le sens profond..
Donc
Function Verif_Egalite_Plage(zone_1 As Range, cellule_2 As Range) As Boolean
Set zone_1 = ws_source.Range(ws_source.Cells(12, 3 + nb_regions * 8), ws_source.Cells(24, 3 + nb_regions * 8))
Set cellule_2 = ws_target.Cells(10, 3 + nb_regions * 8)
For Each c In zone_1
cellule_2.Value = c.Value
Next
End Function
Jusqu'à la ligne 4, ça devrait aller. Par contre apres, je n'arrive pas à savoir comment on intègre le décalé et où?
- ma cellule_2 est l'adresse de la première des cases à remplir dans target.
- Je me sers du décalé entre la cellule de reference source et la cellule en cours source .. mais quelle est l'adresse de la cellule en cours source?, ça devrait être la 1ère de la zone normalement ??
Bon.. je recommence !
For Each c In zone_1
cellule_2.Offset(X, Y).Value = c.Value
Next
Le souci c'est qu'avec ça, la fonction reste sur la dernière valeur de la plage zone_1 ..
Lassé par la pub ? Créez un compte
- Contenus similaires :
- ForumMacro excel mise à jour
- ForumMise a jour d'une liste macro
- ForumMise a jour graphique vba
- ForumMise a jour openoffice mise a jour
- benchmarkVba création d'un onglet
- benchmarkVba création liste
- ForumVba création sheet
- ForumVba création onglet
- ForumCréation macro excel
- ForumVba création graphique
- Voir plus
![[:zeb:6] [:zeb:6]](http://m.bestofmedia.com/sfp/design/usr/fr/smilies/77/40/zeb:6.gif)
!