Base de données et Macro sur 2 onglets différents
Bonsoir 3GB,
je viens de faire copier coller de la macro sur ma base ...
j'ai plus de message d'erreur sur la macro mais l'onglet Sans Facture et Partiel sont vide, rien ne se déverse sur les onglets dédiés ...
Sub BC_2021()
Dim tsf(), tpart()
tCol = Array(2, 5, 3, 4, 6, 12, 11, 17, 20) '<<< numéros des colonnes à récupérer
t = Range("BC_21").Value
For i = LBound(t) To UBound(t) 'pour chaque ligne
Select Case t(i, 23) 'test sur la colonne 23 (la W)
Case "Sans Facture" 'si valeur = "Sans Facture"
n = n + 1: ReDim Preserve tsf(1 To UBound(tCol) + 1, 1 To n) 'alimentation tableau tsf
For k = LBound(tCol) To UBound(tCol)
tsf(k + 1, n) = t(i, tCol(k))
Next k
Case "Partiel" 'si valeur = "Partiel"
m = m + 1: ReDim Preserve tpart(1 To UBound(tCol) + 1, 1 To m) 'alimentation tableau tpart
For k = LBound(tCol) To UBound(tCol)
tpart(k + 1, m) = t(i, tCol(k))
Next k
End Select
Next i
With Sheets("Sans Facture") 'sur feuille SF
nvl = .Cells(.Rows.Count, 1).End(xlUp).Row + 1 'nouvelle ligne (première non vide en colonne 1)
If n > 0 Then .Cells(nvl, 1).Resize(n, UBound(tsf)) = Transpose(tsf) 'si tsf est non vide, il est collé
End With
With Sheets("Partiel") 'idem
nvl = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
If m > 0 Then .Cells(nvl, 1).Resize(m, UBound(tpart)) = Transpose(tpart)
End With
End Sub
Function Transpose(t)
ReDim temp(LBound(t, 2) To UBound(t, 2), LBound(t) To UBound(t))
For i = LBound(t) To UBound(t)
For k = LBound(t, 2) To UBound(t, 2)
temp(k, i) = t(i, k)
Next k
Next i
Transpose = temp
End Function
On est bien d'accord que je copie-colle la macro dans Macro que je l'enregistre, je ferme et je fais exécuter la macro ? je fais correctement les choses ... ? Ca peut venir de moi aussi que ca ne fonctionne pas :(
M'excuse de vous embêter encore une fois
Bien à vous
Nadège
Il faut se rendre sur l'onglet développeur (s'il n'est pas activé, il faut aller dans Fichier/Options/Personnaliser le ruban/Cocher Développeur).
Ensuite, il faut cliquer sur le bouton Visual Basic pour ouvrir l'éditeur. Une fois ouvert, Insertion/Module/double cliquer sur le module créé et coller le code en entier.
Enfin, exécuter le code avec la touche F5.
Mais, il n'y a pas de raison que ça ne marche pas étant donné que vous avez rencontré une erreur et donc que le code s'est bien exécuté.
Pouvez-vous essayer ce code :
Sub BC_2021()
Dim tsf(), tpart()
tCol = Array(2, 5, 3, 4, 6, 12, 11, 17, 20) '<<< numéros des colonnes à récupérer
t = Range("BC_21").Value
For i = LBound(t) To UBound(t) 'pour chaque ligne
Select Case t(i, 23) 'test sur la colonne 23 (la W)
Case "Sans Facture" 'si valeur = "Sans Facture"
n = n + 1: ReDim Preserve tsf(1 To UBound(tCol) + 1, 1 To n) 'alimentation tableau tsf
For k = LBound(tCol) To UBound(tCol)
tsf(k + 1, n) = t(i, tCol(k))
Next k
Case "Partiel" 'si valeur = "Partiel"
m = m + 1: ReDim Preserve tpart(1 To UBound(tCol) + 1, 1 To m) 'alimentation tableau tpart
For k = LBound(tCol) To UBound(tCol)
tpart(k + 1, m) = t(i, tCol(k))
Next k
End Select
Next i
With Sheets("Sans Facture") 'sur feuille SF
nvl = .Cells(.Rows.Count, 1).End(xlUp).Row + 1 'nouvelle ligne (première non vide en colonne 1)
If n > 0 Then .Cells(nvl, 1).Resize(n, UBound(tsf)) = Transpose(tsf) 'si tsf est non vide, il est collé
End With
With Sheets("Partiel") 'idem
nvl = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
If m > 0 Then .Cells(nvl, 1).Resize(m, UBound(tpart)) = Transpose(tpart)
End With
msgbox join(array("n = " & n, "m = " & m, "Ubound(t) = " & ubound(t), "ubound(t, 2) = " & ubound(t, 2)), vblf)
End Sub
Function Transpose(t)
ReDim temp(LBound(t, 2) To UBound(t, 2), LBound(t) To UBound(t))
For i = LBound(t) To UBound(t)
For k = LBound(t, 2) To UBound(t, 2)
temp(k, i) = t(i, k)
Next k
Next i
Transpose = temp
End Function
Et me communiquer les valeurs renvoyées ?
C'est pour que je puisse contrôler les valeurs des variables.
Pouvez-vous enlever ce msgbox et le remplacer par :
msgbox join(array("tpart(1, 1) = " & tpart(1, 1), "tsf(1, 1) = " & tsf(1, 1), "nvl = " & nvl), vblf)
La variable nvl est celle correspondant à tpart car j'ai utilisé 2 fois la même variable... En les distinguant, on pourrait tester les 2, sinon, il faudrait mettre ce msgbox après chacun des 2 derniers with
D'accord, très bien !
Maintenant, rendez-vous sur votre feuille Partiel, allez à la ligne 3962, vous verrez vos données normalement.
Il doit y avoir le même problème sur l'autre feuille.
Donc je vous conseille de supprimer totalement le contenu des 2 feuilles puis de réexécuter le code.
Je vais vous donner un fichier de toute façon qui gère la mise en forme du tableau de destination.
CA FONCTIONNE ... VOUS ETES UN GENIE
j'ai plus qu'a insérer mes entêtes de mon tableau de base ....
Juste une petite question : quand je vais rajouter les bons de commande de Novembre, je n'ai rien à modifier sur la MACRO ?
Merci, merci, merci pour TOUT ... et surtout pour votre Patience ... Merci
Ah génial, je suis super content !
En fait, la macro ajoute les données à la suite des autres pour le moment. Dans ce cas, il est possible que vous ayez des doublons ? Ensuite, les données ne sont pas mises sous forme de tableau structuré. Donc c'est légèrement incomplet mais ça mis à part, il n'y a rien à changer. La seule adaptation envisageable, ce serait de rajouter des critères à retenir.
Moi aussi trop contente, contente d'avoir enfin un outil qui me permettra de gagner beaucoup beaucoup de temps car à ce jour, je faisais ligne par ligne ...
Merci encore pour votre aide et votre patience vraiment ...
Je viens de faire une mise en forme conditionnelle pour savoir si j'avais des doublons et je n'en ai pas ni sur Sans Facture ni sur Partiel ...
Je vais mettre mes tableaux en forme ... en espérant que lorsque je mettra à jour la macro que ma mise en forme ne bouge pas lol :) Si la mise en forme ne bouge pas avec une mise à jour de macro puis je mettre les onglets en tableau structuré ?
J'aimerai vraiment a voir vos connaissances et le temps pour me former ... Autant pour les fonctions je me suis formée seule autant pour la VBA je n'arrive pas à me mettre dedans malgré les tutos, les livres et autres ...
Je vous en prie, ça me fait plaisir !
Tant mieux pour les doublons mais en fait, je voulais savoir si vous désiriez écraser les précédentes données par les nouvelles à chaque exécution de la macro ou les ajouter les nouvelles à la suite des anciennes.
Justement, voici le fichier que je vous ai promis :
Il contient :
- une feuille avec un tableau nommé "BC_21" (le nom de la feuille n'a pas d'importance) qui contient 23 colonnes dont la 23è est nommée ETAT,
- un "bouton" pour extraire les données selon critères (lié à la macro Extraire): Ce bouton peut être supprimé et pour alléger la présentation, l'idéal serait d'exécuter la macro Extraire lors d'un double-clic.
- un bouton pour supprimer les feuilles nouvellement créées (celles commençant pas un T et contenant un _). Le bouton sert à faire des essais. A terme, il faudra le supprimer et effacer la macro raz liée.
La macro Extraire :
Sub Extraire()
'If MsgBox("Voulez-vous lancer l'extraction ?", vbYesNo) <> vbYes Then Exit Sub
With New Divider
.Divide TableRef:="BC_21", _
Field:="ETAT", _
vCriteria:=Array("Sans Facture", "Partiel"), _
vColumns:=Array(2, 5, 3, 4, 6, 12, 11, 17, 20), _
Operation:=AddValues
End With
End Sub
exécute la macro Divide paramétrée en dur.
Les paramètres sont :
TableRef : Le nom du tableau structuré (ou l'adresse mais le code est prévu pour traiter un TS),
Field : La colonne contenant les critères textuels à tester (on peut mettre le nom de la colonne ou son index)
vCriteria (optionnel) : tableau des critères (chaque argument générera une feuille si correspondance). Si l'argument est omis, on crée autant de feuilles qu'il n'y a de valeurs dans la colonne Field.
vColumns (optionnel) : tableau des colonnes à récupérer (nom ou index). Si omis, on récupère toutes les colonnes.
vNewHeaders (optionnel) : tableau des nouveaux noms d'en-têtes à définir. Si omis, on garde ceux de la source. N'apparait pas ici.
vFormats (optionnel) : tableau des formats à appliquer sur la destination. Si omis, on reprend les formats de la source. N'apparait pas ici.
Operation (optionnel) : choix entre remplacer les données ou ajouter les données. Si omis, les données sont remplacées (attention !).
Attention, j'ai essayé de prévoir pas mal de cas mais je n'ai pas tout géré. Il faut donc être attentif aux noms et formats à définir, susceptibles de provoquer un bug non géré. Il faut adapter la macro Divide à chaque modification de la structure des tableaux de destination.
Et évidemment, lorsque les arguments vColumns, vNewHeaders et vFormats sont renseignés, il faut qu'ils contiennent le même nombre d'éléments.
Pour utiliser le fichier, il faut juste que vous colliez votre vrai tableau à la place de celui-ci, adaptiez le cas échéant les arguments (Field notamment et Operation probablement).
Le code est a priori compatible avec Mac, à un détail près (enfin je crois, pas testé) : le nom du paramètre xllistobjecthasheaders (de la macro GetLoRange du module de classe Divider) doit être remplacé par hasheaders.
Sinon, vous devriez vraiment vous former. Je regrette d'avoir perdu plusieurs années avant de me lancer. Si j'avais découvert plus tôt, j'aurais pu gagner un temps fou... En tout cas, il faut y aller petit à petit, pour des choses utiles (export pdf, impression, ...) en se servant au départ l'enregistreur de macros et découvrir ce qui est incontournable et permet de progresser : les conditions, les boucles, les tableaux dynamiques, ...
En fait, il faut avoir des objectifs de réalisation (faire telle macro, telle fonction) tout simplement puis ça vient tout seul et on y prend du plaisir.
Bonne soirée,
Bonjour 3GB,
je vous remercie infiniment pour votre fichier il va mettre ultra utile ...
Je vais me pencher sur la VBA ... vous avez raison petit à petit selon mon besoin je devrais pouvoir m'y mettre :)
En attendant, je réitère mes écrits, je vous remercie infiniment pour votre patience et votre gentillesse.
Merci pour tout,
bien à vous
et à bien vite
Nadège
Bonjour Nadège,
Je vous en prie !
Oui, vous y gagnerez, c'est une certitude et ça permet de comprendre Excel beaucoup mieux ! En fait, on passe du temps à programmer mais ce temps permet d'en gagner dans nos tâches quotidiennes...
Merci à vous également pour votre gentillesse !
Très bonne continuation,
Et à bientôt peut-être,
Bonjour,
Pouvez-vous m'expliquer comment supprimer les options dans la commande divide en dur car quand je supprime quelque chose ça se plante.
Merci
Bonjour danval,
Avez-vous un problème précis sur lequel vous voulez des explications ? Car j'ai justement laissé une petite notice sur le post suivant :
vers lequel je vous ai redirigé.
Il faut un tableau structuré de départ (dont on extrait les données). Le nom de ce tableau est à saisir dans la paramètre TableRef. Il faut un champ de critères (une colonne en l'occurrence) à cibler par sa position dans le tableau ou par son nom. Il s'agit du paramètre Field. Le reste est optionnel et quand même détaillé plus haut.
Si vous me faites voir votre code, ou m'expliquez le besoin (détail des critères notamment), je pourrais plus facilement l'adapter.
Cdlt,
Bonsoir 3GB,
comment allez vous ? Avez vous passez de bonnes fêtes ?
Je me permets de revenir vers vous car j'ai besoin de vous.
Pour faire suite à nos échanges de novembre dernier, sur la VBA que nous avons travaillés ensemble mon fichier fonctionnait à merveille.
Sinon que nous sommes en 2022 et que j'ai du faire un copier coller de mon fichier 2021 pour l'année 2022.
J'ai donc renommé mon fichier, mes onglets ... et j'ai injecté mes bons de commandes de Janvier 2022 dans l'onglet de Janvier.
Sinon que la Macro ne fonctionne plus, j'ai l'erreur suivante :
La macro est la suivante :
Sub BC_2021()
Dim tsf(), tpart()
tCol = Array(2, 5, 3, 4, 6, 12, 11, 17, 20) '<<< numéros des colonnes à récupérer
t = Range("BC_21").Value
For i = LBound(t) To UBound(t) 'pour chaque ligne
Select Case t(i, 23) 'test sur la colonne 23 (la W)
Case "Sans Facture" 'si valeur = "Sans Facture"
n = n + 1: ReDim Preserve tsf(1 To UBound(tCol) + 1, 1 To n) 'alimentation tableau tsf
For k = LBound(tCol) To UBound(tCol)
tsf(k + 1, n) = t(i, tCol(k))
Next k
Case "Partiel" 'si valeur = "Partiel"
m = m + 1: ReDim Preserve tpart(1 To UBound(tCol) + 1, 1 To m) 'alimentation tableau tpart
For k = LBound(tCol) To UBound(tCol)
tpart(k + 1, m) = t(i, tCol(k))
Next k
End Select
Next i
With Sheets("Sans Facture") 'sur feuille SF
nvl = .Cells(.Rows.Count, 1).End(xlUp).Row + 1 'nouvelle ligne (première non vide en colonne 1)
If n > 0 Then .Cells(nvl, 1).Resize(n, UBound(tsf)) = Transpose(tsf) 'si tsf est non vide, il est collé
End With
With Sheets("Partiel") 'idem
nvl = .Cells(.Rows.Count, 1).End(xlUp).Row + 1
If m > 0 Then .Cells(nvl, 1).Resize(m, UBound(tpart)) = Transpose(tpart)
End With
MsgBox Join(Array("tpart(1, 1) = " & tpart(1, 1), "tsf(1, 1) = " & tsf(1, 1), "nvl = " & nvl), vbLf)
End Sub
Function Transpose(t)
ReDim temp(LBound(t, 2) To UBound(t, 2), LBound(t) To UBound(t))
For i = LBound(t) To UBound(t)
For k = LBound(t, 2) To UBound(t, 2)
temp(k, i) = t(i, k)
Next k
Next i
Transpose = temp
End Function
et j'ai une erreur sur cette ligne :
MsgBox Join(Array("tpart(1, 1) = " & tpart(1, 1), "tsf(1, 1) = " & tsf(1, 1), "nvl = " & nvl), vbLf)
End Sub
j'ai tenté de modifier les 21 en 22, les 2021 et les 2022 ... mais c'est encore pire au niveau erreur
Pouvez vous m'aider à "débeuger" car cette VBA est vraiment trop pratique, et je ne me vois faire ligne par ligne pour les encours de mon service.
Vous remerciant par avance de l'aide que vous pourriez m'apporter,
je vous souhaite une bonne soirée,
merci d'avance
Nadège