2 fichiers, copie de certaines colonne vers 1 fichier résumé
Ouiiiiiii ça avance ! ça avance ! (grâce à toi Migou
Sur la sous procédure copie, j'ai éditer de cette façon:
Private Sub lancer_copie()
Dim i As Long
i = 6 ' numéro de la ligne sur laquelle on viendra inscrire les données
wkb_AA.Worksheets("Feuil1").Activate 'on travaille sur le classeurAA
Call copie("N°voiture", 2, i) 'appelle de la sous procédure copie("chaine",numéro de colonne dans classeurCC,numéro de ligne)
Call copie("nombredeporte", 4, 6) 'appelle la sous procédure copie pour la colonne "nombre de porte" l'envoyant en 4eme colonne sur la 6eme ligne
wkb_BB.Worksheets("Feuil1").Activate 'idem
Call copie("N°voiture", 2, i)
Call copie("ventes", 1, 6)
Call copie("origine", 3, 6)
End SubÇa semble fonctionnait ( mais mettre 2 fois dans le code la ligne qui est en commun sur le classeurAA et BB fait qu'elle se superpose l'une après l'autre. Donc je n'en garderais qu'une sur les 2 si je dis pas top de bêtise).
Et j'ai supprimé l'incrémentation via la variable "j", tu confirme que pour le résultat attendu j'ai bien fais ?
Je suis super contente parce que j'ai enfin assimiler (je crois le fonctionnement des procédures) que tu t'efforces de m'expliquer depuis 2 pages ^^
J'aurais bien quelques petits trucs supplémentaires a demander, mais j'attends de voir si tu es toujours d'attaques. Ce qui risque de me tracasser maintenant c'est la méthodo sur la sauvegarde que je voudrais obtenir (cf. mon petit post du dessus
Merci mille fois !
Jenny a écrit :Le nombre de lignes sur les 2 fichiers est similaires, et la seul colonne que ces 2 fichiers aient en commun est la colonne "N° voiture " (présente en col 1 pour ClasseurBB, et présente en col3 pour classeurAA) pour le reste toutes les colonnes sont différentes mais il y a bien une correspondance entre les données puisque le "N°voiture" est ordonné de la même façon sur les 2 fichier.
Sur ce point il faut que tu sois certaine d'avoir toujours les mêmes numéros de voiture, le même nombre de voiture et qu'ils soient ordonnés de la même façon sur tes 2 fichiers. Si c'est le cas alors ça change effectivement ce que j'avais fait, j'avais mal compris la correspondance entre les 2 fichiers.
En revanche si tu n'en n'es pas certaine ça change tout, puisqu'on ne peut plus se contenter de juxtaposer les données des 2 feuilles. Il faut alors faire la copie sur une des feuilles, puis pour la deuxième faire une recherche ligne par ligne du numéro de voiture et coller la cellule au numéo de voiture correspondant.
Si tu optes pour le deuxième cas qui est de loin le plus sûr (ça permet d'éviter des erreurs dont tu ne t'apercevrais que trop tard) commence par trier tes données par numéro de voiture pour gagner du temps d'exécution. L'algorithme serait du type :
- Je trie les données de tous les classeurs puis
- Je copie les données de classeurAA vers classeur CC puis
- Pour chaque colonne de BB alors
- Pour chaque ligne (cellule) de BB alors
- Je récupère le numéro voiture
- Je me positionne sur CC et je cherche le numéro voiture
- Quand je trouve le numéro de voiture sur CC alors je colle dans la colonne correspondante
Jenny a écrit :A chaque fois que je lance la macro, j'aimerais qu'il soit crée un nouveau fichier (donc que la macro me demande dans une boîte de dialogue "enregistrer sous: ....nom.....") qui reprend la structure de mon masque et qui soit allimenté par les donnée contenu dans les 2 fichiers classeurs sources (AA et BB). De cette façon je peux après un temps X faire un retour en allant ouvrir un des fichiers stocké dans un dossier et crée il y a plusieurs semaines (j’intitulerais par exemple les fichier: Analyse_semaine1 , Analyse_semaine2, Analyse_semaine3, etc...)
Pourquoi s'embêter à créer un nouveau fichier ? Ce que j'ai rédigé sur mon dernier post fonctionne très bien. On travaille toujours sur le classeurCC, on effectue tout les traitements sur ce même classeur sans enregistrer. Puis à la fin de l'exécution de la macro on lance le saveas filename pour enregistrer sous un autre nom de fichier.
Ainsi le classeurCC reste intact.
Pour choisir toi-même où le sauvegarder il te faut remplacer la ligne qui contient le SaveAs :
ThisWorkbook.SaveAs ThisWorkbook.Path & "\Final.xls"par celle_ci :
Application.Dialogs(xldialogsaveas).ShowJenny a écrit :Ça semble fonctionnait ( mais mettre 2 fois dans le code la ligne qui est en commun sur le classeurAA et BB fait qu'elle se superpose l'une après l'autre
Bah oui du coup, je pensais que tu voulais le coller en dessous. Le i ne sert plus à rien puisque tu copies toujours sur la même ligne :
Private Sub lancer_copie()
wkb_AA.Worksheets("Feuil1").Activate
Call copie("N°voiture", 2)
Call copie("nombredeporte", 4)
wkb_BB.Worksheets("Feuil1").Activate
Call copie("ventes", 1)
Call copie("origine", 3)
End Sub
Private Sub copie(ByVal chaine As String, ByVal numcol As Byte)
Dim valeur As String
For colonne = 1 To Cells(4, Cells.Columns.Count).End(xlToLeft).Column
valeur = Replace(Cells(4, colonne).Value, " ", "")
If valeur = chaine Then
Range(Cells(5, colonne), Cells(Range("A" & Rows.Count).End(xlUp).Row, colonne)).Copy _
ThisWorkbook.Worksheets("Feuil1").Cells(6, numcol)
Exit For
End If
Next
End SubC'est plus agréable à l'oeuil 8)
J'aurais bien quelques petits trucs supplémentaires a demander, mais j'attends de voir si tu es toujours d'attaques. Ce qui risque de me tracasser maintenant c'est la méthodo sur la sauvegarde que je voudrais obtenir (cf. mon petit post du dessus ).Normalement c'est bon (cf dessus également) mais si tu as des questions tu peux les poser quand même.
Re-coucou
Je viens de vérifier mes 2 fichiers sources, et il y bien concordance des 2 colonnes sur chaque tables (j'ai coupé l'une d'entre elles que j'ai juxtaposé à coté de l'autre pour vérifier et tout concorde). Ouffff, ça m'évite l'opération de tri
Grâce à toi j'ai une base solide, j'adore ce type d’architecture où la macro lance des procédures qu'on crées les unes à la suites des autres.
J'ai 2 petites dernières turpitudes dont je te parlais un peu plus haut :
1) Si je souhaite retravailler les données, est-ce qu'il me suffit de créer une nouvelle sous procédure juste après la procédure de copie, et avant celle de l’enregistrement j'imagine ? Par exemple, je souhaite diviser le nombre de porte par 2 (même si c'est un non sens, juste pour l'exemple
Private Sub divison_porte (ByVal chaine As String, ByVal numcol As Byte)
Range("nombredeporte",4).Select
GoSub div2Si le code est bon, la hiérarchisation du script complet serait-il :
a) Macro qui lance toutes les sous procédures les unes à la suite des autres
b) procédure de copie des données sources vers classeurCC (bilan)
c) procédure de manipulation des données directement sur CC
d) enregistrement d'une copie du classeurCC
J'ai juste quelque doute sur cette logique et la place du 3eme point notamment ?
2) partant sur le fait que je puisse intercaller des sous procédure de manipulation des données, admettons que je veuille rejeter vers un nouvelle onglet les voitures dont l'origine est péruvienne, le script donnerait-il quelque chose de semblable :
Private Sub table_rejet(ByVal chaine As String, ByVal numcol As Byte)
Dim origine As String
For colonne = 1 To Cells(4, Cells.Columns.Count).End(xlToLeft).Column
If origine = "Pérou" Then
... action d'exclure chaque ligne dans son intégrité vers un onglet appeler "rejets" (sur ce même classeur)
Exit For
End If
Next
End SubL'onglet rejet aurait exactement la même structure que l'onglet Feuille1, du coup je suis en train de me demander si on pourrait pas utiliser à nouveau procédure_copie vers l'onglet rejet pour les voiture dont l'origine est péruvienne ?
Pardon d'ajouter une nouvelle contrariété au cas
Et sincère remerciements pour l'aide apportée
Je te conseille de créer une nouvelle sous-routine de copie, ton traitement est différent donc il n'y a pas de raison de réutiliser la même.
La hierarchisation de ton code serait bonne mais j'ai du mal à voir où tu veux en venir avec cette histoire de divisions de portes.
Le mieux est que tu essaies de le faire puis que tu m'envoies tes fichiers pour que je corrige si nécessaire. Là tu as modifié du code et je n'ai pas accès à ce que tu as fait depuis.
A+
Coucou Migou
Je m'y suis prise toute la journée avec tout les supports dont je dispose et surtout avec tes explications, et je commence à sortir la tête de l'eau !!
Voilà le script tel qu'il est pour le moment :
Dim wkb_AA As Workbook, wkb_BB As Workbook
'-----------------------------------------------------------------------------------------------------------
Sub completer()
Application.ScreenUpdating = False 'accélère l'exécution du code de la macro en désactivant le rafraich. écran
Dim position As Worksheet 'variable position en tant que feuille
Set position = ThisWorkbook.ActiveSheet 'initialise la variable objet "position" pour qu'elle pointe vers la feuille active de ce claseur
nettoyer 'toutes les sous procédures qui seront appelées une par une dans ma macro
ouvrir_fichiers 'idem
lancer_copie 'idem
enregistrer_copie 'idem
position.Activate 'feuille de calcul "position" activée.
End Sub
'-----------------------------------------------------------------------------------------------------------------
Private Sub nettoyer()
Range(Cells(6, 1), Cells(6, 4)).Select 'selectionne la plage de données à cleaner
Range(Selection, Selection.End(xlDown)).Clear 'supprime l'objet range défini au dessus entierement
End Sub
'-----------------------------------------------------------------------------------------------------------------
Private Sub ouvrir_fichiers()
Set wkb_AA = Workbooks.Open(ThisWorkbook.Path & "\ClasseurAA.xls") 'ouvre les 2 classeurs
Set wkb_BB = Workbooks.Open(ThisWorkbook.Path & "\ClasseurBB.xls")
End Sub
'-----------------------------------------------------------------------------------------------------------------
Private Sub lancer_copie() 'Je pense avoir intégrée ci dessous le max de colonne, si j'en ai oubliées c'est par distraction (cette étape est bien assimilée pour moi)
wkb_AA.Worksheets("Feuil1").Activate
Call copie("N°voiture", 2)
Call copie("nombredeporte", 4)
call copie("poids",12)
wkb_BB.Worksheets("Feuil1").Activate
Call copie("ventes", 1)
Call copie("origine", 3)
Call copie("prix", 9)
Call copie("codedéfaut", 10)
End Sub
'-----------------------------------------------------------------------------------------------------------------
Private Sub copie(ByVal chaine As String, ByVal numcol As Byte)
Dim valeur As String
For colonne = 1 To Cells(4, Cells.Columns.Count).End(xlToLeft).Column
valeur = Replace(Cells(4, colonne).Value, " ", "")
If valeur = chaine Then
Range(Cells(5, colonne), Cells(Range("A" & Rows.Count).End(xlUp).Row, colonne)).Copy _
ThisWorkbook.Worksheets("Feuil1").Cells(6, numcol)
Exit For
End If
Next
End Sub
'-----------------------------------------------------------------------------------------------------------------
Private Sub enregistrer_copie()
Application.DisplayAlerts = False
FermerClasseur ("ClasseurAA.xls")
FermerClasseur ("ClasseurBB.xls")
Application.Dialogs(xlDialogSaveAs).Show 'ouvre une boite de dialogue "enregistrer sous"
Application.DisplayAlerts = True
End Sub
'-----------------------------------------------------------------------------------------------------------------
Sub FermerClasseur(nomclasseur As String)
On Error Resume Next
Workbooks(nomclasseur).Close False
End SubPour les opérations de traitement qui me reste à faire, j'ai réédité le contenu de mes 3 classeurs (qui sont attachés à ce poste) pour que ça soit moins confus que lors de mes dernières tentatives (
Il me reste quelques opérations de traitement (j'ai bien une idée de la façon de concevoir ça mais il reste à faire)
1) LA première opération c'est d'envoyer les véhicules qui ont pour "origine" (colonne4, ClasseurBB) le Pérou dans l'onglet rejets du ClasseurCC. L'onglet contiendrait exactement les mêmes intitulés des colonnes que sur la feuille1 (même masque, mais leurs simple présence dans l'onglet rejets suffirait au lecteur pour comprendre que les données s'y trouvant valent : origine = "Pérou")
D’après tes dire je dois refaire une sous procédure de copie mais qui serait propre à l'onglet rejets.
Donc ... j'me lance :
- Sachant que la colonne "origine" (colonne4, ClasseurBB) apparait que sur le classeurBB, je ne peux pas lui dire d'aller extraire les lignes du classeurCC.worksheet("Feuil1") contenant origine = "Pérou" pour les envoyer sur l'onglet rejets.
- Je dois donc lui dire d'aller sur (colonne4, ClasseurBB) et de renvoyer toutes les lignes contenant origine="Pérou" (mais il faudrait que l'onglet rejet conserve le même masque que l'onglet "Feuille1" de ce ClasseurCC, ce qui m'oblige de nouveau à une selection et assignation des colonnes comme nous l'avions fait pour la copie des colonnes dans la procédure "lancer_copie" ?
- Je devrais donc créer une sous procédure "copie_rejets" qui irait chercher les éléments des lignes associées à la valeur origine= "Pérou" sur le ClasseursBB.
- Je me rend compte que là va se poser le problème de solidarisation des lignes, je peux pas extraire 3 lignes Pérou de ma base sans leur associer les autres infos(N°voiture, vente, etc..) par lignes qui les concerne....
- La grosse tuile c'est que la colonne "origine" existe uniquement sur le ClasseurBB, et que sur "l'onglet rejet" figure des éléments des 2 classeurs AA et BB. Mais une seule colonne est commune aux 2 classeurs, c'est la colonne "N°voiture" (colonne 3 pour AA, et colonne 2 pour BB). J'imagine la complexité de la chose mais peut-on faire un lien entre les 2 tables en se servant de la colonne pivot "N°voiture" pour afficher les colonnes qui ne concerne que les voiture rejetées parce que origine= "Pérou" ?
Private Sub copie_rejets(ByVal chaine As String, ByVal numcol As Byte)
Dim valeur As String
For colonne = 1 To Cells(4, Cells.Columns.Count).End(xlToLeft).Column
valeur = Replace(Cells(4, colonne).Value, " ", "")
If valeur = chaine Then
Range(Cells(5, colonne), Cells(Range("A" & Rows.Count).End(xlUp).Row, colonne)).Copy _
ThisWorkbook.Worksheets("Table rejets").Cells(6, numcol)
Exit For
End If
Next
End SubJ'avais prévu ceci dans la foulée, mais je ne sais pas où faire figurer l'instruction conditionnelle (IF origine="Pérou" THEN on copie les éléments des colonnes associées à cette ligne qui contient Pérou dans l'onglet rejets) :
Private Sub lancer_copie_rejets()
wkb_AA.Worksheets("Table Rejets").Activate
Call copie_rejets("N°voiture", 2)
Call copie_rejets("nombredeporte", 4)
Call copie_rejets("poids", 12)
wkb_BB.Worksheets("Table Rejets").Activate
Call copie_rejets("ventes", 1)
Call copie_rejets("origine", 3) 'redondant car dans l’onglet rejets se trouverait que les voiture qui ont pour origine le Pérou
Call copie_rejets("prix", 9)
Call copie_rejets("codedéfaut", 10)
End SubEt ma macro appellerait les procédure suivantes :
Dim wkb_AA As Workbook, wkb_BB As Workbook
Sub completer()
Application.ScreenUpdating = False 'accélère l'exécution du code de la macro
Dim position As Worksheet 'variable position en tant que feuille
Set position = ThisWorkbook.ActiveSheet 'initialise la variable position comme feuille active
nettoyer 'toutes les sous procédures qui seront appelées une par une dans ma macro
ouvrir_fichiers
lancer_copie
lancer_copie_rejets 'c'est là qu'on lance la copie des rejets vers ClasseurCC.worksheet("Table rejet")
enregistrer_copie 'idem
position.Activate 'feuille de calcul "position" activée.
End Sub- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Private Sub convertir_tonnes() 'on nomme la sous procédure
Range("K:K").Select 'conversion sur toute la colonne "poids"
GoSub div1000'passage de kilo à tonne
Ce qui ferait pour ma macro principale si on suppose que je désire ajouter d'autres procédures de manipulation de donnée une structure de ce genre ? :
nettoyer 'toutes les sous procédures qui seront appelées une par une dans ma macro
ouvrir_fichiers 'idem
lancer_copie 'idem
copie_des_rejets
convertir_tonnes
convertir_prix_£
....etc....
enregistrer_copie 'idem- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- Les 4 premiers caractères réfèrent un "code vendeur" en classeurCC (colonne5).
- Les 2 caractères suivants réfèrent une "norme véhicule" en classeurCC (colonne6).
- Les 3 derniers caractères réfèrent la "vitesse maxi" classeurCC (colonne5).
Je vais donc devoir créer une nouvelle procédure qui split les valeurs de "code produit" (colonne6, ClasseurAA) en 3 chaines pour les envoyer respectivement dans "code vendeur", "norme véhicule", "vitesse maxi" (3 colonnes autonomes) du classeur classeurCC .
Avec l'enregistreur de macro j'ai lancé une fonction GAUCHE(Cells;nombre de caractère sur la gauche à extraire), pour voir le code généré, mais je suis complétement perdue sur l'adresse des cellules à attribuer. Puis comme c'est une fonction que j'utilise peut être que je devrais créer non pas une sous procédure, mais plutôt une sous fonction en utilisant les fonctions d’extraction de type mid, instr, right, left... Bref, je suis à la dérive ...
Et si par exemple je veux convertir la vitesse maxi de km/h =====> mètres/sec (il me suffit de lancer une sous procédure de conversion comme je l'ai fait pour le point 2, ou est ce qu'il est préférable de le faire pendant l'intégration des données?
- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
La Longueur (m) et Largeur (m) (colonne 7 et 8 du ClasseurAA) devrait être rapatriées dans une unique colonne en ClasseurCC (colonne8) et séparées l'une de l'autre par la lettre "x". J'ai donc essayée dans procédure de copie de faire comme suit :
Private Sub lancer_copie()
wkb_AA.Worksheets("Feuil1").Activate
Call copie("N°voiture", 2)
Call copie("nombredeporte", 4)
Call copie("poids", 12)
Call copie("Longueur(m)" & " " & "x" & " " & "Largeur(m)", 8)
End SubMais ça ne donne aucun résultat
- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Mon intuition me dit de créer une sous procédure avec du conditionnelle. Mais dois-je me baser sur la même syntaxe que la boucle de copie ?
If code défaut="2" then ristourne="prix+250"En fait ce qui m'embête le plus, c'est cette histoire de valeurs stockée dans la mémoire et puis les résultats sont traités avant d'être copiés, ou si les données sont copiées/collées par l'instruction et ensuite on travaille dessus.
Euhhh, j'ai conscience que ça fait beaucoup d'un coup, mais c'est vraiment les dernières difficultés qui me reste, et je suis tellement contente d'avoir put adapter la méthodologie que tu m'a proposée vers des cas plus concrets avec des paramètres différents de nos exemples (et en plus ça donne des résultats tangible !
Enfin, je l'ai déjà dit, mais merci beaucoup et très sincèrement
Je continue de me pencher sur le code voir ce que je peux apporter déjà
Salut Jenny, je regarde ça dès que j'ai le temps. Ce sera probablement mercredi soir. A+
Coucou Migou
Merci de ne pas m'avoir abandonnée (même si tu as déjà beaucoup fais).
J'ai réédité mon post pour rendre les questions plus claires, les infos sur les valeurs sont localisées entres parenthèses, et les données sont plus inéligibles.
Je continue à travailler d’arrachepied mes scripts, et j’espère pouvoir intégrer la méthodologie que tu me proposera sur les données que je traite en parallèle (pour le moments ça fonctionne du tonnerre, je suis parvenue à tout refaire et je documente tout ce que je fais pour que ça me sois encore plus profitable).
Euh, oui je suis une fille très bavarde ....
Merci encore ! (comme ça c'est dit
1) LA première opération c'est d'envoyer les véhicules qui ont pour "origine" (colonne4, ClasseurBB) le Pérou dans l'onglet rejets du ClasseurCC. L'onglet contiendrait exactement les mêmes intitulés des colonnes que sur la feuille1 (même masque, mais leurs simple présence dans l'onglet rejets suffirait au lecteur pour comprendre que les données s'y trouvant valent : origine = "Pérou")
D’après tes dire je dois refaire une sous procédure de copie mais qui serait propre à l'onglet rejets.
Je pars du principe que les numéros de voitures sont uniques, ce qui n'est pas ton cas et pose mais je suppose que c'est une erreur dans les fichiers que tu m'envoies. Le raisonnement sera le suivant :
1) Identification de la colonne contenant le numéro de voiture sur le classeur BB.
2) Identification de la colonne contenant l'origine des voitures sur le classeur BB
2) Filtrage automatique des données sur le classeur BB pour ne conserver que les péruvienne.
3) Copie les données non filtrées sur le classeur CC.
4) Suppression du filtre.
On se retrouve donc avec les numéros de voitures péruviennes en colonne 2 du classeur CC. On va s'en servir pour récupérer les informations complémentaires sur AA.
1) identification de la colonne contenant les numéros de voiture dans AA
2) Identification de la colonne contenant les ventes dans AA
3) On parcours les numéros de voitures dans CC puis, pour chaque numéro de voiture ...
4) ... On parcours La colonne numéro de voiture dans AA.
5) S'il y a jointure / correspondance, on copie les infos qui nous intéressent
Voilà le code, j'ai tout mis dans la même Sub pour éviter de te perdre mais tu peux le découper si tu trouves trop lourd) :
Dim wkb_AA As Workbook, wkb_BB As Workbook
Sub completer()
Application.ScreenUpdating = False 'accélère l'exécution du code de la macro
Dim position As Worksheet 'variable position en tant que feuille
Set position = ThisWorkbook.ActiveSheet 'initialise la variable position comme feuille active
nettoyer 'toutes les sous procédures qui seront appellées une par une dans ma macro
ouvrir_fichiers 'idem
'lancer_copie 'idem
traiter_rejets
'enregistrer_copie 'idem
position.Activate 'feuille de calcul "position" activée.
End Sub
Private Sub nettoyer()
Range(Cells(6, 1), Cells(6, 4)).Select 'selectionne la plage de données à cleaner
Range(Selection, Selection.End(xlDown)).Clear 'supprime l'objet range défini au dessus entierement
End Sub
Private Sub ouvrir_fichiers()
Set wkb_AA = Workbooks.Open(ThisWorkbook.Path & "\ClasseurAA.xls") 'ouvre les 2 classeurs
Set wkb_BB = Workbooks.Open(ThisWorkbook.Path & "\ClasseurBB.xls")
End Sub
Private Sub lancer_copie()
wkb_AA.Worksheets("Feuil1").Activate
Call copie("N°voiture", 2)
Call copie("nombredeporte", 4)
Call copie("poids", 12)
wkb_BB.Worksheets("Feuil1").Activate
Call copie("ventes", 1)
Call copie("origine", 3)
Call copie("prix", 9)
Call copie("codedéfaut", 10)
End Sub
Private Sub copie(ByVal chaine As String, ByVal numcol As Byte)
Dim valeur As String
For colonne = 1 To Cells(4, Cells.Columns.Count).End(xlToLeft).Column
valeur = Replace(Cells(4, colonne).Value, " ", "")
If valeur = chaine Then
Range(Cells(5, colonne), Cells(Range("A" & Rows.Count).End(xlUp).Row, colonne)).Copy _
ThisWorkbook.Worksheets("Feuil1").Cells(6, numcol)
Exit For
End If
Next
End Sub
Private Sub traiter_rejets()
' Première étape : récupération des données de BB
Dim valeur As String, num As String
Dim origine As Byte, numero As Byte, ventes As Byte, nombreDePortes As Byte
orgine = 0: numero = 0: ventes = 0: nombreDePortes = 0
valeur = "": num = ""
wkb_BB.Activate
For colonne = 1 To Cells(4, Cells.Columns.Count).End(xlToLeft).Column
valeur = Replace(Cells(4, colonne).Value, " ", "")
If valeur = "N°voiture" Then numero = colonne
If valeur = "origine" Then origine = colonne
If valeur = "ventes" Then ventes = colonne
If Not origine = 0 And Not numero = 0 And not ventes =0 Then Exit For
Next
Range(Cells(4, 1), Cells(4, 1).End(xlToRight)).AutoFilter origine, "Pérou"
Range(Cells(5, numero), Cells(Range("A" & Rows.Count).End(xlUp).Row, numero)).Copy _
ThisWorkbook.Worksheets("Table Rejets").Cells(6, 1)
Range(Cells(5, numero), Cells(Range("A" & Rows.Count).End(xlUp).Row, numero)).Copy _
ThisWorkbook.Worksheets("Table Rejets").Cells(6, 2)
Range(Cells(5, origine), Cells(Range("A" & Rows.Count).End(xlUp).Row, origine)).Copy _
ThisWorkbook.Worksheets("Table Rejets").Cells(6, 3)
Range(Cells(4, 1), Cells(4, 1).End(xlToRight)).AutoFilter
' Seconde étape : récupération des données de AA
wkb_AA.Activate
numero = 0
For colonne = 1 To Cells(4, Cells.Columns.Count).End(xlToLeft).Column
valeur = Replace(Cells(4, colonne).Value, " ", "")
If valeur = "nombredeporte" Then nombreDePortes = colonne
If valeur = "N°voiture" Then numero = colonne
If Not nombreDePortes = 0 And Not numero = 0 Then Exit For
Next
ThisWorkbook.Worksheets("Table Rejets").Activate
For Each cell_CC In Range(Cells(6, 2), Cells(Range("B" & Rows.Count).End(xlUp).Row, 2))
num = Replace(cell_CC.Value, " ", "")
wkb_AA.Activate
For Each cell_AA In Range(Cells(5, numero), Cells(Range("A" & Rows.Count).End(xlUp).Row, numero))
If Replace(cell_AA.Value, " ", "") = num Then
Cells(cell_AA.Row, nombreDePortes).Copy ThisWorkbook.Worksheets("Table Rejets").Cells(cell_CC.Row, 4)
Exit For
End If
Next
ThisWorkbook.Worksheets("Table Rejets").Activate
Next
End Sub
Private Sub enregistrer_copie()
Application.DisplayAlerts = False
FermerClasseur ("ClasseurAA.xls")
FermerClasseur ("ClasseurBB.xls")
Application.Dialogs(xlDialogSaveAs).Show 'permet de créer un nouveau fichier enregistrer sous
Application.DisplayAlerts = True
End Sub
Sub FermerClasseur(nomclasseur As String)
On Error Resume Next
Workbooks(nomclasseur).Close False
End SubAttention : comme tu as des voitures qui ont le même numéro mais un nombre de portes différent, mon code te renvoies la première voiture rencontrée.
J'ai voulu codé ça sans me prendre la tête mais s'il s'avère que tu as plusieurs milliers de ligne dans ton vrai fichier, mon code (la partie récup des données de AA) pourra s'avérer assez lent. Pour l'optimiser tu peux faire un filtre sur les numéros de voiture qui t'intéressent de sorte à avoir immédiatement le nombre de porte.
2) La suite est liée à un remaniement/conversion des données, mettons que je veuille par exemple convertir la colonne poids(colonne 11, ClasseurCC, 1er onglet) de kg à tonne. J'ai juste à créer une sous procédure et l’appeler dans ma macro principale juste avant la sous procédure qui enregistre ?
Séléctionne ta plage et fait une boucle :
For Each cell In Range(TaPlage)
cell.Value = cell.Value / 1000
Next-Les 4 premiers caractères réfèrent un "code vendeur" en classeurCC (colonne5).
- Les 2 caractères suivants réfèrent une "norme véhicule" en classeurCC (colonne6).
- Les 3 derniers caractères réfèrent la "vitesse maxi" classeurCC (colonne5).
De mémoire, ça doit donner ça :
code_vendeur = Left(chaine, 4)
norme_vehicule = Mid(chaine, 5, 2)
vitesse_max = Right(chaine, 2)La Longueur (m) et Largeur (m) (colonne 7 et 8 du ClasseurAA) devrait être rapatriées dans une unique colonne en ClasseurCC (colonne8) et séparées l'une de l'autre par la lettre "x". J'ai donc essayée dans procédure de copie de faire comme suit :
Aucune chance que ça marche comme ça, créé toi une nouvelle Sub. Pour concaténer c'est effectivement un & :
cellule1.value = cellule2.value & cellule3.value 5) Le dernier traitement qui me turlupine, il faudrait qu'une sous procédure détecte que si sur le classeurCC la valeur du "code défaut" (colonne 10; ClasseurCC; Feuil 1) est égale à 2 ... alors, il envoie dans la colonne intitulée "ristourne" de ce même classeur (colonne 11 ClasseurCC) la valeur "prix" ((colonne 9 ClasseurCC) +250.
Mon intuition me dit de créer une sous procédure avec du conditionnelle. Mais dois-je me baser sur la même syntaxe que la boucle de copie ?
Oui
En fait ce qui m'embête le plus, c'est cette histoire de valeurs stockée dans la mémoire et puis les résultats sont traités avant d'être copiés, ou si les données sont copiées/collées par l'instruction et ensuite on travaille dessus.
Il n'est pas toujours nécessaire travailler avec des variables. Par exemple pour reprendre des prix et ristournes tu peux faire une boucle qui incrémente la ligne et se contente de :
If cells(ligne, 9).Value = 2 then Cells(ligne, 8).Value = Cells(ligne, 8).Value + Cells(ligne,10).value(Je met les numéros de colonnes un peu au hasard)
Ou plus rapide, inscrire la formule dans la cellule et utilisée la poignée de recopie (possible via VBA).
A+
Coucou Migou et merci d'être revenu à ma rescousse
Je travaille sur les éléments que tu m'as apportés depuis que tu as posté, donc j'accuse un peu la fatigue et ce que je fais ne tourne pas comme ça devrait.
Je me penche à nouveau sur tout ça à la première heure demain matin (et plus fraiche) .
Merci pour tout,
Jenny
Je dois être bien chiante en revenant ainsi à la charge, mais j'aimerais tellement que cette macro fonctionne
Tout ça pour dire que je suis encore en galère, et je croise les doigts pour que tu es encore la patience de t'occuper de mon cas.
1) -------------------------------------------------------------------------------------------------------------------------------------------------------------------------
J'ai repris le script pour exclure les voitures qui ont pour origines "Pérou" est malheureusement ça ne tourne pas chez moi. J'ai relevée une erreur dans un intitulé mais même en corrigeant, rien n'y fait. La sous procédure copie toutes les voitures dans l’onglet rejets (d'ailleurs ça n'est pas une erreur, on peut très bien avoir plusieurs voitures avec le même numéro, l'important c'est de détecter "Pérou" est d'exclure la ligne") .
Est-ce qu'on ne pourrait pas faire plus simplement avec ta permission:
- Si j'ajoute la colonne "origine" dans mon classeurCC, j'alimente cette colonne avec la sous procédure de copie conventionnelle (que je maitrise bien maintenant), on lui dit alors de fouiller ligne par ligne le classeurCC Feuil1, puis dès qu'il détecte la ligne "origine"= "Pérou", il l'envoie vers l'onglet rejet de ce même classeur. Une fois qu'il à tout exclut, on lui demande de cacher la colonne "origine" sur les 2 classeurs.
C'est pas très jojo, mais même en m'y reprenant toute l'après midi, et essayant de comprendre et commentant le script via tri, je ne m'en sors pas
2) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Une bonne nouvelle pour la suite , Youpiii !!!
La procédure de conversion fonctionne magnifiquement bien, j’ai testé ca sur pleins d’autres colonnes et de type de données, rien à redire. Le script manque d’élégance mais les résultats sont bons (j’y ai même ajouté un Selection.NumberFormat = "0.0..etc…" pour peaufiner).
Private Sub conversion()
Range("L6").Select
For Each cell In Range(Selection, Selection.End(xlDown))
cell.Value = cell.Value / 1000
Next
End SubPar contre et assez bizarrement la procédure de conversion ne fonctionne pas avant la sous procédure d’enregistrement des données. Mais elle tourne impeccablement après l’enregistrement. C'est pas un peu ambigu d’un point de vu logique ?
3) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Pour l’extraction de caractère du « code produit » vers 3 colonnes, j’ai tenté de le faire directement dans la procédure de copie intitulée (Private Sub lancer_copie) sous cette forme là :
Private Sub lancer_copie()
wkb_AA.Worksheets("Feuil1").Activate
Call copie("N°voiture", 2)
Call copie("nombredeporte", 4)
…..... etc...
Call copie("codevendeur" = Left("code produit", 4), 5)Mais la colonne reste vide (sans doute normal puisque la procédure attends le titre d’une colonne source pour lancer la copie).
Donc j’ai rapatriée via la procédure de copie la colonne « code produit » (Classeur AA colonne 6) telle qu’elle est vers le fichier CC. En espérant ensuite pouvoir retravailler le contenu de la colonne en créant une procédure de Left sur la colonne, mais la colonne reste désespérément identique.
Private Sub split_1()
Range("E6").Select
For Each cell In Range(Selection, Selection.End(xlDown)).Select
code_vendeur = Left(Selection, 4)
Next
End Sub4) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Pour l’opération de jonction, je n’ai pas plus de résultat. Je pense que je fais la confusion en pensant que « cell » désigne une cellule alors qu’il s’agit plutôt d’une variable qui doit être déclarée. Du coup j’ai une erreur script sans savoir comment solutionner.
Private Sub joindre()
Range("H6").Select
For Each cell In Range(Selection, Selection.End(xlDown)).Select
wkb_CC.Worksheets("Feuil1").Cells(6, 8).Value = wkb_AA.Worksheets("Feuil1").Cells(5, 8).Value & _
wkb_AA.Worksheets("Feuil1").Cells(5, 8).Value
Next
End Sub 5)---------------------------------------------------------------------------------------------------------------------------------------------------------------------
Pour le traitement conditionnel (si code défaut = 2 alors la « ristourne » vaux « prix » + 250).
Je fais la sous procédure suivante que je lance à partir de la macro principale. Mais là encore les résultats ne sont pas probants et rien ne se passe...
Private Sub recalcul()
Range("K6").Select
For Each cells In Range(Selection, Selection.End(xlDown)).Select
If cells(ligne, 10).Value = 2 Then cells(ligne, 11).Value = cells(ligne, 9).Value + 250
Next
End SubJe ne sais pas si tu aura encore le temps et la volonté de t'occuper de moi, mais sans vouloir insister sur les sentiments ça me permettrais de trouver enfin le sommeil.
Enfin .. merci encore
Jenny
Hop, juste un p'tit mot pour dire que le script de tri et de copie fonctionne maintenant parfaitement bien chez moi, et sur tout mes cas d'application. Je continue de plancher sur les points suivants.
Merci encore,
Jenny.
J'ai repris le script pour exclure les voitures qui ont pour origines "Pérou" est malheureusement ça ne tourne pas chez moi. J'ai relevée une erreur dans un intitulé mais même en corrigeant, rien n'y fait. La sous procédure copie toutes les voitures dans l’onglet rejets (d'ailleurs ça n'est pas une erreur, on peut très bien avoir plusieurs voitures avec le même numéro, l'important c'est de détecter "Pérou" est d'exclure la ligne") .
Sauf qu'au moment où tu vas récupérer le nombre de portes à partir des numéros de voitures fraîchement copiés, on se retrouve a avoir des voitures qui ont le même numéro mais un nombre de portes différents. On est censé renvoyé quoi du coup ? Mon code comme je te l'ai dit, renvoie le nombre de portes de la première voiture trouvée et passe au numéro de voiture suivant.
La procédure de conversion fonctionne magnifiquement bien, j’ai testé ca sur pleins d’autres colonnes et de type de données, rien à redire. Le script manque d’élégance mais les résultats sont bons (j’y ai même ajouté un Selection.NumberFormat = "0.0..etc…" pour peaufiner).Fais particulièrement attention quand tu manipules Selection.End(xlDown), si tu as des cellules vides il est possible que la sélection n'aille pas réellement jusqu'à la dernière ligne. Pour résoudre le problème tu peux te faire une fonction qui renvoie le numéro de la dernière ligne, basée sur une colonne qui sera à coup sur pleine.
Call copie("codevendeur" = Left("code produit", 4), 5)
Cela n'a strictement aucun sens.
Donc j’ai rapatriée via la procédure de copie la colonne « code produit » (Classeur AA colonne 6) telle qu’elle est vers le fichier CC. En espérant ensuite pouvoir retravailler le contenu de la colonne en créant une procédure de Left sur la colonne, mais la colonne reste désespérément identique.
Private Sub split_1() Range("E6").Select For Each cell In Range(Selection, Selection.End(xlDown)).Select code_vendeur = Left(Selection, 4) Next End Sub
Normal, la c'est ta variable qui prend la valeur de la sélection, mais à aucun moment tu n'écris le résultat dans la cellule. Il est donc perdu dès que tu attaque le tour de boucle suivant.
Je n'ai pas excel sous la main donc le code est à tester :
Private Sub split_1()
Range("E6").Select
For Each cell In Range(Selection, Selection.End(xlDown)).Select
cell.value = Left(cell.value, 4)
Next
End SubPour tes problèmes de déplacement par ligne, va faire un tour du côté des tutoriaux VBA sur les boucles. Toi tu mélanges les boucles For et les boucles For each, c'est normal que ça ne donne rien.
Hello, et merci pour ton post
Oui je me rends compte des lacunes que j'ai (un peu moins maintenant que j'y travaille jours et nuit, mais il me reste à faire c'est évident). Je fais les choses au plus simples quit à utiliser des subterfuge telles que des colonnes temporaire que je masque en fin de procédure. C'est pas très jolie mais le résultats et là (à quelques secondes près d’exécution
Merci pour ta mise en garde sur la sélection de mes plages, je pense avoir repéré une façon de faire qui permet d'aller tout en bas de la feuille pour ensuite remonter chercher la première cellule rencontrée en remontant qui est non vide. Ça doit être ça si je dis pas de bêtise :
Cells(.Rows.Count, 1).End(xlUp).Rowou sinon :
Range([A1], [A65535].End(xlUp)Pour le reste j'ai su traiter la moitié des cas qui me bloquaient, et ceux qui restent en suspens, ... j'y travaille dur
Sincère remerciement à toi pour tout le temps que tu m'a accordé sur ces 4 pages et plus
Jenny.