[MS Access] Variare struttura tabella dati

  • Creatore Discussione Creatore Discussione markusmn
  • Data di inizio Data di inizio

markusmn

Nuovo Utente
5 Apr 2018
3
0
1
Ciao a tutti. Vorrei lavorare in Access un file txt che importo in una tabella ("tabella1").

Tra i diversi campi ve ne è uno che lega i record appartenenti ad una stessa operazione. Il campo è "n_oper". Estratto tabella:

Record1: N.oper = 1 Campo1="CCN" Campo2=20 Campo3=null Campo4=null
Record2: N.oper = 2 Campo1="DAA" Campo2=10 Campo3=null Campo4=null
Record3: N.oper = 2 Campo1="EAA" Campo2=20 Campo3=null Campo4=null

Vorrei fare una routine (ciclo) che:

- mi andasse a mettere nel Campo3 del record 1 la stringa "CCN" e nel Campo4 (sempre del record 1) il valore 20.

- mi andasse a mettere nel Campo3 del record 2 la stringa "DAA","EAA" e nel Campo4 (sempre del record 2) il valore 30 (20+10).

Quindi, a parità di N.oper deve concatenare nel Campo3 le stringhe contenute nel Campo1 (DAA,EAA) e sommare nel Campo4)i valori contenuti nel Campo2 (10+20).

In pratica il contenuto dei campi di ciascuna operazione deve essere riepilogato in un unico record.

Qualcuno mi da una dritta sul come farlo? Grazie!!!!!
 
La soluzione è ceare una nuova tabella chiamata, ad esempio, tabella2 (campi: N_oper, Campo1 e Campo2) quindi creare un modulo in VBA e scrivere la seguente procedura:
Codice:
Sub ElaborazioneDati()
Dim strN_oper As String
Dim intCiclo As Integer
Dim intN_oper As Integer
Dim strCampo1 As String
Dim intCampo2 As Integer
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
    CurrentDb.Execute "DELETE * FROM tabella2"
    Set rs1 = CurrentDb.OpenRecordset("SELECT * FROM tabella1")
    If rs1.RecordCount > 0 Then
        Set rs2 = CurrentDb.OpenRecordset("SELECT * FROM tabella2")
        Do While Not rs1.EOF
            If intCiclo = 0 Then
                intN_oper = rs1!N_oper
                strCampo1 = rs1!Campo1
                intCampo2 = rs1!Campo2
            Else
                If intN_oper <> rs1!N_oper Then
                    rs2.AddNew
                    rs2!N_oper = intN_oper
                    rs2!Campo1 = strCampo1
                    rs2!Campo2 = intCampo2
                    rs2.Update
                    intN_oper = rs1!N_oper
                    strCampo1 = rs1!Campo1
                    intCampo2 = rs1!Campo2
                Else
                    strCampo1 = strCampo1 & "," & rs1!Campo1
                    intCampo2 = intCampo2 + rs1!Campo2
                End If
            End If
            intCiclo = intCiclo + 1
            rs1.MoveNext
        Loop
        rs2.AddNew
        rs2!N_oper = intN_oper
        rs2!Campo1 = strCampo1
        rs2!Campo2 = intCampo2
        rs2.Update
        rs2.Close
        Set rs2 = Nothing
    End If
    rs1.Close
    Set rs1 = Nothing
End Sub
se con il cursore ti posizioni all'interno della procedura e primi il tasto F5 verrà eseguito il codice ed aprendo la tabella2 vedrai il risultato desiderato.
 
Ultima modifica di un moderatore:
@CarlettoFed
Da regolamento del forum, come tutti noi sei tenuto ad usare il tag
code.gif
quando posti del codice, oppure la funzione codice dalla barra degli strumenti
box inserisci 2.png.JPG

Inoltre ti prego di leggere attentamente il regolamento generale del forum e quello di sezione dove posti
Grazie
Per questa volta te lo sistemo io ma mi raccomando per il futuro
 
La soluzione è ceare una nuova tabella chiamata, ad esempio, tabella2 (campi: N_oper, Campo1 e Campo2) quindi creare un modulo in VBA e scrivere la seguente procedura:
Codice:
Sub ElaborazioneDati()
Dim strN_oper As String
Dim intCiclo As Integer
Dim intN_oper As Integer
Dim strCampo1 As String
Dim intCampo2 As Integer
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
    CurrentDb.Execute "DELETE * FROM tabella2"
    Set rs1 = CurrentDb.OpenRecordset("SELECT * FROM tabella1")
    If rs1.RecordCount > 0 Then
        Set rs2 = CurrentDb.OpenRecordset("SELECT * FROM tabella2")
        Do While Not rs1.EOF
            If intCiclo = 0 Then
                intN_oper = rs1!N_oper
                strCampo1 = rs1!Campo1
                intCampo2 = rs1!Campo2
            Else
                If intN_oper <> rs1!N_oper Then
                    rs2.AddNew
                    rs2!N_oper = intN_oper
                    rs2!Campo1 = strCampo1
                    rs2!Campo2 = intCampo2
                    rs2.Update
                    intN_oper = rs1!N_oper
                    strCampo1 = rs1!Campo1
                    intCampo2 = rs1!Campo2
                Else
                    strCampo1 = strCampo1 & "," & rs1!Campo1
                    intCampo2 = intCampo2 + rs1!Campo2
                End If
            End If
            intCiclo = intCiclo + 1
            rs1.MoveNext
        Loop
        rs2.AddNew
        rs2!N_oper = intN_oper
        rs2!Campo1 = strCampo1
        rs2!Campo2 = intCampo2
        rs2.Update
        rs2.Close
        Set rs2 = Nothing
    End If
    rs1.Close
    Set rs1 = Nothing
End Sub
se con il cursore ti posizioni all'interno della procedura e primi il tasto F5 verrà eseguito il codice ed aprendo la tabella2 vedrai il risultato desiderato.

Grazie mille CarlettoFed! Provo a mettere dei commenti per capire se li interpreto correttamente:
Codice:
Sub ElaborazioneDati()
Dim strN_oper As String
Dim intCiclo As Integer
Dim intN_oper As Integer
Dim strCampo1 As String
Dim intCampo2 As Integer
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
'Ripulisco la tabella 2 da eventuali record presenti
    CurrentDb.Execute "DELETE * FROM tabella2"
'Definisco tabella1 come primo recordset
    Set rs1 = CurrentDb.OpenRecordset("SELECT * FROM tabella1")
'Se tabella1 non è vuota avvio il ciclo  
If rs1.RecordCount > 0 Then
'Definisco tabella2 come secondo recordset
        Set rs2 = CurrentDb.OpenRecordset("SELECT * FROM tabella2")
'Prevedo un ciclo che continua fino all'ultimo record di tabella1
        Do While Not rs1.EOF
'Da qui mi è poco chiaro (non a caso sono un principiante):
'se intCiclo=0 significa che N_oper (di tabella1)
'ha solo un record e per questo
'definisco le variabili con il contenuto dei campi di tabella1? 
'Mi riesci a spiegare gentilmente i passaggi successivi (che poi sono il 'cuore del problema)?
            If intCiclo = 0 Then
                intN_oper = rs1!N_oper
                strCampo1 = rs1!Campo1
                intCampo2 = rs1!Campo2
            Else
                If intN_oper <> rs1!N_oper Then
                    rs2.AddNew
                    rs2!N_oper = intN_oper
                    rs2!Campo1 = strCampo1
                    rs2!Campo2 = intCampo2
                    rs2.Update
                    intN_oper = rs1!N_oper
                    strCampo1 = rs1!Campo1
                    intCampo2 = rs1!Campo2
                Else
                    strCampo1 = strCampo1 & "," & rs1!Campo1
                    intCampo2 = intCampo2 + rs1!Campo2
                End If
            End If
            intCiclo = intCiclo + 1
            rs1.MoveNext
        Loop
        rs2.AddNew
        rs2!N_oper = intN_oper
        rs2!Campo1 = strCampo1
        rs2!Campo2 = intCampo2
        rs2.Update
        rs2.Close
        Set rs2 = Nothing
    End If
    rs1.Close
    Set rs1 = Nothing
End Sub

Grazie per la disponibilità!!!!!!
 
Ho fatto dei cambiamenti che semplificano quella di prima:
Codice:
Sub ElaborazioneDatiNew()
'La routine prevede che ad ogni record della tabella1 legga i dati e li memorizzi nelle relative variabili temporanee
'concatenando il Campo1 e sommanndo il Campo2 se ci sono più record per il campo N_oper.
'Quando N_oper cambia memorizza nella tabella 2 nei relativi campi i dati memorizzati nelle relative variabili temporanee.
Dim intN_oper As Integer
Dim strCampo1 As String
Dim intCampo2 As Integer
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
'Ripulisco la tabella 2 da eventuali record presenti
    CurrentDb.Execute "DELETE * FROM tabella2"
'Definisco tabella1 come primo recordset
    Set rs1 = CurrentDb.OpenRecordset("SELECT * FROM tabella1")
'Se tabella1 non è vuota avvio il ciclo
If rs1.RecordCount > 0 Then
'Definisco tabella2 come secondo recordset
        Set rs2 = CurrentDb.OpenRecordset("SELECT * FROM tabella2")
'memorizzo i dati del primo record nelle relative variabile temporanee
        intN_oper = rs1!N_oper
        strCampo1 = rs1!Campo1
        intCampo2 = rs1!Campo2
        rs1.MoveNext
'Prevedo un ciclo che continua fino all'ultimo record di tabella1
        Do While Not rs1.EOF
            If intN_oper <> rs1!N_oper Then
'essendo differente il valore memorizzato nella variabile intN_oper rispetto al valore nel campo rs1!N_oper aggiungo un record nella tabella2
'ed aggiorno i dati nei relativi campi
                rs2.AddNew
                rs2!N_oper = intN_oper
                rs2!Campo1 = strCampo1
                rs2!Campo2 = intCampo2
                rs2.Update
                intN_oper = rs1!N_oper
                strCampo1 = rs1!Campo1
                intCampo2 = rs1!Campo2
            Else
'se il valore memorizzato nella variabile intN_oper è uguale al valore nel campo rs1!N_oper aggiorno soltanto le variabili temporanee
'concatenando la variabile strCampo1 con il valore del campo relativo nel record attuale della tabella1 e sommando la variabile intCampo2
'con il valore del campo relativo nel record attuale della tabella1
                strCampo1 = strCampo1 & "," & rs1!Campo1
                intCampo2 = intCampo2 + rs1!Campo2
            End If
'passo al record succesivo
            rs1.MoveNext
        Loop
'essendo uscito dal ciclo memorizzo l'ultima elaborazione che era rinasta in sospeso
        rs2.AddNew
        rs2!N_oper = intN_oper
        rs2!Campo1 = strCampo1
        rs2!Campo2 = intCampo2
        rs2.Update
        rs2.Close
        Set rs2 = Nothing
    End If
    rs1.Close
    Set rs1 = Nothing
End Sub
 
Ho fatto dei cambiamenti che semplificano quella di prima:
Codice:
Sub ElaborazioneDatiNew()
'La routine prevede che ad ogni record della tabella1 legga i dati e li memorizzi nelle relative variabili temporanee
'concatenando il Campo1 e sommanndo il Campo2 se ci sono più record per il campo N_oper.
'Quando N_oper cambia memorizza nella tabella 2 nei relativi campi i dati memorizzati nelle relative variabili temporanee.
Dim intN_oper As Integer
Dim strCampo1 As String
Dim intCampo2 As Integer
Dim rs1 As DAO.Recordset
Dim rs2 As DAO.Recordset
'Ripulisco la tabella 2 da eventuali record presenti
    CurrentDb.Execute "DELETE * FROM tabella2"
'Definisco tabella1 come primo recordset
    Set rs1 = CurrentDb.OpenRecordset("SELECT * FROM tabella1")
'Se tabella1 non è vuota avvio il ciclo
If rs1.RecordCount > 0 Then
'Definisco tabella2 come secondo recordset
        Set rs2 = CurrentDb.OpenRecordset("SELECT * FROM tabella2")
'memorizzo i dati del primo record nelle relative variabile temporanee
        intN_oper = rs1!N_oper
        strCampo1 = rs1!Campo1
        intCampo2 = rs1!Campo2
        rs1.MoveNext
'Prevedo un ciclo che continua fino all'ultimo record di tabella1
        Do While Not rs1.EOF
            If intN_oper <> rs1!N_oper Then
'essendo differente il valore memorizzato nella variabile intN_oper rispetto al valore nel campo rs1!N_oper aggiungo un record nella tabella2
'ed aggiorno i dati nei relativi campi
                rs2.AddNew
                rs2!N_oper = intN_oper
                rs2!Campo1 = strCampo1
                rs2!Campo2 = intCampo2
                rs2.Update
                intN_oper = rs1!N_oper
                strCampo1 = rs1!Campo1
                intCampo2 = rs1!Campo2
            Else
'se il valore memorizzato nella variabile intN_oper è uguale al valore nel campo rs1!N_oper aggiorno soltanto le variabili temporanee
'concatenando la variabile strCampo1 con il valore del campo relativo nel record attuale della tabella1 e sommando la variabile intCampo2
'con il valore del campo relativo nel record attuale della tabella1
                strCampo1 = strCampo1 & "," & rs1!Campo1
                intCampo2 = intCampo2 + rs1!Campo2
            End If
'passo al record succesivo
            rs1.MoveNext
        Loop
'essendo uscito dal ciclo memorizzo l'ultima elaborazione che era rinasta in sospeso
        rs2.AddNew
        rs2!N_oper = intN_oper
        rs2!Campo1 = strCampo1
        rs2!Campo2 = intCampo2
        rs2.Update
        rs2.Close
        Set rs2 = Nothing
    End If
    rs1.Close
    Set rs1 = Nothing
End Sub

Spettacolo!!! Ultima cosa (spero!). Se volessi mettere un ulteriore condizione allinterno dell'Else finale (


strCampo1 = strCampo1 & "," & rs1!Campo1
intCampo2 = intCampo2 + rs1!Campo2
End If) ad esempio che se rs1!Campo1 is null non deve concatenare.... Sarebbe possibile? Mi dice loop senza do se faccio un if...then...
 
devi sostituire la riga di codice
Codice:
strCampo1 = strCampo1 & "," & rs1!Campo1
con la seguente:
Codice:
strCampo1 = strCampo1 & IIf(IsNull(rs1!Campo1),"","," & rs1!Campo1)
 

Discussioni simili