Combinare celle



  • Combinare celle
    di Ste.cla (utente non iscritto) data: 22/09/2015 15:14:34

    Buongiorno a tutti,

    ho il seguente problema di risolvere in maniera efficiente (in maniera analitica ci sono già riuscito).
    Ho un database in excel da riorganizzare. All'interno della colonna A, ad ogni riga corrisponde un set di informazioni da combinare con altre informazioni per creare un nuovo record. Passo ad un esempio pratico.
    I set di informazioni sono nominati con lettere da A ad D, il numero progressivo indica che i set di informazioni C e D hanno una molteplicità pari a 2. Tutti i set possono avere molteplicità superiore a 1 tranne A che compare al massimo una volta.

    Riga1: info A
    Riga 2: Info B
    Riga 3: Info C1
    Riga 4: Info C2
    Riga 5: Info D1
    Riga 6: Info D2


    Partendo da questo esempio avrei bisogno di un programma vba che mi portasse ad avere questo, per qualsiasi molteplicità di B, C, D:
    Riga 1 = info A + info B + info C1 + info D1
    Riga 2 = info A + info B + info C1 + info D2
    Riga 3 = info A + info B + info C2 + info D1
    Riga 4 = info A + info B + info C2 + info D2

    Vi ringrazio in anticipo per ogni contributo!


  • allega un file
    di tanimon data: 22/09/2015 19:19:22

    ciao,
    credo di avere capito il tuo esempio e la nomina dei set
    ma per esserne sicuro e non cercare di darti una soluzione a casaccio....,

    allega un file con l'impostazione dei dati in posizione reale e con nomi di fantasia,
    descrivendo come hai già fatto, nel file che allegherai, il risultato atteso.

    Per come ho inteso, probabilmente puoi risolvere anche con formule.
    Ciao
    Frank



  • di Ste.cla (utente non iscritto) data: 23/09/2015 17:51:26

    Ciao Frank,

    grazie mille per il supporto. Dovrei aver allegato alla discussione un file excel con un esempio composto da 2 tipoinfo C e 3 tipoinfo D. Così da renderlo più completo. Tieni conto che l'esempio è solo una frazione del database, io poi dovrò replicare il modello di ordinamento su tutto il resto del database che è composto da blocchi di informazioni articolati in tipoinfo A, B, C, D e per i quali B, C e D possono apparire 0, 1 o N volte, mentre A appare una volta sola ed è quello che mi fa capire quando passo al blocco di informazioni successivo.

    Spero di essere stato chiaro, se non lo sono stato mi scuso in anticipo.

    Grazie mille

    Stefano



  • di Cucù data: 24/09/2015 13:22:03

    Io non capisco con che criteri si formano le serie

    Mi fai un esempio con valori di N=4 e N=5 così forse capisco meglio.

    Cucù



  • di tanimon data: 24/09/2015 22:33:52

    prova ad usare un STRINGA.ESTRAI

    una cosa tipo:


     
     
    =SE(STRINGA.ESTRAI(A8;9;1)="D";A8;"")



  • di Ste.cla (utente non iscritto) data: 01/10/2015 16:59:56

    Buongiorno Cucù, scusi il ritardo nella risposta.

    Le ho allegato un file excel (§Esempio 3§) che dovrebbe chiarire meglio come deve avvenire l'ordinamento della base dati. Tenga conto che faccio l'esempio con due soli blocchi di informazioni, in realtà il mio modello VBA mi dovrebbe consentire di replicarlo per alcune migliai adi blocchi in sequenza (che come precisato possono avere una dimensione, in termini di numerosità dei tipi informazione, diversa).

    L'archivio però si basa su regole certe.

    In ogni cella i primi 14 caratteri mi identificano il blocco, per cui tutte le celle nello stesso blocco hanno i primi 14 caratteri uguali.
    Le celle di ogni blocco sono sequenziali per cui sono tutte vicine una dopo l'altra.
    Il quindicesimo carattere di ogni cella mi identifica la tipologia di informazione. In proposito a parte il tipo informazione 1, le altre possono apparire più di una volta o non esserci proprio (negli esempi fatti compaiono sempre almeno una volta).
    All'interno del blocco le celle sono ordinate in modo crescente per tipo informazione.
    Il resto delle celle, per cui dal carattere 16 in poi sono informazioni specifiche di quella cella.

    Detto questo, nel file excel che ho caricato trova appunto due esempi. Nel foglio uno trova i blocchi grezzi. Nel foglio due trova i blocchi grezzi con accanto i nuovi blocchi ordinati. Come vede ogni cella del tipo informazione 4 si comina una e una sola volta con quelle del tipo 3 e del tipo 2. Nel nuovo database le righe di dati dovranno comunque essere tutte consecutive, senza riche vuote. Cioè prima vanno scritte tutte le righe del blocco 1, poi quelle del 2, poi quelle del 3, In questo caso però occupano un numero di righe pari a = 1 (il tipo info 1) * N. tipo info 2 * N. Tipo info 3 * N. tipo info 4. Ad esempio nel blocco 1 sono 1*1*2*4 = 8 righe; mentre nel blocco 2 sono 1*2*4*3 = 24 righe.

    Spero che in questo modo sia più chiaro l'algoritmo di ordinamento.

    La ringrazio anticipatamente per il contributo



  • di Cucù data: 05/10/2015 14:26:19

    "Ad esempio nel blocco 1 sono 1*1*2*4 = 8 righe; mentre nel blocco 2 sono 1*2*4*3 = 24 righe. "

    Questo proprio non riesco a capirlo!



  • di Cucù data: 05/10/2015 14:31:46

    Ok, ma non capisco l'ordinamento.
    nel foglio2 per esempio blocco2 perchè la colonna "Mare" "Montagna" l'hai divisa le prime 8 righe "Mare" e le seconde 8 "Montagna" e non hai fatto per esempio alternativamente 1 mare e una montagna come hai fatto nella colonna F (marco verdi- ligabue-monnalisa)???



  • di Cucù data: 05/10/2015 14:32:41

    "Ad esempio nel blocco 1 sono 1*1*2*4 = 8 righe; mentre nel blocco 2 sono 1*2*4*3 = 24 righe. "

    Questo proprio non riesco a capirlo!
    PS ho capito mi hai confuso l'idee perchè ci sono diversi errori tra i blocchi del foglio1 e quelli del foglio2



  • di Ste.cla (utente non iscritto) data: 07/10/2015 10:08:04

    Se ci sono degli errori scusmi ma ho fatto di fretta perchè lo sto facendo nei ritagli di tempo.

    Comunque per me l'ordine delle righe non ha nessuna importanza, mi basta che ci siano tutte le combinazioni relative allo stesso blocco una in fila all'altra. Però per logica è come se avessi utilizzato dei cicli for annidati in questo modo:

    Il codice è esemplificativo

    'il tipo informazione 1 c'è sempre solo una volta, per cui non ha un ciclo dedicato
    for tipoinfo2 = 1 to §n. tipo informazione 2§
    for tipoinfo3 = 1 to §n. tipo informazione 3§
    for tipoinfo4 = 1 to §n. tipo informazione 4§
    sheets(2).cells(i, 1).value = tipoinfo1
    sheets(2).cells(i, 2).value = ennesimo tipo info 2
    sheets(2).cells(i, 3).value = ennesimo tipo info 3
    sheets(2).cells(i, 4).value = ennesimo tipo info 4
    i = i +1 'come nell'esempio descritto 2*4*3 diventano 24 righe
    Next
    Next
    Next
    Quindi come vedi vado a combinare ogni tipo informazione 4 una volta con ogni tipo informazione 3 e una volta con ogni tipo informazione 2 (il tipo informazione 1 è la chiave univoca identificativa del blocco e rimane sempre quello).

    E' un po' come con ore, minuti e secondi. hai ora 1, minuto 1 e secondo 1, quando sono passati tutti i 60 secondi scatta il minuto 2, ecc.

    Il mio problema è che se ho un blocco in cui non ho tutti i tipo informazione (ad esempio manca il 2) il mio ciclo for non funziona. Per cui devo trovare il modo di §condizionare§ i cicli for alla presenza dei relativi tipi informazioni, per cui se il tipo informazione 2 non è presente venga escluso il primo ciclo for ma non i due annidati. Altrimenti dovrei tramite istruzione if e elseif costruirmi tutti i casi. Ti preciso che questa è una semplificazione del lavoro che sto facendo che si basa in realtà su 6 tipi informazioni (scusami se non ti pubblico il vero esempio ma ci sono info riservate), per cui il numero di combinazioni non è proprio piccolo (al momento sto comunque lavorando su questa strada, appena ho del codice te lo pubblico) e mi ci vorrebbe molto tempo oltre a non essere efficiente (dovendo lavorare per migliaia di righe ho paura che sia una macro piuttosto lentina). Se riesco a trovare una soluzione con quattro tipo informazioni poi la posso facilmente replicare su 6.

    Grazie mille per il contributo



  • di Cucù data: 08/10/2015 09:41:38

    Siccome non è facile capire tutto l'ambaradan forse conviene andare per passi.
    Facciamo così posta il codice che hai scritto spiegando cosa non funziona e cosa vorresti invece ottenere come risultato finale.




  • di Ste.cla (utente non iscritto) data: 09/10/2015 16:06:32

    Buongiorno,

    riporto di seguito il codice VBA che ho prodotto. Da un primo debug e controllo dei risultati sembra funzionare tutto correttamente. La prova condotta su quasi 1 milione di righe mi ha portato a rilevare che il sistema lavora circa 4000 righe al secondo, conseguentemente per lavorarne un milione ci mette tra i 4 e i 5 minuti. Siccome dovrei aggiungere anche altre operazioni alla macro, vorrei rendere il codice più efficiente.
     
    Sub Ordinamento()
    
    
    With Application
         .EnableEvents = False
         .Calculation = xlCalculationManual
         .ScreenUpdating = False
    End With
        
        Sheets.Item(1).Activate
        Sheets.Item(1).Select
        Sheets.Item(1).Columns.NumberFormat = "@"
    
    Dim i, g, tipo5, tipo6, tipo7, tipo8, tipo9  As Integer
    i = 1
    g = 1
    
    
    Do While Not IsEmpty(Sheets(1).Cells(i, 1))                           'ciclo per far scorrere tutte le righe di input
        If Mid(Sheets(1).Cells(i, 1), 14, 1) = "1" Then                   'controllo per identificare la presenza del tipo informazione 1 che costituisce l'inizione del blocco informativo
            tipo5 = 0                                                     'azzero i contatori dei tipo informazione
            tipo6 = 0
            tipo7 = 0
            tipo8 = 0
            tipo9 = 0
            
            i = i + 1
            
            Do While Mid(Sheets(1).Cells(i, 1), 15, 20) = Mid(Sheets(1).Cells(i - 1, 1), 15, 20)   'tutti i record dati appartenti al medesimo blocco informativo hanno gli stessi caratteri nella parte iniziale della stringa (dalla posizione 15 per 20 caratteri). In questo modo ho costruito un ciclo che lavora ogni record del blocco e basta
            
                Select Case Mid(Sheets(1).Cells(i, 1), 14, 1)             'faccio contare i tipo informazione presenti
                    Case "5"
                    tipo5 = tipo5 + 1
                    Case "6"
                    tipo6 = tipo6 + 1
                    Case "7"
                    tipo7 = tipo7 + 1
                    Case "8"
                    tipo8 = tipo8 + 1
                    Case "9"
                    tipo9 = tipo9 + 1
                    Case Else
                    messaggio = MsgBox("tipo informazione sconosciuto", 0, "Record con tipo info errato - record " & i)             'versioni precedenti del data base avevano altre codifiche dei tipo informazione, questo mi dovrebbe consentire di rilevare se erroneamente sto lavorando un database vecchio.
                End Select
                i = i + 1
            Loop
        Else
        messaggio = MsgBox("La registrazione non inizia con un tipo informazione 1", 0, "Record con tipo info errato - record " & i)     'ogni blocco informazioni inizia con un tipo informazione 1 se la cella è piena e non c'è un tipo informazione 1 è errore
        End If
        
        'preciso che nei blocchi informativi i tipo informazione seguono questo ordine di priorità: 1, 7, 8, 5, 9, 6
        'i blocchi informativi possono avere due tipologie di struttura con i tipo informazioni: 1 (1), 7 (1/N), 8 (0/N), 5 (0/N), 9 (0/N)    (tra parentesi è indicata la molteplicità dei record possibile per ogni tipo informazione 1/N c'è sempre almeno una volta, 0/N il tipo informazione può anche non esserci
        'oppure: 1 (1), 7 (0/N), 9 (0/N), 6 (1/N)     (tra parentesi è indicata la molteplicità dei record possibile per ogni tipo informazione 1/N c'è sempre almeno una volta, 0/N il tipo informazione può anche non esserci
        'detto questo procedo nel seguito, sulla base delle diverse combinazioni possibili attivate con if e elseif, a costruire i cicli di ordinamento del database con scrittura della nuova versione
            
        If tipo7 > 0 And tipo8 > 0 And tipo5 > 0 And tipo9 > 0 and tipo6 = 0 Then
            For a = 1 To tipo7
                For b = 1 To tipo8
                    For c = 1 To tipo5
                        For d = 1 To tipo9
                            Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo5 - tipo8 - tipo7, 1)
                            Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo5 - tipo8 - tipo7 + a, 1)
                            Sheets(2).Cells(g, 3).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo5 - tipo8 + b, 1)
                            Sheets(2).Cells(g, 4).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo5 + c, 1)
                            Sheets(2).Cells(g, 5).Value = Sheets(1).Cells(i - 1 - tipo9 + d, 1)
                            g = g + 1
                        Next
                    Next
                Next
            Next
        ElseIf tipo7 > 0 And tipo8 > 0 And tipo5 > 0 And tipo9 = 0 and tipo6 = 0 Then
            For a = 1 To tipo7
                For b = 1 To tipo8
                    For c = 1 To tipo5
                        Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo5 - tipo8 - tipo7, 1)
                        Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo5 - tipo8 - tipo7 + a, 1)
                        Sheets(2).Cells(g, 3).Value = Sheets(1).Cells(i - 1 - tipo5 - tipo8 + b, 1)
                        Sheets(2).Cells(g, 4).Value = Sheets(1).Cells(i - 1 - tipo5 + c, 1)
                        g = g + 1
                    Next
                Next
            Next
        
        ElseIf tipo7 > 0 And tipo8 > 0 And tipo5 = 0 And tipo9 = 0 and tipo6 = 0 Then
            For a = 1 To tipo7
                For b = 1 To tipo8
                    Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo8 - tipo7, 1)
                    Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo8 - tipo7 + a, 1)
                    Sheets(2).Cells(g, 3).Value = Sheets(1).Cells(i - 1 - tipo8 + b, 1)
                    g = g + 1
                Next
            Next
    
        ElseIf tipo7 > 0 And tipo8 = 0 And tipo5 = 0 And tipo9 = 0 and tipo6 = 0 Then
            For a = 1 To tipo7
                Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo7, 1)
                Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo7 + a, 1)
                g = g + 1
            Next
    
        ElseIf tipo7 > 0 And tipo8 = 0 And tipo5 > 0 And tipo9 > 0 and tipo6 = 0 Then
            For a = 1 To tipo7
                For c = 1 To tipo5
                    For d = 1 To tipo9
                        Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo5 - tipo7, 1)
                        Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo5 - tipo7 + a, 1)
                        Sheets(2).Cells(g, 4).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo5 + c, 1)
                        Sheets(2).Cells(g, 5).Value = Sheets(1).Cells(i - 1 - tipo9 + d, 1)
                        g = g + 1
                    Next
                Next
            Next
    
        ElseIf tipo7 > 0 And tipo8 = 0 And tipo5 = 0 And tipo9 > 0 and tipo6 = 0 Then
            For a = 1 To tipo7
                For d = 1 To tipo9
                    Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo7, 1)
                    Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo7 + a, 1)
                    Sheets(2).Cells(g, 5).Value = Sheets(1).Cells(i - 1 - tipo9 + d, 1)
                    g = g + 1
                Next
            Next
    
        ElseIf tipo7 > 0 And tipo8 > 0 And tipo5 = 0 And tipo9 > 0 and tipo6 = 0 Then
            For a = 1 To tipo7
                For b = 1 To tipo8
                    For d = 1 To tipo9
                        Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo8 - tipo7, 1)
                        Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo8 - tipo7 + a, 1)
                        Sheets(2).Cells(g, 3).Value = Sheets(1).Cells(i - 1 - tipo9 - tipo8 + b, 1)
                        Sheets(2).Cells(g, 5).Value = Sheets(1).Cells(i - 1 - tipo9 + d, 1)
                        g = g + 1
                    Next
                Next
            Next
    
        ElseIf tipo7 > 0 And tipo8 = 0 And tipo5 > 0 And tipo9 = 0 and tipo6 = 0 Then
            For a = 1 To tipo7
                For c = 1 To tipo5
                    Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo5 - tipo7, 1)
                    Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo5 - tipo7 + a, 1)
                    Sheets(2).Cells(g, 4).Value = Sheets(1).Cells(i - 1 - tipo5 + c, 1)
                    g = g + 1
                Next
            Next
    
        ElseIf tipo7 > 0 And tipo9 > 0 And tipo6 > 0 and tipo5 = 0 and tipo8 = 0 Then
            For a = 1 To tipo7
                For d = 1 To tipo9
                    For e = 1 To tipo6
                        Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo6 - tipo9 - tipo7, 1)
                        Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo6 - tipo9 - tipo7 + a, 1)
                        Sheets(2).Cells(g, 5).Value = Sheets(1).Cells(i - 1 - tipo6 - tipo9 + d, 1)
                        Sheets(2).Cells(g, 6).Value = Sheets(1).Cells(i - 1 - tipo6 + e, 1)
                        g = g + 1
                    Next
                Next
            Next
    
        ElseIf tipo7 > 0 And tipo9 = 0 And tipo6 > 0 and tipo5 = 0 and tipo8 = 0 Then
            For a = 1 To tipo7
                For e = 1 To tipo6
                    Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo6 - tipo7, 1)
                    Sheets(2).Cells(g, 2).Value = Sheets(1).Cells(i - 1 - tipo6 - tipo7 + a, 1)
                    Sheets(2).Cells(g, 6).Value = Sheets(1).Cells(i - 1 - tipo6 + e, 1)
                    g = g + 1
                Next
            Next
            
        ElseIf tipo7 = 0 And tipo9 > 0 And tipo6 > 0 and tipo5 = 0 and tipo8 = 0 Then
            For d = 1 To tipo9
                For e = 1 To tipo6
                    Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo6 - tipo9, 1)
                    Sheets(2).Cells(g, 3).Value = Sheets(1).Cells(i - 1 - tipo6 - tipo9 + d, 1)
                    Sheets(2).Cells(g, 5).Value = Sheets(1).Cells(i - 1 - tipo6 + e, 1)
                    g = g + 1
                Next
            Next
        
        ElseIf tipo7 = 0 And tipo9 = 0 And tipo6 > 0 and tipo5 = 0 and tipo8 = 0 Then
            For e = 1 To tipo6
                Sheets(2).Cells(g, 1).Value = Sheets(1).Cells(i - 1 - tipo6, 1)
                Sheets(2).Cells(g, 6).Value = Sheets(1).Cells(i - 1 - tipo6 + e, 1)
                g = g + 1
            Next
    
        Else
            
        messaggio = MsgBox("Registrazione non conforme", 0, "Record con tipo info errato - record " & i - 1 - tipo5 - tipo6 - tipo7 - tipo8 - tipo9)
            
        End If
        
    Loop
    
    
    With Application
         .EnableEvents = True
         .Calculation = xlCalculationAutomatic
    End With
    
    
    End Sub



  • di Cucù data: 12/10/2015 09:10:06

    Ammazza 1 Milione di righe...
    Non sono espertissimo di Access ma con queste moli di dati forse ne varrebbe proprio la pena...
    Per quanto riguarda rendere più efficiente il codice probabilmente bisogna intervenire nel ridurre al minimo tutti quei cicli e per fare questo bisogna probabilmente cambiare l'approccio al problema.
    Spero di avere il tempo materiale per darci un'occhiata_