Extraire donnée par macro + utilisation de tableau
Bonjour,
Je suis débutante dans les macros et j'en ai besoin pour traiter des données pour mon stage du coup je galère un peu lorsque les codes sont trop long
Mon problème est un peut compliqué et je ne sais pas si le sujet convient réellement. Je vais donc essayer d'être le plus explicite possible!
Mon but est de séparer une colonne contenant des dates et heures en 2 colonnes, une avec les dates l'autres avec les heures . Pour cela j'utilisais la fonction convertir avec la macro suivante
Sub Macro2()
Columns("A:A").EntireColumn.Select
Selection.TextToColumns Destination:=Range("A1"), DataType:=xlDelimited, _
TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, _
Semicolon:=False, Comma:=False, Space:=True, Other:=False, FieldInfo _
:=Array(Array(1, 1), Array(2, 1)), TrailingMinusNumbers:=True
End SubCe qui fonctionne très bien sur les 5 premières feuilles de mon classeur mais à la sixième elle échange le moi et le jour pour la moitié de ma colonne et l'autre moitié elle la met sous format texte et je ne peut changer le format de cellule
Du coup la solution que j'ai trouvée est d’extraire les données de la plage pour en faire deux colonnes mais il me reste un problème c'est que cette VBA utilise des tableaux et je ne sais pas comment faire en sorte qu'elle change de tableau a chaque feuille (je ne sais pas si c'est très explicite)
Sub Macro2b1()
Application.CutCopyMode = False
ActiveSheet.ListObjects.Add(xlSrcRange, Range("$A:$A"), , xlYes).Name =[color=#FF4000]"Tableau12"[/color]Ici la VBA réutilise le nom tableau 12 à chaque fois que je change de feuille ce qui est problématique
Columns("A:A").Select
ActiveWorkbook.Queries.Add Name:=[color=#FF4000]"Tableau12"[/color], Formula:="let" & Chr(13) & "" & Chr(10) & "_
Source = Excel.CurrentWorkbook(){[Name=""Tableau12""]}[Content]," & Chr(13) & "" & Chr(10) & " #""Type modifié"" = Table.TransformColumnTypes(Source,{{""Date/heure"", type text}})," & Chr(13) & "" & Chr(10) & " #""Fractionner la colonne par délimiteur"" = Table.SplitColumn(#""Type modifié"", ""Date/heure"", Splitter.SplitTextByDelimiter("" "", QuoteStyle.Csv), {""Date/heure.1"", ""Date/heure.2""})," & Chr(13) & "" & Chr(10) & " #" & _
"""Type modifié1"" = Table.TransformColumnTypes(#""Fractionner la colonne par délimiteur"",{{""Date/heure.1"", type date}})" & Chr(13) & "" & Chr(10) & "in" & Chr(13) & "" & Chr(10) & " #""Type modifié1"""J'ai un peu du mal à tout comprendre dans le code donc je ne sais pas trop quoi changer pour que ca fonctionne
With ActiveSheet.ListObjects.Add(SourceType:=0, Source:= _
"OLEDB;Provider=Microsoft.Mashup.OleDb.1;Data Source=$Workbook$;Location=Tableau12;Extended Properties=""""" _
, Destination:=Range("$B$1")).QueryTable
.CommandType = xlCmdSql
.CommandText = Array("SELECT * FROM [Tableau12]")
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.BackgroundQuery = True
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.AdjustColumnWidth = True
.RefreshPeriod = 0
.PreserveColumnInfo = True
.ListObject.DisplayName = "Tableau12_2"
.Refresh BackgroundQuery:=False
End With
End Sub
Voilà, j'ai joint un petit fichier pour vous aider à comprendre et m'aider à trouver la solution
Ha oui et il faut savoir que si je fait convertir la colonne date sans macro cela fonctionne très bien !
Merci d'avance à ceux qui prendront un peut de leur temps pour m'aider !
Bonjour,
Si tu mettais ton code sous balises Code, cela faciliterait la lecture...
Désolé mais je ne prendrai pas la peine de le lire jusqu'au bout en l'état, mais je vais tout de même regarder le fichier...
NB- J'apprécie aussi lorsqu'un code est indenté et ne comporte pas de Select...
Petit complément : je convertis tes tableaux Excel en plages normales...
Pas d'objection à travailler sur tableaux Excel, mais un tableau allant de la ligne 1 à la ligne 1048576 ! n'est pas ce que j'appellerais une bonne utilisation de tels tableaux !
Re, Voilà une proposition :
Sub TraitementDates()
Dim f As Worksheet, aa, dh, n&, i&, t!
t = Timer
For Each f In Worksheets(Array("Feuil1", "Feuil2", "Feuil3"))
With f
n = .Cells(.Rows.Count, 1).End(xlUp).Row
aa = .Range("A1:B" & n).Value
For i = 2 To n
dh = Split(aa(i, 1))
aa(i, 2) = TimeValue(Replace(dh(1), ".", ":"))
aa(i, 1) = CLng(DateValue(dh(0)))
Next i
aa(1, 1) = "Date": aa(1, 2) = "Heure"
With .Range("C1:D" & n)
.Value = aa
.Columns(1).NumberFormat = "dd/mm/yyyy"
.Columns(2).NumberFormat = "hh:mm:ss"
End With
End With
Next f
t = Round((Timer - t) * 1000, 0)
MsgBox "Durée de l'opération : " & t & " millisecondes"
End SubElle traite les 3 feuilles Feuil1 à Feuil3 (NB- Une boucle sur les feuilles peut se faire de diverses façons, mon choix visait simplement à ne pas toucher tes autres feuilles de travail).
J'ai éliminé l'extension de plage utiisée à toutes les lignes de la feuille sur Feuil1 et Feuil2, car cela avait tendance à commencer à faire sérieusement ramer le classeur... c'est redevenu plus fluide...
J'ai laissé dans la macro une mesure du temps d'exécution (à titre d'information...) : moins d'une demi-seconde pour les 3 feuilles, ce qui paraît acceptable...
Cordialement.
Bonjour,
Tout d'abord, merci pour vos réponses et désolé pour le code, c'est la première fois que j'utilise le forum et je n'avais pas vu le "bouton" pour mettre en code.
Ensuite pour votre "Petit complément " je travaille en effet sur un grand nombre de données et mon but est justement d'en faire des TCD pour réduire ce nombre de données. Il me faut donc passer par des tableaux mais le nombre de données varie d'un tableau à l'autre et donc pour que mes macros fonctionnent j'ai sélectionné toute la colonne (comme dans la première macro) ou alors je met le nombre de ligne de ma plage de donné la plus grande qui va généralement jusqu’à un peut plus de 12000 données donc oui un grand nombre!
Finallement comme dit précédemment je suis débutante en macro ... du coup je m'aide de l'enregistrement de macro pour les créer et je les modifie ensuite pour les appliquer correctement à mes différentes données en fonction de ce que je veux obtenir et en essayant de comprendre tout les codes.
Du coup je comprend que la notion
Dim f As Worksheet, aa, dh, n&, i&, t!sert a faire une boucle
mais malheureusement lorsque je l'applique a mon classeur il bloque a cette ligne
For Each f In Worksheets(Array("Feuil1", "Feuil2", "Feuil3")) même en changeant le nom des feuille ...
Donc je suis toujours bloqué et j'aurais aimé garder la notion de tableau car je vais devoir la réutiliser dans une autre macro.
En faite j'aimerais juste savoir comment créer un tableau avec une macro et qu'il lui donne un nom différent à chaque fois et comment sélectionner un tableau différent sur chaque feuille du coup ...
Et je répète je suis débutante mais j'aimerais quand même comprendre ce que je fait donc si on peut éviter les macro des boucle et des timing etc et rester sur des truc basic ca serait sympa !
Noisette
Bonjour,
Tu fais une série de confusions...
D'abord :
Dim f As Worksheet, aa, dh, n&, i&, t!Cette ligne déclare des variables, qui seront utilisées dans la procédure. Ces déclarations sont placées en tête, immédiatement après la déclaration de procédure (Sub...), c'est l'usage, et cet usage est très fortement recommandé, parce que VBA réserve ainsi les emplacements mémoire destinés aux variables immédiatement, avant d'attaquer l'exécution...
Au cas particulier, on déclare une variable objet de type Worksheet (feuille de calcul), 2 variables de type Variant, qui accueilleront des tableaux !, 2 variables de type Long, et la variable t (type Single) ne sert quant à elle qu'à mesurer la durée d'exécution...
For Each f In Worksheets(Array("Feuil1", "Feuil2", "Feuil3")) Cette ligne n'a aucune raison de bloquer ! dès lors que tu as 3 feuilles dans ton classeur nommées Feuil1, Feuil2 et Feuil3, on parcourt simplement en boucle un tableau (encore un !
Entre parenthèses, bloquer ne signifie rien, il faut indiquer de quoi il s'agit dans le détail : erreur d'exécution avec son numéro et la ligne où elle intervient, erreur de compilation, et sur quoi, etc.
Disons donc que pour travailler vite (et on y a intérêt avec plusieurs milliers de lignes) et bien, on travaille toujours avec des tableaux (et naturellement des boucles) le plus possible en dehors d'Excel...
Le terme de tableau étant générique, ne les confondons pas tous, une plage normale, selon son organisation (en lignes et colonnes) constituera un tableau. Un tableau Excel formalise une telle plage et la dote de propriétés particulières...
Ainsi que je l'ai dit dès le départ, ton classeur ramait sérieusement avant d'être sérieusement nettoyé, ce que j'ai fait. Et en particulier j'ai supprimé tes tableaux Excel qui faisait ramer ton classeur en raison de la très mauvaise utilisation que tu en fais !
Ne viens pas me dire que le classeur que j'ai retourné avec la macro ne fonctionne pas ! Je ne te croirai pas !
J'ai laissé la mesure du temps d'exécution pour montrer le résultat auquel on parvenait avec un classeur une fois nettoyé, tu as donc pu testé... Cette mesure est à éliminer dans la version définitive (opérationnelle) : il suffit de supprimer la variable t dans la déclaration, la ligne qui suit Dim... (recueil du temps départ) et les 2 lignes à la fin avant End Sub (temps arrivée et affichage).
Si tu as testé la macro sur un autre classeur sans l'avoir préalablement nettoyé, je ne saurais garantir le résultat...
Si tu tiens à utiliser des tableaux Excel pour tes données à traiter, commence par les mettre en place correctement, façon qu'il n'exèdent pas la taille des données et ne comportent aucun vide...
La macro pourra facilement s'adapter et s'exécuter dans les mêmes conditions :
suppression de la variable n (en déclaration) et de la ligne qui l'initialise (n = ...)
recueil de la plage dans le tableau aa qui devient :
aa = .ListObjects(1).Range.Resize(, 2).Valueet remplacement de n aux deux autres endroits où il apparaît dans le code (initialisation de la boucle de traitement et définition de la plage d'affectation) par UBound(aa).
C'est donc fort simple !
Cordialement.
Ouf ... Je pense que je vais laisser tomber les macros pour le moment et continuer manuellement pcq a moins d'avoir un dictionnaire de code pour macro il y a beaucoup trop d'infos et je suis totalement perdue...
Merci beaucoup quand même d'avoir pris de votre temps pour m'aider je m'y réessayerais p-e plutard quand j'aurais un peu plus de temps
Est-ce que tu ne te sers pas de tes appareils ménagers lorsque tu n'en comprends pas le fonctionnement interne ?
Et travail manuel ou pas, si tu ne commences pas par nettoyer tes classeurs et appliquer quelques règles strictes, tu cours aux catastrophes en cascade...
Cordialement.