Comment fractionner une ligne d'Excel en plusieurs lignes pour la gestion de base de données

3

J'ai un ensemble de données qui est actuellement de 39 000 lignes et 27 colonnes. La première colonne est le numéro d'identification. Les colonnes suivantes correspondent aux élections, avec la date de l'élection dans la rangée 1 (cellules B1- AA1). Le reste des cellules est rempli avec une lettre qui correspond à la méthode de vote (ou nulle si vous n'avez pas voté). Je dois réorganiser ce tableau afin qu'il y ait un total de trois colonnes: ID, Date et Méthode de vote. Par exemple:

Tableau actuel:

ID          05/2005        11/2005        03/2006 (etc., for 27 total columns)
2345           P              V
3789                          A              V
4321           V              A              V
7890                          I

Et j'en ai besoin pour ressembler à ceci:

ID           Date            Voting Method
2345         05/2005               P
2345         11/2005               V
3789         11/2005               A
3789         03/2006               V
4321         05/2005               V
4321         11/2005               A
4321         03/2006               V
7890         11/2005               I

Je pense que cela va nécessiter un script VBA, et j'ai essayé de reconstituer des morceaux de script trouvés en ligne (car je n'ai jamais appris VBA), mais je n'arrive pas à le faire fonctionner correctement. Peut-être que cette fonction existe déjà dans Excel?

Voici le script sur lequel je travaille jusqu'à présent:

Sub NewLayout()
For i = 2 To Cells.Find("*", [A1], , , xlByRows, xlPrevious).Row
  For j = 0 To 26
    If Cells(i, 3 + j) <> vbNullString Then
      intCount = intCount + 1
      Cells(i, 1).Copy Destination:=Cells(intCount, 10)
      Cells(i, 2).Copy Destination:=Cells(intCount, 11)
                [I think this one is wrong. It needs to copy the column name,
                not the cell value, if there is a cell value.]
      Cells(i, 3 + j).Copy Destination:=Cells(intCount, 12)
    End If
    Next j
  Next i
End Sub

Si quelqu'un a des suggestions, je l'apprécierais!

Haynes
la source
J'ai un peu formaté votre message pour le rendre plus lisible. Ceci dit, montrez votre travail: nous ne sommes pas un service de rédaction de scripts.
Doktoro Reichard
Merci d'avoir nettoyé le formatage! Je n'étais pas sûr de savoir comment l'afficher correctement. Et je ne m'attends certainement pas à ce que vous écriviez le script pour moi (si un script est la bonne façon de procéder? Peut-être que cette fonction existe déjà dans Excel?) Je posterai le script que je travaille dans mon message d'origine ( Je n'arrive pas non plus à obtenir le formatage exact dans la section commentaire).
Haynes
Réorganiser les cellules dans Excel est une tâche délicate. Souvent, vous ne pouvez pas le faire car Excel est en mode "Lecture seule" pendant l'exécution du script, afin d'éviter des problèmes tels qu'un script mal écrit essayant de mettre à jour une cellule, ce qui déclenche une autre cellule à mettre à jour, ce qui déclenche la mise à jour de votre script, ce qui déclenche la mise à jour d'une autre cellule, ce qui déclenche à nouveau votre script, et ainsi de suite, en boucle pour toujours. Pourriez-vous éventuellement exporter vos données vers un produit de base de données tel qu'Access?
CM
Cela pourrait se faire sans VBA, mais la façon dont je vois les choses serait compliquée (parce que cela se ferait avec un processus similaire à celui que j'avais fait lors d'une réponse précédente , ce qui, je l'avoue, est compliqué). Je vais essayer de faire une réponse concrète en utilisant seulement les fonctions Excel plus tard, mais un script VBA serait "plus facile" à implémenter.
Doktoro Reichard
Bonjour à tous, Merci beaucoup pour vos réponses! J'ai eu les données reformatées en utilisant le script Python (je n'avais même pas considéré cela) qu'un ami a écrites. Heureux de savoir qu'il existe plusieurs façons d'obtenir le même résultat!
Haynes

Réponses:

1

Avec VBA, en supposant que les données se trouvent dans la feuille 1 à partir de A1 et que la feuille 2 existe:

Sub normalize()
    Dim wks1 As Worksheet, wks2 As Worksheet
    Dim iColCount As Integer, iRowCount As Integer
    Dim i As Integer, j As Integer, k As Integer

    Set wks1 = ActiveWorkbook.Sheets("Sheet1")
    Set wks2 = ActiveWorkbook.Sheets("Sheet2")
    iColCount = Application.WorksheetFunction.CountA(wks1.Range("1:1"))
    iRowCount = Application.WorksheetFunction.CountA(wks1.Range("A:A"))

    k = 1
    For i = 2 To iRowCount
        For j = 2 To iColCount
            If wks1.Cells(i, j) <> vbNullString Then
                wks1.Cells(i, 1).Copy Destination:=wks2.Cells(k, 1)
                wks1.Cells(1, j).Copy Destination:=wks2.Cells(k, 2)
                wks1.Cells(i, j).Copy Destination:=wks2.Cells(k, 3)
                k = k + 1
            End If
        Next j
    Next i
End Sub

Résultats en Sheet2:

2345    5/2005  P
2345    11/2005 V
3789    11/2005 A
3789    3/2006  V
4321    5/2005  V
4321    11/2005 A
4321    3/2006  V
7890    11/2005 I
geoB
la source
0

Par souci d'exhaustivité, je montre maintenant comment je fais cela sans recourir à VBA. Je dois avertir que le code suivant est compliqué et qu’il est difficile de s’adapter efficacement.

Supposons la condition initiale suivante:

Feuille1

   |  A |    B    |    C    |    D    | …
---+----+---------+---------+---------+---
 1 | ID | 05/2005 | 11/2005 | 03/2006 |
 2 |2345|    P    |    V    |         |
 3 |3789|         |    A    |    V    | …
 4 |4321|    V    |    A    |    V    |
 5 |7890|         |    I    |         |
 … |                 …

Feuille2

   |  A |   B  |       C       |
---+----+------+---------------+
 1 | ID | Date | Voting method |
 2 | #1 |  #2  |       #3      |

La cellule nommée # 1 a la formule suivante:

=INDIRECT(ADDRESS(FLOOR((ROW(A2)-2)/27 + 2,0),1,,,"Sheet1"))

Ce que cette formule fait est de mapper la cellule actuelle vers les cellules appropriées dans Sheet1. Ceci est fait avec l'aide de la FLOORfonction. La fonction augmente de 1 lorsque 27 lignes ont été passées, mappant correctement les lignes de la feuille Sheet2 avec le contenu de la feuille Sheet1.

La ADDRESSfonction construit une référence utilisable vers une cellule à partir des noms d'entrée et de feuille numériques, tandis que la INDIRECTfonction extrait le contenu pointé par la référence.

Le reste des autres fonctions suivent un raisonnement identique: vous utilisez une fonction auxiliaire pour mapper les coordonnées de la cellule actuelle sur la cellule correcte de la feuille Sheet1.

Pour la cellule nommée # 2 :

=INDIRECT(ADDRESS(1,MOD(ROW(A2)-2,27)+2,,,"Sheet1"))

Dans ce cas, la MODfonction alterne séquentiellement entre 0 et 26, qui est ensuite convertie en une séquence entre 2 et 28 (en d’autres termes, où se trouvent les cellules avec les dates).

Enfin, pour la cellule nommée # 3 :

=INDIRECT(ADDRESS(FLOOR((ROW(A2)-2)/27 + 2,0),MOD(ROW(A2)-2,27)+2,,,"Sheet1"))

C'est un mélange des deux séquences utilisées précédemment. La raison en est que le contenu varie en ce qui concerne l'ID (en tant que telle, la partie de la cellule n ° 1 est appelée) et la date (qui est l'endroit où la partie de la cellule n ° 2 entre).

Après avoir entré ces fonctions dans les bonnes cellules, faites simplement glisser le curseur vers le bas pour afficher les résultats, avec un petit problème: les votes nuls apparaissent également.

Vous pouvez cependant filtrer ces résultats. Sélectionnez l'en-tête (dans ce cas, la Aligne de la feuille Sheet2) et accédez à Données> Filtre> Filtre automatique (ou l'équivalent dans la version Excel que vous utilisez). Cliquez sur le menu déroulant dans la colonne du mode de vote et personnalisez le tri afin d'exclure les résultats composés de zéro.

Doktoro Reichard
la source
0

J'utiliserais le complément de requête de puissance pour ceci. Il ne nécessite aucun code ni fonctions complexes. À partir de zéro, cette tâche prendra probablement moins de 5 minutes.

Vous pouvez lancer une requête à partir d'un tableau Excel existant. J'utiliserais ensuite la commande Unpivot pour transformer les données selon vos besoins.

http://office.microsoft.com/en-au/excel-help/unpivot-columns-HA104053356.aspx

L'avantage de leur implémentation d'Unpivot est qu'il acceptera toutes les colonnes ajoutées (nouvelles dates) et les traitera sans aucun changement dans la définition de votre requête.

Je renommerais les colonnes si nécessaire et transmettrais le résultat à un tableau Excel.

Mike Honey
la source