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.

È stato utile?

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 controllare If 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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top