Optimiser Macro dans un fichier ayant plus de 50 000 lignes
M@cfly
Messages postés
16
Date d'inscription
Statut
Membre
Dernière intervention
-
pijaku Messages postés 12263 Date d'inscription Statut Modérateur Dernière intervention -
pijaku Messages postés 12263 Date d'inscription Statut Modérateur Dernière intervention -
Bonjour,
J'ai un rapport TXT que je dois reformater dans Excel afin de sortir des statistiques. J'ai donc créer une Macro. Malheureusement lorsque je l'exécute dans un fichier de 50 000 lignes et plus (125 000) c'est excessivement long. Pouvez-vous m'aider à l'accélérer?
Voici :
J'ai un rapport TXT que je dois reformater dans Excel afin de sortir des statistiques. J'ai donc créer une Macro. Malheureusement lorsque je l'exécute dans un fichier de 50 000 lignes et plus (125 000) c'est excessivement long. Pouvez-vous m'aider à l'accélérer?
Voici :
Sub Inventory_postingList() Application.ScreenUpdating = False Columns("A:B").Select Selection.Insert Shift:=x1ToRight Range("A1").FormulaR1C1 = "#" Range("B1").FormulaR1C1 = "ITEM" Dim z As Long Dim y As Long Dim LNG As Long 'LNG = ActiveCell.SpecialCells(xlLastCell).Row + 10 LNG = 106255 y = 2 For z = 2 To LNG If y = LNG Then Exit For End If If (Cells(z, 3).Value = "") Or (Right(Cells(z, 3).Value, 1) = "U") Or (Right(Cells(z, 3).Value, 1) = "u") Or (Cells(z, 8).Value > "0") Then Rows(z & ":" & z).Delete Shift:=xlUp z = z - 1 Else If (Cells(z, 4).Value = "") Then Cells(z, 3).Cut Cells(z, 1).Paste ' ActiveSheet.Paste Cells(z, 7).Cut Cells(z, 2).Paste ' ActiveSheet.Paste ' Rows(z & ":" & z).Select ' With Selection.Interior ' .Pattern = xlSolid ' .PatternColorIndex = xlAutomatic ' .ThemeColor = xlThemeColorDark1 ' .TintAndShade = -0.149998474074526 '.PatternTintAndShade = 0 'End With ElseIf (Cells(z, 1).Value = "") And (Left(Cells(z, 4).Value, 2) <> "DN") Then Rows(z & ":" & z).Delete Shift:=xlUp z = z - 1 ElseIf (Cells(z, 1).Value = "") Then Cells(z - 1, 1).Copy Cells(z, 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False Cells(z - 1, 2).Copy Cells(z, 2).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _ :=False, Transpose:=False End If End If y = y + 1 Next z Application.ScreenUpdating = True Range("A1").Select End Sub
A voir également:
- Optimiser Macro dans un fichier ayant plus de 50 000 lignes
- Fichier bin - Guide
- Optimiser son pc - Accueil - Utilitaires
- Comment réduire la taille d'un fichier - Guide
- Comment ouvrir un fichier epub ? - Guide
- Fichier rar - Guide
10 réponses
Bonjour,
1) Quand on supprime des lignes, il est toujours bien plus rapide de commencer par la dernière :
For z = LNG to 2 Step -1
2) plutôt qu'un paste spécial valeur il est préférable d'utiliser simplement :
rngCible.Value = rngSource.Value
1) Quand on supprime des lignes, il est toujours bien plus rapide de commencer par la dernière :
For z = LNG to 2 Step -1
2) plutôt qu'un paste spécial valeur il est préférable d'utiliser simplement :
rngCible.Value = rngSource.Value
Bonsoir M@cfly,Patrice, bonsoir le forum,
Peut-être comme ça :
Au lieu de travailler directement dans les cellules j'utilise une variable tableau TC avec un accès beaucoup plus rapide. Ça devrait considérablement améliorer la vitesse d'exécution...
À plus,
ThauTheme
Peut-être comme ça :
Sub Inventory_postingList() Dim TC As Variant 'déclare la variable TC (Tableau de Cellules) Dim NL As Long 'déclare la variable NL (Nombre de lignes) Dim I As Long 'déclare la variable I (Incrément de ligne) Dim TL() As Variant 'déclare la variable TL (Tableau de Lignes) Dim J As Long 'déclare la variable J (incrément de lignes) Application.ScreenUpdating = False 'masque les rafraîchissements d'écran Columns("A:B").Insert Shift:=x1ToRight 'insère deux colonnes à gauche Range("A1").FormulaR1C1 = "#" 'écrit "#" en A1 Range("B1").FormulaR1C1 = "ITEM" 'écrit "ITEM" en B1 TC = Range("A1").CurrentRegion 'définit le tableau de cellules TC NL = UBound(TC, 1) 'définit le nombre de lignes du tableau de cellule TC For I = 2 To NL 'boucle sur toutes les lignes I du tableau de cellulles TC (en partant de la seconde) If TC(I, 3) = "" Or UCase(Right(TC(I, 3), 1)) = "U" Or TC(I, 8) > 0 Then 'condition 1 : si l'un des 3 cas ReDim Preserve TL(J) 'redimensionne le tableau de lignes TL TL(J) = I 'stocke dans TL(J) le numéro de ligne à effacer J = J + 1 'incrémente J Else 'sinon (condition 1) If TC(I, 4) = "" Then 'condition 2 : la valeur ligne I colonne 4 de TC est vide TC(I, 1) = TC(I, 3): TC(I, 3) = "" 'récupère en colonne 1 la valeur colonne 3 et efface la valeur colonne 3 TC(I, 2) = TC(I, 7): TC(I, 7) = "" 'récupère en colonne 2 la valeur colonne 7 et efface la valeur colonne 7 'condition 3 : si la valeur ligne I colonne 1 est vide et les deux premiers 'caractères de la valeur ligne I colonne 'sont différents de "DN" ElseIf TC(I, 1) = "" And Left(TC(I, 4), 2) <> "DN" Then ReDim Preserve TL(J) 'redimensionne le tableau de lignes TL TL(J) = I 'stocke dans TL(J) le numéro de ligne à effacer J = J + 1 'incrémente J ElseIf TC(I, 1).Value = "" Then 'condition 4 : si la valeur ligne I colonne 1 est vide TC(I, 1) = TC(I - 1, 1) 'récupère en colonne 1 la valeur de la ligne au-dessus TC(I, 2) = TC(I - 1, 2) 'récupère en colonne 2 la valeur de la ligne au-dessus End If 'fin des condition 2, 3 et 4 End If 'fin de la condition 1 Next I 'prochaine ligne du tableau de cellues TC Range("A1").Resize(UBound(TC, 1), UBound(TC, 2)) = TC 'renvoie dans A1 le tableau TC moditfié For I = UBound(TL) To LBound(TL) Step -1 'boucle inversée du dernièr élément tu tableau de ligne Tl au premier Rows(TL(I)).Delete 'supprime la ligne TL(I) Next I 'prochaine élément de la boucle Application.ScreenUpdating = True 'affiche les rafraîchissements d'écran End Sub
Au lieu de travailler directement dans les cellules j'utilise une variable tableau TC avec un accès beaucoup plus rapide. Ça devrait considérablement améliorer la vitesse d'exécution...
À plus,
ThauTheme
Bonjour à tous, bonjour le forum,
Le code corrigé ci-dessous. En effet si le tableau de lignes TL était vide, ça provoquait une erreur. La condition If J > 0 permet d'y remedier.
Le code corrigé ci-dessous. En effet si le tableau de lignes TL était vide, ça provoquait une erreur. La condition If J > 0 permet d'y remedier.
Sub Inventory_postingList() Dim TC As Variant 'déclare la variable TC (Tableau de Cellules) Dim NL As Long 'déclare la variable NL (Nombre de lignes) Dim I As Long 'déclare la variable I (Incrément de ligne) Dim TL() As Variant 'déclare la variable TL (Tableau de Lignes) Dim J As Long 'déclare la variable J (incrément de lignes) Application.ScreenUpdating = False 'masque les rafraîchissements d'écran Columns("A:B").Insert Shift:=x1ToRight 'insère deux colonnes à gauche Range("A1").FormulaR1C1 = "#" 'écrit "#" en A1 Range("B1").FormulaR1C1 = "ITEM" 'écrit "ITEM" en B1 TC = Range("A1").CurrentRegion 'définit le tableau de cellules TC NL = UBound(TC, 1) 'définit le nombre de lignes du tableau de cellule TC For I = 2 To NL 'boucle sur toutes les lignes I du tableau de cellulles TC (en partant de la seconde) If TC(I, 3) = "" Or UCase(Right(TC(I, 3), 1)) = "U" Or TC(I, 8) > 0 Then 'condition 1 : si l'un des 3 cas ReDim Preserve TL(J) 'redimensionne le tableau de lignes TL TL(J) = I 'stocke dans TL(J) le numéro de ligne à effacer J = J + 1 'incrémente J Else 'sinon (condition 1) If TC(I, 4) = "" Then 'condition 2 : la valeur ligne I colonne 4 de TC est vide TC(I, 1) = TC(I, 3): TC(I, 3) = "" 'récupère en colonne 1 la valeur colonne 3 et efface la valeur colonne 3 TC(I, 2) = TC(I, 7): TC(I, 7) = "" 'récupère en colonne 2 la valeur colonne 7 et efface la valeur colonne 7 'condition 3 : si la valeur ligne I colonne 1 est vide et les deux premiers 'caractères de la valeur ligne I colonne 'sont différents de "DN" ElseIf TC(I, 1) = "" And Left(TC(I, 4), 2) <> "DN" Then ReDim Preserve TL(J) 'redimensionne le tableau de lignes TL TL(J) = I 'stocke dans TL(J) le numéro de ligne à effacer J = J + 1 'incrémente J ElseIf TC(I, 1).Value = "" Then 'condition 4 : si la valeur ligne I colonne 1 est vide TC(I, 1) = TC(I - 1, 1) 'récupère en colonne 1 la valeur de la ligne au-dessus TC(I, 2) = TC(I - 1, 2) 'récupère en colonne 2 la valeur de la ligne au-dessus End If 'fin des condition 2, 3 et 4 End If 'fin de la condition 1 Next I 'prochaine ligne du tableau de cellues TC Range("A1").Resize(UBound(TC, 1), UBound(TC, 2)) = TC 'renvoie dans A1 le tableau TC moditfié If J > 0 Then 'condition : si il existe au moins une données dans le tabelau de lignes TL For I = UBound(TL) To LBound(TL) Step -1 'boucle inversée du dernièr élément tu tableau de ligne Tl au premier Rows(TL(I)).Delete 'supprime la ligne TL(I) Next I 'prochaine élément de la boucle End If 'fin de la condition Application.ScreenUpdating = True 'affiche les rafraîchissements d'écran End Sub
re,
Je pense que ton tableau ne commence pas en A1 ou alors il contient des lignes entières (ou des colonnes entières) vide séparant les données. C'est pour cela que le tableau TC ne prend pas en compte toutes les données et du coup, le nombre de lignes NL (du tableau TC) reste à 2...
Regarde avec https://www.cjoint.com/ mais surtout envoie un fichier zippé sinon il est inutilisable...
Je pense que ton tableau ne commence pas en A1 ou alors il contient des lignes entières (ou des colonnes entières) vide séparant les données. C'est pour cela que le tableau TC ne prend pas en compte toutes les données et du coup, le nombre de lignes NL (du tableau TC) reste à 2...
Regarde avec https://www.cjoint.com/ mais surtout envoie un fichier zippé sinon il est inutilisable...
Bonjour M@cfly, Patrice, ThauTheme,
Tu dis : J'ai un rapport TXT que je dois reformater dans Excel afin de sortir des statistiques.
Et si, au lieu de créer une macro fonctionnant à postériori, tu te faisais, en même temps, une macro d'importation de ton fichier txt?
Pour l'instant, pour créer ta feuille de 125 000 lignes, je supposes que tu fais un copié-collé. On pourrait très bien importer le contenu de ton fichier txt dans une variable tableau et la traiter un peu à la manière de ThauTheme.
Tu dis...
Tu dis : J'ai un rapport TXT que je dois reformater dans Excel afin de sortir des statistiques.
Et si, au lieu de créer une macro fonctionnant à postériori, tu te faisais, en même temps, une macro d'importation de ton fichier txt?
Pour l'instant, pour créer ta feuille de 125 000 lignes, je supposes que tu fais un copié-collé. On pourrait très bien importer le contenu de ton fichier txt dans une variable tableau et la traiter un peu à la manière de ThauTheme.
Tu dis...
Bonjour,
ça ne dérangera personne de t'aider, c'est le but du forum.
Par contre, il faudrait que tu nous précise réellement qu'elles sont tes conditions.
En partant de ton fichier txt, comment fais tu, manuellement pour obtenir ton résultat.
Tu copie ton fichier txt, le colle à partir de C2 etc...
Toutes les étapes doivent être décrites.
ça ne dérangera personne de t'aider, c'est le but du forum.
Par contre, il faudrait que tu nous précise réellement qu'elles sont tes conditions.
En partant de ton fichier txt, comment fais tu, manuellement pour obtenir ton résultat.
Tu copie ton fichier txt, le colle à partir de C2 etc...
Toutes les étapes doivent être décrites.
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Bonjour,
Tout d'abord, une petite difficulté supplémentaire se présente à moi, ou plutôt une incompréhension :
La colonne K (Balance) de ton fichier RESULTAT_maMacro.xlsx contient des valeurs numériques à 4 chiffres (exemple ligne 101 : 2058) alors que dans le fichier DONNEES.txt, ces valeurs sont décimales : 2,058.
Que doit-on faire?
Ensuite, pour te parler performances, la macro sur laquelle je travaille, traite plus de 80 000 lignes initiales (un peu plus de 51 000 à l'arrivée) en moins de 7 secondes, y compris l'importation du fichier txt que tu n'auras plus à faire manuellement.
Mais bon, à la différence de ThauTheme (que je salue), mon pc est réellement performant (je suis au taf ;-)).
Tout d'abord, une petite difficulté supplémentaire se présente à moi, ou plutôt une incompréhension :
La colonne K (Balance) de ton fichier RESULTAT_maMacro.xlsx contient des valeurs numériques à 4 chiffres (exemple ligne 101 : 2058) alors que dans le fichier DONNEES.txt, ces valeurs sont décimales : 2,058.
Que doit-on faire?
Ensuite, pour te parler performances, la macro sur laquelle je travaille, traite plus de 80 000 lignes initiales (un peu plus de 51 000 à l'arrivée) en moins de 7 secondes, y compris l'importation du fichier txt que tu n'auras plus à faire manuellement.
Mais bon, à la différence de ThauTheme (que je salue), mon pc est réellement performant (je suis au taf ;-)).
Super pour la vitesse!!!
La colonne (Balance) et (Qty) doivent être de format nombre. Dans le fichier TXT, il y a un séparateur de millier "," et un séparateur de décimal ".".
Important :
Lors de l'importation du fichier TXT la première colone doit être en format texte car il y a des codes de produit qui commence par 0 (ex : 0000149)
Une fois que j'obtiens le tableau final, je fais d'autres manipulations. Est-ce possible de les automatiser dans la macro?
soit :
- Colone C "Posting Date" je le mets en format de date
- j'ajoute une colone pour ajouter le # de la semaine.
Merci encore
La colonne (Balance) et (Qty) doivent être de format nombre. Dans le fichier TXT, il y a un séparateur de millier "," et un séparateur de décimal ".".
Important :
Lors de l'importation du fichier TXT la première colone doit être en format texte car il y a des codes de produit qui commence par 0 (ex : 0000149)
Une fois que j'obtiens le tableau final, je fais d'autres manipulations. Est-ce possible de les automatiser dans la macro?
soit :
- Colone C "Posting Date" je le mets en format de date
- j'ajoute une colone pour ajouter le # de la semaine.
Merci encore
Bon...
La différence tiens dans le formatage préalable de la colonne K. Si on veut 2,058 en K101, il faut la formater en texte, pour obtenir 2058 il faut formater en standard. J'ai mis les deux dans la macro, il suffit de commenter (ou dé-commenter) la ligne correspondante.
A adapter :
En tout début de code, deux constantes sont à adapter :
A vérifier : la variable delim. Selon la construction du fichier txt. Celui proposé dans les sources ici utilise la tabulation (Chr(9)) comme délimiteur. Changer donc cette variable si on utilise le point-virgule ou autre...
Performances : fichier txt de 82 399 lignes restitué en 51 921 lignes. Durée : 7,55 secondes.
Configuration pc : W7 + Excel 2010 en 32 bits
Processeur Celeron 1,80 Ghz
RAM : 4 Go
Le code :
Dans l'attente...
La différence tiens dans le formatage préalable de la colonne K. Si on veut 2,058 en K101, il faut la formater en texte, pour obtenir 2058 il faut formater en standard. J'ai mis les deux dans la macro, il suffit de commenter (ou dé-commenter) la ligne correspondante.
A adapter :
En tout début de code, deux constantes sont à adapter :
- Source => le chemin vers le fichier txt (complet, avec le répertoire + le nom du fichier + l'extension)
- Feuille => le nom de la feuille ou restituer les données.
A vérifier : la variable delim. Selon la construction du fichier txt. Celui proposé dans les sources ici utilise la tabulation (Chr(9)) comme délimiteur. Changer donc cette variable si on utilise le point-virgule ou autre...
Performances : fichier txt de 82 399 lignes restitué en 51 921 lignes. Durée : 7,55 secondes.
Configuration pc : W7 + Excel 2010 en 32 bits
Processeur Celeron 1,80 Ghz
RAM : 4 Go
Le code :
Option Explicit '========================================================================= Constantes A ADAPTER Private Const Source As String = "C:\Users\....\Desktop\DONNEES_2.txt" 'chemin d'accès complet au fichier txt Private Const Feuille As String = "Feuil3" 'nom de la feuille de restitution des données 'constante pour l'entête de la feuille de restitution Private Const Entete As String = "#;ITEM;Posting Date;Document;Whse;G/L Acct/BP Code;G/L Acct/BP Name;Qty;Inventory UoM;Price after Disc.;Balance" 'Variable utilisée dans la Sub et dans la Function Private delim As String Sub Macfly() Dim Tb() As String, Tb_Out() As Variant, Chaine As String, num As Long, i As Long '========================================================================= Initialisation des variables delim = Chr(9) 'délimiteur du fichier txt Chr(9) = Tabulation For i = 1 To 9 Chaine = Chaine & delim 'Chaine pour éviter d'extraire les lignes vides du fichier txt Next i num = FreeFile 'Numéro libre d'ouverture d'un fichier '========================================================================= IMPORT du fixhier txt dans variable tableau (Tb) Open Source For Input As #num i = -1 While Not EOF(1) i = i + 1 ReDim Preserve Tb(i) Line Input #1, Tb(i) If Tb(i) = Chaine Then i = i - 1 'En évitant les lignes vides Wend Close #num '========================================================================= Organisation des données de la variable tableau Tb Tb_Out = Organise_Datas(Tb()) '========================================================================= Restitution des données dans la feuille Application.ScreenUpdating = False 'désactive le rafraichissement d'écran With Sheets(Feuille) .Columns("A:K").ClearContents 'vide le contenu déjà présent .Columns("A:I").NumberFormat = "@" 'formate les colonnes A:I en texte '--------------------------------------------------------------------- Cellule K101 (formatage colonne K) A ADAPTER '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General" 'formate la colonne K en standard ===> Affichage 2058 For i = 1 To 11 .Cells(1, i) = Split(Entete, ";")(i - 1) 'Ecris l'entête de la feuille Next .Cells(2, 1).Resize(UBound(Tb_Out, 1), UBound(Tb_Out, 2)) = Tb_Out 'Saisie des données .Select End With Application.ScreenUpdating = True 'Active le rafraichissement d'écran End Sub Private Function Organise_Datas(Tb() As String) As Variant() Dim TbTemp() As Variant, i As Long, Cpt As Long, j As Byte 'on redimensionne le tableau TbTemp pour : '- transposer les données de Tb '- ajouter les deux premières colonnes ReDim Preserve TbTemp(1 To UBound(Tb), 1 To 11) 'Boucle sur toutes les lignes extraites For i = 1 To UBound(Tb) 'utilisation de Split avec le délimiteur pour "isoler" chacune des données 'tests généraux sur : '- 1ère colonne du fichier txt (Posting Date <> "" ou <> u) '- 6ème colonne du fichier txt (Qty <= 0) If Split(Tb(i), delim)(0) <> "" Or UCase(Right(Split(Tb(i), delim)(0), 1)) <> "U" Or Split(Tb(i), delim)(5) <= 0 Then Cpt = Cpt + 1 'test si Document vide If Split(Tb(i), delim)(1) = "" Then TbTemp(Cpt, 1) = CStr(Split(Tb(i), delim)(0)) TbTemp(Cpt, 2) = CStr(Split(Tb(i), delim)(4)) On Error Resume Next 'la dernière ligne du fichier txt, n'a pas 9 colonnes TbTemp(Cpt, 11) = CStr(Split(Tb(i), delim)(8)) On Error GoTo 0 'test si Document commence par DN ElseIf Left(Split(Tb(i), delim)(1), 2) = "DN" Then TbTemp(Cpt, 1) = CStr(TbTemp(Cpt - 1, 1)) TbTemp(Cpt, 2) = CStr(TbTemp(Cpt - 1, 2)) For j = 0 To UBound(Split(Tb(i), delim)) - 1 TbTemp(Cpt, j + 3) = CStr(Split(Tb(i), delim)(j)) Next j End If End If 'évite les lignes vides If TbTemp(Cpt, 1) = "" Then Cpt = Cpt - 1 Next i Organise_Datas = TbTemp End Function
Dans l'attente...
Mode d'emploi complet :
EDIT : Ci-joint mon fichier de travail
N'oublie pas d'adapter ce qui doit l'être...
- Ouvre un nouveau classeur Excel
- Alt + F11
- Insertion/Module
- Copie-colle le code dans son intégralité
- saisir les modifications à apporter
- ferme l'éditeur VBA
- Alt + F8, choix Macfly
- Exécuter
EDIT : Ci-joint mon fichier de travail
N'oublie pas d'adapter ce qui doit l'être...
Re-
Voici trois des méthodes (il en existe d'autres) adaptées à ton problème.
Ne pas oublier d'adapter ce qui doit l'être : chemin d'accès + nom du fichier.
1- Méthode 1 => Lecture séquentielle du fichier txt
C'est celle décrite plus haut que tu ne parviens pas à faire fonctionner.
Je l'ai légèrement modifiée pour être sur de ne rien oublier.
2- Méthode 2 => Utilisation du FSO (FileSystemObject) pour la lecture du fichier txt
Si cela ne passe pas, retenter en cochant la référence "Microsoft Scripting Runtime". Pour info, chez moi ça passe sans...
(pour cocher une référence : sous VBE : OUtils/Références, chercher et cocher la référence demandée)
3- Méthode 3 => Utilisation du Jet de Microsoft pour l'import du fichier txt
!!!! Nécessite de cocher la référence Microsoft ActiveX DataObject 2.0
Cette méthode, curieusement, ne rapatrie pas toutes les données dans leur intégralité. Elle en tronque certaines et en oublie d'autres, je ne sais pas pourquoi. C'est pour cela que je la places ici tout de même; si un collègue arrivait à m'expliquer pourquoi...
En terme de performances, la 1 et la 2 sont identiques. La 3 est un peu plus lente (10 sec pour 100 000 lignes).
Vous trouverez, ci-joint, mon fichier de travail.
Dans la feuille Feuil1, des tests de comparaison entre les méthodes.
Voici trois des méthodes (il en existe d'autres) adaptées à ton problème.
Ne pas oublier d'adapter ce qui doit l'être : chemin d'accès + nom du fichier.
1- Méthode 1 => Lecture séquentielle du fichier txt
C'est celle décrite plus haut que tu ne parviens pas à faire fonctionner.
Je l'ai légèrement modifiée pour être sur de ne rien oublier.
Option Explicit Private Const SOURCE As String = "C:\Users\pijaku\Desktop\DONNEES_2.txt" Private Const ENTETE As String = "#;ITEM;Posting Date;Document;Whse;G/L Acct/BP Code;G/L Acct/BP Name;Qty;Inventory UoM;Price after Disc.;Balance" Private delim As String Private Feuille As String Public Sub Macfly_SEQ() Dim Tb() As String, Tb_Out() As Variant, Chaine As String, num As Long, i As Long Dim t As Double t = Timer delim = Chr(9) Feuille = "Feuil2" For i = 1 To 9 Chaine = Chaine & delim Next i num = FreeFile Open SOURCE For Input As #num i = -1 While Not EOF(1) i = i + 1 ReDim Preserve Tb(i) Line Input #1, Tb(i) If Tb(i) = Chaine Then i = i - 1 Wend Close #num Tb_Out = Tri_Donnees_SEQ(Tb()) Application.ScreenUpdating = False With Sheets(Feuille) .Columns("A:K").ClearContents .Columns("A:I").NumberFormat = "@" '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General" For i = 1 To 11 .Cells(1, i) = Split(ENTETE, ";")(i - 1) Next .Cells(2, 1).Resize(UBound(Tb_Out, 1), UBound(Tb_Out, 2)) = Tb_Out .Select End With Application.ScreenUpdating = True MsgBox Timer - t End Sub Private Function Tri_Donnees_SEQ(Tb() As String) As Variant() Dim TbTemp() As Variant, i As Long, Cpt As Long, j As Byte ReDim Preserve TbTemp(1 To UBound(Tb), 1 To 11) For i = 1 To UBound(Tb) If Split(Tb(i), delim)(0) <> "" Or UCase(Right(Split(Tb(i), delim)(0), 1)) <> "U" Or Split(Tb(i), delim)(5) <= 0 Then Cpt = Cpt + 1 If Split(Tb(i), delim)(1) = "" Then TbTemp(Cpt, 1) = CStr(Split(Tb(i), delim)(0)) TbTemp(Cpt, 2) = CStr(Split(Tb(i), delim)(4)) For j = 3 To UBound(Split(Tb(i), delim)) - 1 If j <> 4 Then TbTemp(Cpt, j + 3) = CStr(Split(Tb(i), delim)(j)) Next j ElseIf Left(Split(Tb(i), delim)(1), 2) = "DN" Then TbTemp(Cpt, 1) = CStr(TbTemp(Cpt - 1, 1)) TbTemp(Cpt, 2) = CStr(TbTemp(Cpt - 1, 2)) For j = 0 To UBound(Split(Tb(i), delim)) - 1 TbTemp(Cpt, j + 3) = CStr(Split(Tb(i), delim)(j)) Next j End If End If If TbTemp(Cpt, 1) = "" Then Cpt = Cpt - 1 Next i Tri_Donnees_SEQ = TbTemp End Function
2- Méthode 2 => Utilisation du FSO (FileSystemObject) pour la lecture du fichier txt
Si cela ne passe pas, retenter en cochant la référence "Microsoft Scripting Runtime". Pour info, chez moi ça passe sans...
(pour cocher une référence : sous VBE : OUtils/Références, chercher et cocher la référence demandée)
Option Explicit Private Const SOURCE As String = "C:\Users\pijaku\Desktop\DONNEES_2.txt" Private Const ENTETE As String = "#;ITEM;Posting Date;Document;Whse;G/L Acct/BP Code;G/L Acct/BP Name;Qty;Inventory UoM;Price after Disc.;Balance" Private delim As String Private Feuille As String Public Sub MacFly_FSO() Dim oFso As Variant, txtFic As Variant, Tb As Variant, TbTemp() As Variant Dim i As Long, j As Long, ligEnt As Byte Dim t As Double t = Timer delim = Chr(9) Feuille = "Feuil3" Set oFso = CreateObject("Scripting.FileSystemObject") Set txtFic = oFso.OpenTextFile(SOURCE) Do While Not txtFic.AtEndOfStream i = i + 1 ReDim Preserve TbTemp(i) TbTemp(i) = Split(txtFic.ReadLine, delim) If j < UBound(TbTemp(i), 1) Then j = UBound(TbTemp(i), 1) Loop txtFic.Close ReDim Tb(1 To i, 1 To j + 1) As Variant For i = 1 To i For j = 0 To UBound(TbTemp(i), 1) Tb(i, j + 1) = TbTemp(i)(j) Next j Next i Tb = Tri_Donnees_FSO(Tb) Application.ScreenUpdating = False With Sheets(Feuille) .Columns("A:K").ClearContents .Columns("A:I").NumberFormat = "@" '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General" For ligEnt = 1 To 11 .Cells(1, ligEnt) = Split(ENTETE, ";")(ligEnt - 1) Next .Cells(2, 1).Resize(UBound(Tb, 1), UBound(Tb, 2)) = Tb .Select End With Application.ScreenUpdating = True MsgBox Timer - t End Sub Private Function Tri_Donnees_FSO(Tb As Variant) As Variant() Dim TbTemp() As Variant, i As Long, Cpt As Long, j As Byte ReDim Preserve TbTemp(1 To UBound(Tb, 1), 1 To UBound(Tb, 2) + 2) For i = 1 To UBound(Tb, 1) If Tb(i, 1) <> "" Or UCase(Right(Tb(i, 1), 1)) <> "U" Or Tb(i, 6) <= 0 Then Cpt = Cpt + 1 If Tb(i, 2) = "" Then TbTemp(Cpt, 1) = CStr(Tb(i, 1)) TbTemp(Cpt, 2) = CStr(Tb(i, 5)) For j = 3 To UBound(Tb, 2) - 1 If j <> 5 Then TbTemp(Cpt, j + 2) = CStr(Tb(i, j)) Next j ElseIf Left(Tb(i, 2), 2) = "DN" Then TbTemp(Cpt, 1) = CStr(TbTemp(Cpt - 1, 1)) TbTemp(Cpt, 2) = CStr(TbTemp(Cpt - 1, 2)) For j = 1 To UBound(Tb, 2) - 1 TbTemp(Cpt, j + 2) = CStr(Tb(i, j)) Next j End If End If If TbTemp(Cpt, 1) = "" Then Cpt = Cpt - 1 Next i Tri_Donnees_FSO = TbTemp End Function
3- Méthode 3 => Utilisation du Jet de Microsoft pour l'import du fichier txt
!!!! Nécessite de cocher la référence Microsoft ActiveX DataObject 2.0
Cette méthode, curieusement, ne rapatrie pas toutes les données dans leur intégralité. Elle en tronque certaines et en oublie d'autres, je ne sais pas pourquoi. C'est pour cela que je la places ici tout de même; si un collègue arrivait à m'expliquer pourquoi...
Option Explicit Private Const ENTETE As String = "#;ITEM;Posting Date;Document;Whse;G/L Acct/BP Code;G/L Acct/BP Name;Qty;Inventory UoM;Price after Disc.;Balance" Private delim As String Private Feuille As String Sub MacFly_JET() Const REPERTOIRE As String = "C:\Users\pijaku\Desktop" Const FICHIER As String = "DONNEES_2.txt" Dim strReq As String Dim Conn As ADODB.Connection, Enrg As ADODB.Recordset Dim Extract As Variant, Tb() As String, Temp As Variant, i As Long, j As Integer Dim t As Double t = Timer strReq = "SELECT * FROM " & FICHIER Feuille = "Feuil4" delim = Chr(9) Set Conn = New ADODB.Connection On Error Resume Next Conn.Open "Driver={Microsoft Text Driver (*.txt; *.csv)};" & "Dbq=" & REPERTOIRE & ";" & "Extensions=txt;" On Error GoTo 0 If Conn.State <> 1 Then Exit Sub Set Enrg = New ADODB.Recordset On Error Resume Next Enrg.Open strReq, Conn, adOpenForwardOnly, adLockReadOnly, adCmdText On Error GoTo 0 If Enrg.State <> 1 Then Conn.Close Set Conn = Nothing Exit Sub End If Extract = Enrg.GetRows ReDim Preserve Tb(0 To UBound(Extract, 2), 0 To 9) For i = 0 To UBound(Extract, 2) If Extract(0, i) & Extract(1, i) <> "" Then For j = 0 To UBound(Split(Extract(0, i) & Extract(1, i), delim)) Tb(i, j) = Split(Extract(0, i) & Extract(1, i), delim)(j) Next j End If Next i Enrg.Close Conn.Close Set Enrg = Nothing Set Conn = Nothing Temp = Tri_Donnees_JET(Tb) Application.ScreenUpdating = False With Sheets(Feuille) .Columns("A:K").ClearContents .Columns("A:I").NumberFormat = "@" '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General" For i = 1 To 11 .Cells(1, i) = Split(ENTETE, ";")(i - 1) Next .Cells(2, 1).Resize(UBound(Temp, 1), UBound(Temp, 2)) = Temp .Select End With Application.ScreenUpdating = True MsgBox Timer - t End Sub Private Function Tri_Donnees_JET(Tb As Variant) As Variant() Dim TbTemp() As Variant, i As Long, Cpt As Long, j As Byte ReDim Preserve TbTemp(1 To UBound(Tb, 1), 1 To UBound(Tb, 2) + 2) For i = 0 To UBound(Tb, 1) If Tb(i, 0) <> "" Or UCase(Right(Tb(i, 0), 1)) <> "U" Or Tb(i, 5) <= 0 Then Cpt = Cpt + 1 If Tb(i, 1) = "" Then If Tb(i, 0) <> "" And Tb(i, 4) <> "" Then TbTemp(Cpt, 1) = CStr(Tb(i, 0)) TbTemp(Cpt, 2) = CStr(Tb(i, 4)) For j = 3 To UBound(Tb, 2) - 1 If j <> 4 Then TbTemp(Cpt, j + 3) = CStr(Tb(i, j)) Next j End If ElseIf Left(Tb(i, 1), 2) = "DN" Then TbTemp(Cpt, 1) = CStr(TbTemp(Cpt - 1, 1)) TbTemp(Cpt, 2) = CStr(TbTemp(Cpt - 1, 2)) For j = 1 To UBound(Tb, 2) TbTemp(Cpt, j + 2) = CStr(Tb(i, j - 1)) Next j End If End If If TbTemp(Cpt, 1) = "" Or TbTemp(Cpt, 2) = "" Then Cpt = Cpt - 1 Next i Tri_Donnees_JET = TbTemp End Function
En terme de performances, la 1 et la 2 sont identiques. La 3 est un peu plus lente (10 sec pour 100 000 lignes).
Vous trouverez, ci-joint, mon fichier de travail.
Dans la feuille Feuil1, des tests de comparaison entre les méthodes.
Bonjour le fil, bonjour le forum,
Merci Pijaku d'avoir pris le relai car je me suis absenté quelques jour et je suis un peu larguer là... C'est toujours un grand plaisir de te croiser au fil des fils...
Merci Pijaku d'avoir pris le relai car je me suis absenté quelques jour et je suis un peu larguer là... C'est toujours un grand plaisir de te croiser au fil des fils...
Bonjour,
Désolé du délais... Grosse journée vendredi dernier.
Je viens d'essayer les propositions ci hauts et ça ne fonctionne pas. Le fichier de s'ouvre pas. Serait-ce une question de sécurité?
Pour la proposition 1 j'ai le même message de chemin ne fonctionne pas
Proposition 2 :
Argument ou appel de procédure incorrect à la ligne 17.
Que faire?
Désolé du délais... Grosse journée vendredi dernier.
Je viens d'essayer les propositions ci hauts et ça ne fonctionne pas. Le fichier de s'ouvre pas. Serait-ce une question de sécurité?
Pour la proposition 1 j'ai le même message de chemin ne fonctionne pas
Proposition 2 :
Argument ou appel de procédure incorrect à la ligne 17.
Que faire?
Bonjour,
Oh comme ta réponse manque cruellement de précisions!
Le fichier de s'ouvre pas. Quel fichier?
Ton fichier txt?
==> Normal, on ne l'ouvre pas.
Mon fichier transmis précédemment?
==> Pas normal, il s'agit d'un simple fichier xlsm...
Serait-ce une question de sécurité?
Si tu parles de ton fichier txt, oui il peut y avoir un problème de sécurité.
Si tu parles de mon fichier, il faut regarder le niveau de sécurité des macros... et accepter les macros.
Pour les 2 propositions, tu as un souci avec le chemin d'accès au fichier txt. On va essayer de contourner ce problème par macro, en utilisant une boite de dialogue de sélection de fichier plutôt que de l'inscrire en dur.
Essaye ces deux possibilités (chacune dans son propre Module standard) :
Méthode 1 :
Méthode 2
Oh comme ta réponse manque cruellement de précisions!
Le fichier de s'ouvre pas. Quel fichier?
Ton fichier txt?
==> Normal, on ne l'ouvre pas.
Mon fichier transmis précédemment?
==> Pas normal, il s'agit d'un simple fichier xlsm...
Serait-ce une question de sécurité?
Si tu parles de ton fichier txt, oui il peut y avoir un problème de sécurité.
Si tu parles de mon fichier, il faut regarder le niveau de sécurité des macros... et accepter les macros.
Pour les 2 propositions, tu as un souci avec le chemin d'accès au fichier txt. On va essayer de contourner ce problème par macro, en utilisant une boite de dialogue de sélection de fichier plutôt que de l'inscrire en dur.
Essaye ces deux possibilités (chacune dans son propre Module standard) :
Méthode 1 :
Option Explicit Private Const ENTETE As String = "#;ITEM;Posting Date;Document;Whse;G/L Acct/BP Code;G/L Acct/BP Name;Qty;Inventory UoM;Price after Disc.;Balance" Private delim As String Private Feuille As String '===================================================== 'Méthode 1 => Lecture séquentielle du fichier txt Public Sub Macfly_SEQ() Dim Tb() As String, Tb_Out() As Variant, Chaine As String, NomFic As String, num As Long, i As Long Dim t As Double t = Timer delim = Chr(9) Feuille = "Feuil2" For i = 1 To 9 Chaine = Chaine & delim Next i num = FreeFile NomFic = Source Open NomFic For Input As #num i = -1 While Not EOF(1) i = i + 1 ReDim Preserve Tb(i) Line Input #1, Tb(i) If Tb(i) = Chaine Then i = i - 1 Wend Close #num Tb_Out = Tri_Donnees_SEQ(Tb()) Application.ScreenUpdating = False With Sheets(Feuille) .Columns("A:K").ClearContents .Columns("A:I").NumberFormat = "@" '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General" For i = 1 To 11 .Cells(1, i) = Split(ENTETE, ";")(i - 1) Next .Cells(2, 1).Resize(UBound(Tb_Out, 1), UBound(Tb_Out, 2)) = Tb_Out .Select End With Application.ScreenUpdating = True MsgBox Timer - t End Sub Private Function Tri_Donnees_SEQ(Tb() As String) As Variant() Dim TbTemp() As Variant, i As Long, Cpt As Long, j As Byte ReDim Preserve TbTemp(1 To UBound(Tb), 1 To 11) For i = 1 To UBound(Tb) If Split(Tb(i), delim)(0) <> "" Or UCase(Right(Split(Tb(i), delim)(0), 1)) <> "U" Or Split(Tb(i), delim)(5) <= 0 Then Cpt = Cpt + 1 If Split(Tb(i), delim)(1) = "" Then TbTemp(Cpt, 1) = CStr(Split(Tb(i), delim)(0)) TbTemp(Cpt, 2) = CStr(Split(Tb(i), delim)(4)) For j = 3 To UBound(Split(Tb(i), delim)) - 1 If j <> 4 Then TbTemp(Cpt, j + 3) = CStr(Split(Tb(i), delim)(j)) Next j ElseIf Left(Split(Tb(i), delim)(1), 2) = "DN" Then TbTemp(Cpt, 1) = CStr(TbTemp(Cpt - 1, 1)) TbTemp(Cpt, 2) = CStr(TbTemp(Cpt - 1, 2)) For j = 0 To UBound(Split(Tb(i), delim)) - 1 TbTemp(Cpt, j + 3) = CStr(Split(Tb(i), delim)(j)) Next j End If End If If TbTemp(Cpt, 1) = "" Then Cpt = Cpt - 1 Next i Tri_Donnees_SEQ = TbTemp End Function Private Function Source() As String Source = Application.GetOpenFilename End Function
Méthode 2
Option Explicit Private Const ENTETE As String = "#;ITEM;Posting Date;Document;Whse;G/L Acct/BP Code;G/L Acct/BP Name;Qty;Inventory UoM;Price after Disc.;Balance" Private delim As String Private Feuille As String '===================================================== 'Méthode 2 => Utilisation du FSO (FileSystemObject) pour la lecture du fichier txt Public Sub MacFly_FSO() Dim oFso As Variant, txtFic As Variant, Tb As Variant, TbTemp() As Variant Dim i As Long, j As Long, ligEnt As Byte, NomFic As String Dim t As Double t = Timer delim = Chr(9) Feuille = "Feuil3" NomFic = Source Set oFso = CreateObject("Scripting.FileSystemObject") Set txtFic = oFso.OpenTextFile(NomFic) Do While Not txtFic.AtEndOfStream i = i + 1 ReDim Preserve TbTemp(i) TbTemp(i) = Split(txtFic.ReadLine, delim) If j < UBound(TbTemp(i), 1) Then j = UBound(TbTemp(i), 1) Loop txtFic.Close ReDim Tb(1 To i, 1 To j + 1) As Variant For i = 1 To i For j = 0 To UBound(TbTemp(i), 1) Tb(i, j + 1) = TbTemp(i)(j) Next j Next i Tb = Tri_Donnees_FSO(Tb) Application.ScreenUpdating = False With Sheets(Feuille) .Columns("A:K").ClearContents .Columns("A:I").NumberFormat = "@" '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General" For ligEnt = 1 To 11 .Cells(1, ligEnt) = Split(ENTETE, ";")(ligEnt - 1) Next .Cells(2, 1).Resize(UBound(Tb, 1), UBound(Tb, 2)) = Tb .Select End With Application.ScreenUpdating = True MsgBox Timer - t End Sub Private Function Tri_Donnees_FSO(Tb As Variant) As Variant() Dim TbTemp() As Variant, i As Long, Cpt As Long, j As Byte ReDim Preserve TbTemp(1 To UBound(Tb, 1), 1 To UBound(Tb, 2) + 2) For i = 1 To UBound(Tb, 1) If Tb(i, 1) <> "" Or UCase(Right(Tb(i, 1), 1)) <> "U" Or Tb(i, 6) <= 0 Then Cpt = Cpt + 1 If Tb(i, 2) = "" Then TbTemp(Cpt, 1) = CStr(Tb(i, 1)) TbTemp(Cpt, 2) = CStr(Tb(i, 5)) For j = 3 To UBound(Tb, 2) - 1 If j <> 5 Then TbTemp(Cpt, j + 2) = CStr(Tb(i, j)) Next j ElseIf Left(Tb(i, 2), 2) = "DN" Then TbTemp(Cpt, 1) = CStr(TbTemp(Cpt - 1, 1)) TbTemp(Cpt, 2) = CStr(TbTemp(Cpt - 1, 2)) For j = 1 To UBound(Tb, 2) - 1 TbTemp(Cpt, j + 2) = CStr(Tb(i, j)) Next j End If End If If TbTemp(Cpt, 1) = "" Then Cpt = Cpt - 1 Next i Tri_Donnees_FSO = TbTemp End Function Private Function Source() As String Source = Application.GetOpenFilename End Function
Bonjour Pijaku,
Désolé d'avoir manqué de précision. Par contre, Tu sembles m'avoir compris car ta méthode 1 fonctionne me donne un résultat parfait. Un ajustement si possible :
Est-ce que dans le résultat final, il serait possible que la Colonne H soit de format nombre?
Merci j'apprécie grandement ton dévouement.
Désolé d'avoir manqué de précision. Par contre, Tu sembles m'avoir compris car ta méthode 1 fonctionne me donne un résultat parfait. Un ajustement si possible :
Est-ce que dans le résultat final, il serait possible que la Colonne H soit de format nombre?
Merci j'apprécie grandement ton dévouement.
Pas de souci.
Pour le format nombre, il te suffit de remplacer :
par :
Peux tu me faire un retour également sur la solution 2. Est ce qu'elle fonctionne?
Cela pourrait, en effet, servir à d'autres...
Pour le format nombre, il te suffit de remplacer :
With Sheets(Feuille) .Columns("A:K").ClearContents .Columns("A:I").NumberFormat = "@" '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General"
par :
With Sheets(Feuille) .Columns("A:K").ClearContents .Columns("A:G").NumberFormat = "@" .Columns("H:H").NumberFormat = "0.00" .Columns("I:I").NumberFormat = "@" '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General"
Peux tu me faire un retour également sur la solution 2. Est ce qu'elle fonctionne?
Cela pourrait, en effet, servir à d'autres...
Bonjour,
Désolé du délais... vacance oblige :)
Je veux ajouter trois colonnes entre B et C.
La nouvelle Colonne C : rien à automatiser
La nouvelle Colonne D : Je veux le # de la semaine (=No.semaine...)
La nouvelle Colonne E : Je veux l'année de la nouvelle colonne F
En passant, La macro fonctionne vraiment bien. :):):)
Désolé du délais... vacance oblige :)
Je veux ajouter trois colonnes entre B et C.
La nouvelle Colonne C : rien à automatiser
La nouvelle Colonne D : Je veux le # de la semaine (=No.semaine...)
La nouvelle Colonne E : Je veux l'année de la nouvelle colonne F
En passant, La macro fonctionne vraiment bien. :):):)
Bonjour,
Avec un peu (beaucoup) de retard, essaye ce code :
Avec un peu (beaucoup) de retard, essaye ce code :
Option Explicit Private Const ENTETE As String = "#;ITEM;???;N° SEM;Year;Posting Date;Document;Whse;G/L Acct/BP Code;G/L Acct/BP Name;Qty;Inventory UoM;Price after Disc.;Balance" Private delim As String Private Feuille As String '===================================================== 'Méthode 1 => Lecture séquentielle du fichier txt Public Sub Macfly_SEQ() Dim Tb() As String, Tb_Out() As Variant, Chaine As String, NomFic As String, num As Long, i As Long Dim t As Double t = Timer delim = Chr(9) Feuille = "Feuil2" For i = 1 To 9 Chaine = Chaine & delim Next i num = FreeFile NomFic = Source If NomFic = "" Then Exit Sub Open NomFic For Input As #num i = -1 While Not EOF(1) i = i + 1 ReDim Preserve Tb(i) Line Input #1, Tb(i) If Tb(i) = Chaine Then i = i - 1 Wend Close #num Tb_Out = Tri_Donnees_SEQ(Tb()) Application.ScreenUpdating = False With Sheets(Feuille) .Columns("A:K").ClearContents .Columns("A:G").NumberFormat = "@" .Columns("H:H").NumberFormat = "0.00" .Columns("I:I").NumberFormat = "@" '.Columns("K:K").NumberFormat = "@" 'formate la colonne K en texte ===> Affichage 2,058 .Columns("K:K").NumberFormat = "General" For i = 0 To UBound(Split(ENTETE, ";")) .Cells(1, i + 1) = Split(ENTETE, ";")(i) Next .Cells(2, 1).Resize(UBound(Tb_Out, 1), UBound(Tb_Out, 2)) = Tb_Out .Select End With Application.ScreenUpdating = True MsgBox Timer - t End Sub Private Function Tri_Donnees_SEQ(Tb() As String) As Variant() Dim TbTemp() As Variant, i As Long, Cpt As Long, j As Byte ReDim Preserve TbTemp(1 To UBound(Tb), 1 To 14) For i = 1 To UBound(Tb) If Split(Tb(i), delim)(0) <> "" Or UCase(Right(Split(Tb(i), delim)(0), 1)) <> "U" Or Split(Tb(i), delim)(5) <= 0 Then Cpt = Cpt + 1 If Split(Tb(i), delim)(1) = "" Then TbTemp(Cpt, 1) = CStr(Split(Tb(i), delim)(0)) TbTemp(Cpt, 2) = CStr(Split(Tb(i), delim)(4)) For j = 3 To UBound(Split(Tb(i), delim)) - 1 If j = 3 And IsDate(Split(Tb(i), delim)(j)) Then TbTemp(Cpt, 4) = num_sem(CDate(Split(Tb(i), delim)(j))) If j = 4 And IsDate(Split(Tb(i), delim)(j)) Then TbTemp(Cpt, 4) = Year(Split(Tb(i), delim)(j)) If j <> 4 Then TbTemp(Cpt, j + 6) = CStr(Split(Tb(i), delim)(j)) Next j ElseIf Left(Split(Tb(i), delim)(1), 2) = "DN" Then TbTemp(Cpt, 1) = CStr(TbTemp(Cpt - 1, 1)) TbTemp(Cpt, 2) = CStr(TbTemp(Cpt - 1, 2)) If IsDate(Split(Tb(i), delim)(0)) Then TbTemp(Cpt, 4) = num_sem(CDate(Split(Tb(i), delim)(0))) TbTemp(Cpt, 5) = Year(Split(Tb(i), delim)(0)) End If For j = 0 To UBound(Split(Tb(i), delim)) - 1 TbTemp(Cpt, j + 6) = CStr(Split(Tb(i), delim)(j)) Next j End If End If If TbTemp(Cpt, 1) = "" Then Cpt = Cpt - 1 Next i Tri_Donnees_SEQ = TbTemp End Function Private Function Source() As String Source = Application.GetOpenFilename End Function Private Function num_sem(D As Date) As Long 'Auteur: Laurent Longre. X-Cell 'La fonction suivante renvoie le numéro de semaine conforme à la norme ISO, _ utilisée dans les pays européens (la première semaine d'un mois étant définie _ comme la première semaine comportant au moins quatre jours dans le mois). D = Int(D) num_sem = DateSerial(Year(D + (8 - Weekday(D)) Mod 7 - 3), 1, 1) num_sem = ((D - num_sem - 3 + (Weekday(num_sem) + 1) Mod 7)) \ 7 + 1 End Function
Je ne sais pas où inscrire le code rngCible.Value = rngSource.Value
Pour ma boucle, Dans mon code actuel, je copie et colle des données de la ligne du haut. si je commence par la dernière ligne, ça ne fonctionnera pas...