Réorganisation fichier Excel

Bonjour,

Débutant en VBA, je vous sollicite car je ne comprends pas le résultat de ma macro, et plus particulièrement la condition.

Dans l'idée, je souhaite tester une cellule, si celle ci est est vide, j’incrémente mon compteur pour passer a la ligne suivante ou est présente l'information.

N'arrivant pas à maîtriser le niveau 1, j'en profite pour vous demander l'inverse.

Pour un numéro de série, je peux avoir 2 adresse mac, je souhaite les concaténer dans une cellule unique, et si vide passer à la ligne suivante.

Je sais pas si je m'exprime clairement, du coup je vous joint un fichier avec mon début de code, le fichier source, le résultat obtenu, et ce que je souhaite obtenir comme résultat définitif.

Merci pour votre aide.

Bonjour,

2 remarques concernant ton code :

--> Utiliser des boucles "With Truc...End With" pour simplifier l'écriture du code

Sheets("ligne").Range("A" & NumLigneLigne).Value = Sheets("Feuil1").Range("C" & NumLigneFeuil1).Value
'Devient :
With Sheets("ligne")
    .Range("A" & NumLigneLigne).Value = Sheets("Feuil1").Range("C" & NumLigneFeuil1).Value
End With

--> Pour tester si une cellule est vide :

IsEmpty(Range("A1"))
'On peut procéder différemment :
Not IsNumeric(Range("A1"))
Not IsText(Range("A1"))

Bonjour, Salut Pedro !

Nouvelle procédure :

Sub Reorganisation()
    Dim Tbl(), aa, i%, j%
    aa = Worksheets("export").Range("A1").CurrentRegion
    For i = 2 To UBound(aa)
        If aa(i, 4) <> "" Then
            j = i
            If j < UBound(aa) Then
                Do While aa(j + 1, 3) = aa(i, 3)
                    j = j + 1
                    If aa(j, 4) <> "" Then
                        aa(i, 4) = aa(i, 4) & " + " & aa(j, 4)
                        aa(j, 4) = ""
                    End If
                    If j = UBound(aa) Then Exit Do
                Loop
            End If
            i = j
        End If
    Next i
    j = 0
    For i = 2 To UBound(aa)
        j = j + 1: ReDim Preserve Tbl(2, j)
        Tbl(0, j - 1) = aa(i, 3): Tbl(1, j - 1) = aa(1, 1): Tbl(2, j - 1) = aa(i, 1)
        Tbl(0, j) = aa(i, 3): Tbl(1, j) = aa(1, 2): Tbl(2, j) = aa(i, 2)
        If aa(i, 4) <> "" Then
            j = j + 1: ReDim Preserve Tbl(2, j)
            Tbl(0, j) = aa(i, 3): Tbl(1, j) = aa(1, 4): Tbl(2, j) = aa(i, 4)
        ElseIf aa(i, 5) <> "" Then
            j = j + 1: ReDim Preserve Tbl(2, j)
            Tbl(0, j) = aa(i, 3): Tbl(1, j) = aa(1, 5): Tbl(2, j) = aa(i, 5)
        End If
        j = j + 1
    Next i
    With Worksheets("ligne")
        .Range("A1").CurrentRegion.Offset(1).ClearContents
        .Range("A2").Resize(j, 3).Value = WorksheetFunction.Transpose(Tbl)
        .Activate
    End With
End Sub

NB- Honnêtement, je trouve que ta présentation est plutôt tordue...

Cordialement.

Bonjour,

Merci pour vos réponses.

@MFerrand, ta procédure fonctionne parfaitement, mais je m'attendais pas à qqch d'aussi compliqué, ça va me prendre du temps pour bien le comprendre et l'adapter à mon contexte.

Pour ma compréhension, initialiser un tableau tel que tu l'as fait, est vraiment plus simple que de vérifier les cellules unitairement puis d’incrémenter?

Disons que la manipulation de tableau est plus rapide et plus simple une fois les données chargées dans le tableau. La rapidité d’exécution s'en ressent dans le cas de fichiers de dimension importante.

Effectivement mon fichier d'origine fait 20000 lignes, et ta procédure et nettement plus rapide.

Bon, bah plus qu'a tout comprendre pour être capable de pondre ça une prochaine fois.

Merci

Pour 20000 lignes, remplace i% et j% (variables Integer) dans les déclarations de variables par i& et j& (variables Long). Les expériences ont montré qu'elles sont plus rapides lors de l'exécutions. [J'ai toujours quelques scrupules à les utiliser systématiquement (comme le fait Eriiic...) pour des petits nombres, mais dès qu'on approche le millier, je pense que ça s'impose...]

Comme l'a dit Pedro, travailler avec des tableaux est plus rapide, bien qu'au cas particulier, le tableau résultat doit être composé élément par élément, vu ta disposition des données...

C'est assez simple à comprendre, mais il convient de maîtriser un minimum les variables tableaux.

D'abord on extrait tes données initiales dans un tableau : on affecte les valeurs de la plage à une variable de type Variant, ce qui produit un tableau à 2 dimensions de bases 1 (on sait ainsi qu'on va toujours de la ligne 2 à la fin s'il y a une en-tête, ou de la ligne 1 à fin si pas d'en-tête).

La particularité dans ton cas, c'est qu'on traite ce tableau pour opérer la concaténation des adresse MAC dès le départ : on parcours les lignes, lorsqu'on trouve une adresse MAC, on démarre un boucle Do... Loop sur le même numéro de série, et lorsqu'on trouve une autre adresse MAC, on la concatène à la première (sur la ligne d'arrêt dans la première boucle) en l'effaçant de son emplacement initial. On apporte un correctif pour ne pas revenir sur les lignes parcourues par la boucle interne (en faisant i=j pour poursuivre). Les autres conditions visent à ne pas dépasser la dimension du tableau avec la boucle interne...

Ensuite on parcours à nouveau les lignes de notre tableau pour servir le tableau résultat : chaque ligne du tableau initial se traduit par 2 lignes de résultat + éventuellement 1 ligne MAC ou 1 ligne disque. On l'incrémente donc au fur et à mesure : on part avec la variable j à 0 qu'on incrémente systématiquement de 1, le tableau étant d'indice 0, cela inclut 2 lignes au départ, qu'on sert, puis on incrémente une ligne si nécessaire (MAC ou disque) et enfin on incrémente j de 1 avant de passer au tour suivant où il sera incrémenté à nouveau de 1 (soit les 2 lignes nécessaires minimales à chaque tour). En fin, j dépasse de 1 l'indice max du tableau résultat, et correspond au nombre de lignes de résultats, le tableau étant de base 0.

S'agissant d'un tableau(colonnes, lignes), on le transpose lors de l'affectation. La rapidité supérieure provient de ce qu'entre le prélèvement initial des données et l'affectation des résultats à la fin on travaille hors Excel...

Cordialement.

Petite question supplémentaire, il m'est nécessaire de pouvoir ajouter des lignes, mais je n'arrive pas à redimensionner le tableau pour avoir "la place nécessaire" pour intégrer de nouvelles lignes.

Comment puis je faire ? J'avoue que j('ai un peu de mal avec la visualisation des tableaux.

bonjour

sans VBA

juste des RECHERCHEV, des SI et un TCD

on peut améliorer si vraiment nécessaire

Je peux pas utiliser les formules excel, dans la mesure ou je dois générer un csv 100% automatiquement afin de réimporter les données dans une autre console, et cela sans actions externe.

heu...

sais-tu organiser des fichiers ? c'est très important en Excel

crée un fichier "Exploitation" au clavier/souris, 1 unique fois dès maintenant

il importera d'un clic les données d'une source

il les traitera automatiquement (les formules font le job instantanément ou presque)

un tout petit code peut cliquer à ta place sur "actualiser"

reste à créer le csv

là je pense qu'un petit code VBA s'impose. Même l'enregistreur peut suffire

combine les 2 codes

on a économisé 95% du code, et 100% du code difficile !

Je ne décide pas comment organiser mon fichier. C'est la console dans laquelle je vais importer le fichier qui me l'impose.

Pour faire simple, je récupère les informations présentes dans le fichier de démo via une web api mais je ne peux pas toucher au schéma, sinon je me serais débrouillé pour tout mettre sur une seule et même ligne au départ, et sans cellule vide.

Ensuite je veux trier les informations et les mettre au bon format, qui m'est imposé, pour pouvoir les importer dans une console.

Petite question supplémentaire, il m'est nécessaire de pouvoir ajouter des lignes, mais je n'arrive pas à redimensionner le tableau pour avoir "la place nécessaire" pour intégrer de nouvelles lignes.

Comment puis je faire ? J'avoue que j('ai un peu de mal avec la visualisation des tableaux.

Nouveau Feuille de calcul Microsoft Excel.xlsm

Bonjour,

Il faudrait que tu expliques dans le détail comment tu passes de ta nouvelle situation de départ à la situation souhaitée, et en précisant à chaque fois si c'est semblable à ta 1re version ou diffère et en quoi...

Ta réorganisation de données n'étant pas particulièrement simple, on ne va pas s'y retrouver spontanément !

Coordialement.

Je ne décide pas comment organiser mon fichier. C'est la console dans laquelle je vais importer le fichier qui me l'impose.

Pour faire simple, je récupère les informations présentes dans le fichier de démo via une web api mais je ne peux pas toucher au schéma, sinon je me serais débrouillé pour tout mettre sur une seule et même ligne au départ, et sans cellule vide.

Ensuite je veux trier les informations et les mettre au bon format, qui m'est imposé, pour pouvoir les importer dans une console.

re à tous

pour moi, c'est le job de menu Données Obtenir (sur ton 2016, c'est du gâteau)

on modifie

on charge

Bonjour, salut MFerrand,

[quote]remplace i% et j% (variables Integer) dans les déclarations de variables par i& et j& (variables Long). Les expériences ont montré qu'elles sont plus rapides lors de l'exécutions. [J'ai toujours quelques scrupules à les utiliser systématiquement (comme le fait Eriiic...)[/quote]

Dans un langage normalement conçu , oui. Byte sera plus rapide que Integer, lui-même plus rapide que Long.

Cependant lorsque je teste avec ça par exemple :

Sub comp_IntegerLong()
    Dim k As Long, t As Single
    Dim i As Integer, a(0 To 99) As Integer
    Dim j As Long, b(0 To 99) As Long
   'Integer
    t = Timer
    For k = 1 To 1000000
        Erase a
        For i = 0 To 99
            a(i) = a(i) + i
        Next i
    Next k
    Debug.Print Timer - t
    'Long
    t = Timer
    For k = 1 To 1000000
        Erase b
        For j = 0 To 99
            b(j) = b(j) + j
        Next j
    Next k
    Debug.Print Timer - t
End Sub

Contrôle le code en détail, je ne pense pas avoir commis d'impairs qui pourrait fausser les résultats, mais bon, 4 yeux valent mieux que 2.

Chez moi Integer met 13% de temps en plus que Long.

Et pour les bytes c'est pire encore : +22%

Cependant, sur une boucle seule (sans calculs, tableaux mis en commentaire) un Integer sera plus rapide de 2%.

Idem si on l'utilise uniquement en tant qu'indice (a(i) = 5 ou Cells(i, 1) = 5)

Forcément ça me fait me poser des questions.

Je n'ai pas d'autre explication rationnelle qu'en Entiers, pour les calculs, il ne connaisse que les Long, et qu'il fasse une conversion Integer/Long avant usage.

A se demander même si pour les Bytes il ne ferait pas une conversion en Integer suivie d'une conversion de l'Integer en Long

Il y a donc des cas où l'on est gagnant de 2%, d'autres perdant de 13%.

Ca demanderait à chaque fois une lecture attentive pour faire le bon choix.

A partir de ce constat c'est vrai, je ne m'embête plus : tout en Long et basta

eric

Salut Eric !

Je vais essayer de garder en mémoire tes résultats de tests élaborés... mais le choix de la meilleure solution n'a rien d'évident !

Ce qui est dommage c'est que VB a des vrais Byte et Integer, ils auraient pu se contenter d'emmener l'ensemble.

Désolé pour le HS pinpin, on va essayer de se reconcentrer sur ton sujet

eric

Petite question supplémentaire, il m'est nécessaire de pouvoir ajouter des lignes, mais je n'arrive pas à redimensionner le tableau pour avoir "la place nécessaire" pour intégrer de nouvelles lignes.

Comment puis je faire ? J'avoue que j('ai un peu de mal avec la visualisation des tableaux.

Nouveau Feuille de calcul Microsoft Excel.xlsm

Bonjour,

Il faudrait que tu expliques dans le détail comment tu passes de ta nouvelle situation de départ à la situation souhaitée, et en précisant à chaque fois si c'est semblable à ta 1re version ou diffère et en quoi...

Ta réorganisation de données n'étant pas particulièrement simple, on ne va pas s'y retrouver spontanément !

Coordialement.

Hello,

Concrètement ma clé d'entrée est le numéro de série et je dois pouvoir passer le tableau, qui est dynamique en revu.

Je n'ai pas une ligne par entré car, il est possible qu'un poste est plusieurs adresse mac (wifi, eth etc..), et plusieurs disques durs.

De ce fait, je boucle sur les adresses MACs, pour les concaténer, et les stocker .

Ensuite, création du tableau, ou les valeurs des adresses macs sont coller, et ensuite je souhaite pouvoir integrer des données supplémentaire.

En effet, si je passe en commentaire les lignes suivantes :

'Tbl(0, j) = aa(i, 9): Tbl(1, j) = aa(1, 12): Tbl(2, j) = aa(i, 12)

'Tbl(0, j) = aa(i, 9): Tbl(1, j) = aa(1, 15): Tbl(2, j) = aa(i, 15)

'Tbl(0, j) = aa(i, 9): Tbl(1, j) = aa(1, 6): Tbl(2, j) = aa(i, 6)

Je me retrouve avec un résultat a trou ce qui est normal, mais je n'arrive pas à gagner de la place afin de pouvoir ajouter des lignes.

Dans l'idée mon CSV doit ressembler a

N°de série;Nom de la caractéristique;valeur

Si on a deux valeurs différentes (mac, disque dur dans mon cas), pour un meme nom de caractéristique pour un numéro de serie donné je dois pouvoir les concaténer (comme ce qui est fait pour les mac)

Bonjour,

Pas eu le temps de me pencher sur la question pour t'indiquer les informations dont j'ai besoin...

Il faut que je passe au peigne fin toutes les données traitées dans ta configuration précédente pour les replacer dans la nouvelle, et voir comment se situent celles qui ne figuraient pas dans la config précédente...

Dès que je trouve un moment pour ça...

Bonjour,

On va tenter un premier débroussaillage :

Premier cas traité (antérieurement) : nous avions 5 colonnes par ligne à prendre en considération

CPU - Capacité mémoire - N° série - Adresse Mac - Disque dur

Ces infos se situaient col. 1 - 2 - 3 - 4 - 5

Pour chaque ligne de données initiale, on avait plusieurs lignes résultantes :

Série - CPU

Série - Capacité mémoire

Série - Adresses mac [optionnelle si adresses Mac concernant ce numéro de série]*

Série - Disque dur [optionnelle si disque dur mentionné sur la ligne traité]

* Particularité : si plusieurs ligne avec même numéro de série comportaient une adresse Mac, regroupement des adresses Mac (concaténation) sur une seule ligne résultante, dans le traitement de la première ligne traitée d'un même numéro de série.

D'où la méthode :

  • prise en compte d'un numéro de série : recherche des adresses Mac dans les lignes comportant ce numéro de série
  • puis traitement par ligne source de ce numéro de série : 2 lignes résultantes obligatoires (CPU - Capacité mémoire) - 1 ligne éventuelle Adresses Mac regroupées (sur la première ligne traitée dans la source concernant le numéro de série) - 1 ligne optionnelle Disque dur.

Pour le nouveau cas soumis (nouvelle configuration de données sources et des résultats)

Nous avons 6 colonnes à prendre en considération (en jaune dans le modèle) :

Fréquence du processeur (remplace le libellé CPU) - Capacité mémoire - N° série - Adresse Mac - OS (nouveau) - Taille disque (remplace le libellé Disque dur)

Ces infos se situent en colonnes : 4 - 6 - 9 - 11 - 12 - 15.

Si tout doit se passer de façon analogue au précédent traitement :

  • On va naturellement rechercher les adresses Mac d'un même numéro de série pour les concaténer.
  • On traite ensuite ligne par ligne (source), pour obtenir :
Série - Fréquence processeur

Série - Capacité mémoire

Série - OS

Série - Adresses Mac (selon les mêmes particularités que précédemment)

Série - Taille disque (optionnelle...)

Pour chaque ligne source, on aura donc 3 lignes résultantes obligatoires + 1 lignes éventuelle adresses Mac (une seule fois par numéro de série) + 1 lignes optionnelle (Taille disque).

Ce schéma est à confirmer, car ton modèle en feuille ligne a fait disparaître la ligne Capacité mémoire.

Il faut donc confirmer si cette ligne demeure obligatoire d'une part.

Et confirmer l'ordre des lignes d'autre part : Fréquence processeur - Capacité mémoire - OS, ou bien : Fréquence processeur - OS - Capacité mémoire, ou bien autre le cas échéant.

Cordialement.

Rechercher des sujets similaires à "reorganisation fichier"