Converti riga con colonne di dati in colonna con più righe in Excel 2007
-
21-09-2019 - |
Domanda
Ho una riga di dati come segue:
header1 header2 header3 header4 header5
row key datavalue1 datavalue2 datavalue3 datavalue4 datavalue5....
quindi, fondamentalmente, ho un set di dati denormalizzato in cui i valori dei dati possono o meno essere vuoti riga per riga.Devo normalizzarli.
cioè
12345678 NULL 10 3 NULL 14
potrebbe diventare:
12345678 header2 10
12345678 header3 3
12345678 header5 14
Potrei farlo utilizzando una trasformazione speciale Incolla, ma ho migliaia di righe e dovrei assicurarmi di ottenere la chiave di riga giusta per ciascuna.inoltre, ogni riga ha una serie di descrizioni ad essa associate che devo copiare con ciascun valore di dati.
Qual è il modo più semplice per convertire ogni riga di colonne in modo tale da avere più righe di una singola colonna con tutti i valori di dati non vuoti più il riferimento al valore di dati associato?Devo essere in grado di ruotare il set di dati.
Soluzione
Se hai cinque colonne di "intestazione", inserisci queste formule
H1: =OFFSET($A$1,INT((ROW()-1)/5)+1,0)
I1: =OFFSET($A$1,0,IF(MOD(ROW(),5)=0,5,MOD(ROW(),5)))
J1: =INDEX($A$1:$F$9,MATCH(H1,$A$1:$A$9,FALSE),MATCH(I1,$A$1:$F$1,FALSE))
Copia H1:J??e incolla valori speciali sopra.Ordina nella colonna J ed elimina tutto ciò che è zero.Se nei dati sono presenti zeri legittimi, è necessario prima sostituire le celle vuote con una stringa univoca che è possibile eliminare in seguito.
Se hai più colonne, sostituisci il "5" in tutte le formule precedenti con qualunque numero tu abbia.
Altri suggerimenti
Mi sembra che parte di ciò che stai cercando di fare sia "de-pivotare" una tabella pivot.Ho trovato questo suggerimento di grande aiuto quando ho dovuto svolgere compiti simili: http://spreadsheetpage.com/index.php/tip/creating_a_database_table_from_a_summary_table/
Tieni presente che in Excel 2007 puoi accedere alla vecchia procedura guidata per la tabella pivot di Excel 2003 utilizzando la sequenza di tasti Alt+D, P .
Excel ha una funzione di trasposizione che può soddisfare le tue esigenze.È piuttosto nascosto e un po' goffo, ma probabilmente più semplice che approfondire VBA.Ecco un estratto dalla Guida di Excel 2007:
Le colonne e le righe di BlockQuote Switch (trasponi) mostrano tutto se i dati vengono immessi in colonne o righe, ma si desidera riorganizzare tali dati in righe o colonne, è possibile trasporre rapidamente i dati da uno all'altro.
Ad esempio, i dati sulle vendite regionali organizzati in colonne vengono visualizzati in righe dopo la trasposizione dei dati, come mostrato nella grafica seguente.
1.Nel foglio di lavoro, effettuare le seguenti operazioni:Per riorganizzare i dati dalle colonne alle righe, seleziona le celle nelle colonne che contengono i dati.Per riorganizzare i dati dalle righe alle colonne, seleziona le celle nelle righe che contengono i dati.2.Nella scheda Home, nel gruppo Appunti, fare clic su Copia .
Scorciatoia da tastiera Per copiare i dati selezionati, puoi anche premere CTRL+C.
Nota È possibile utilizzare solo il comando Copia per riorganizzare i dati.Per completare correttamente questa procedura, non utilizzare il comando Taglia.
3.Nel foglio di lavoro selezionare la prima cella delle righe o colonne di destinazione in cui si desidera riorganizzare i dati copiati.Nota Aree di copia (area di copia:Le celle che copi quando desideri incollare i dati in un'altra posizione.Dopo aver copiato le celle, attorno ad esse viene visualizzato un bordo mobile per indicare che sono state copiate) e le aree di incollaggio (area incolla:La destinazione di destinazione per i dati che sono stati tagliati o copiati utilizzando gli Appunti di Office.) non può sovrapporsi.Assicurati di selezionare una cella in un'area di incollamento che non rientra nell'area da cui hai copiato i dati.
4.Nella scheda Home, nel gruppo Appunti, fare clic sulla freccia sotto Incolla, quindi su Trasponi.5.Dopo che i dati sono stati trasposti con successo, è possibile eliminare i dati nell'area di copia.Suggerimento Se le celle che trasponi contengono formule, le formule vengono trasposte e i riferimenti di cella ai dati nelle celle trasposte vengono regolati automaticamente.Per assicurarti che le formule continuino a fare riferimento correttamente ai dati nelle celle non trasposte, utilizza riferimenti assoluti nelle formule prima di trasporle.
Per ulteriori informazioni, consulta Passare tra riferimenti relativi, assoluti e misti.
Citazione in blocco
Diamo un'occhiata a una possibile soluzione in VBA.Penso che questo sarà davvero d'aiuto.Ecco alcune cose che dovresti sapere sul mio codice.
- Dovrai inserire questo codice in un modulo di codice in VBA (lo stesso posto in cui vanno i macro)
- Guarda come ho chiamato le lenzuola:Originale e normalizzato.Ti consigliamo di modificare i nomi dei fogli o il codice
- Sto controllando i valori con un campo stringa di
NULL
.Se la cella è vuota, ti consigliamo di controllareIf IsEmpty(rngCurrent.Value) Then
Invece.
'
Sub NormalizeSheet()
Dim wsOriginal As Worksheet
Dim wsNormalized As Worksheet
Dim strKey As String
Dim clnHeader As Collection
Dim lngColumnCounter As Long
Dim lngRowCounterOriginal As Long
Dim lngRowCounterNormalized As Long
Dim rngCurrent As Range
Dim varColumn As Variant
Set wsOriginal = ThisWorkbook.Worksheets("Original") 'This is the name of your original worksheet'
Set wsNormalized = ThisWorkbook.Worksheets("Normalized") 'This is the name of the new worksheet'
Set clnHeader = New Collection
wsNormalized.Cells.ClearContents 'This deletes the contents of the destination worksheet'
lngColumnCounter = 2
lngRowCounterOriginal = 1
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
' We'll loop through just the headers to get a collection of header names'
Do Until IsEmpty(rngCurrent.Value)
clnHeader.Add rngCurrent.Value, CStr(lngColumnCounter)
lngColumnCounter = lngColumnCounter + 1
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
Loop
'Here we'll reset our Row Counter and loop through the entire data set'
lngRowCounterOriginal = 2
lngRowCounterNormalized = 1
lngColumnCounter = 1
Do While Not IsEmpty(wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter))
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
strKey = rngCurrent.Value ' Get the key value from the current cell'
lngColumnCounter = 2
'This next loop parses the denormalized values for each row'
Do While Not IsEmpty(wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter))
Set rngCurrent = wsOriginal.Cells(lngRowCounterOriginal, lngColumnCounter)
'We're going to check to see if the current value'
'is equal to NULL. If it is, we won't add it to'
'the Normalized Table.'
If rngCurrent.Value = "NULL" Then
'Skip it'
Else
'Add this item to the normalized sheet'
wsNormalized.Range("A" & lngRowCounterNormalized).Value = strKey
wsNormalized.Range("B" & lngRowCounterNormalized).Value = clnHeader(CStr(lngColumnCounter))
wsNormalized.Range("C" & lngRowCounterNormalized).Value = rngCurrent.Value
lngRowCounterNormalized = lngRowCounterNormalized + 1
End If
lngColumnCounter = lngColumnCounter + 1
Loop
lngRowCounterOriginal = lngRowCounterOriginal + 1
lngColumnCounter = 1 'We reset the column counter here because we're on a new row'
Loop
End Sub
Vorrei creare una macro VBA che esegue il loop su ogni riga e invia i dati a un'altra pagina.Ciò ti consentirebbe di creare la tua tabella pivot nella nuova pagina una volta che i dati sono stati generati.
Non sono sicuro di quanto tu abbia familiarità con VBA, ma questo potrebbe essere fatto abbastanza facilmente caricando i dati in un array (o una raccolta di oggetti se vuoi davvero farlo correttamente) e riscrivendoli.
Ecco un collegamento a un buon documento VBA.
http://social.msdn.microsoft.com/Forums/en/isvvba/thread/d712dbdd-c876-4fe2-86d2-7d6323b4262c
Modificare
Tieni presente che questa non vuole essere una soluzione completamente funzionante, ma in realtà un framework generico per aiutarti nella giusta direzione.
Come esempio generico che fa molto di ciò che dovresti fare (non il modo migliore, ma probabilmente il più semplice per un principiante), qualcosa di simile dovrebbe aiutarti a iniziare, anche se è difficile dirlo senza vedere più parti del tuo foglio di lavoro .
Sub RowsToColumns ()
Application.ScreenUpdating = False
Dim srcWrkSheet As Worksheet
Dim destWrkSheet As Worksheet
Dim excelData as pExcelData
Dim srcRowNumber As Long
Dim srcRolNumber As Long
Dim destRowNumber As Long
Dim destColNumber As Long
SET srcWrkSheet = Sheets("YourSourceWorkSheetName")
SET destWrkSheet = Sheets("YourDestinationWorkSheetName")
srcRowNumber = 1
srcColNumber = 1
destRowNumber = 1
destColNumber = 1
'Loop until blank row is encountered in column 1
Do
destWrkSheet.Cells(destRowNumber ,1).Value = "Header 1 " & srcWrkSheet.Cells(srcRowNumber,srcColNumber )
destWrkSheet.Cells(destRowNumber ,1).Value = "Header 2 " & srcWrkSheet.Cells(srcRowNumber ,srcColNumber)
srcRowNumber = srcRowNumber + 1
srcColNumber = srcColNumber + 1
destRowNumber = destRowNumber + 1
Loop Until srcWrkSheet .Cells(rowNumber, 1).value = ""
End Sub