Newsgroup: it.comp.appl.access
Titolo: Help per ...traposizione dati

Buongiorno a tutti. Ho un problema che mi assila da un po...
 
non riesco a trovare soluzione
 
ho una tabella che è cosi strutturata
 
 
rifmateriale	308-ND	358-ND	3510-ND	408-ND	4510-ND
1234            x
2345		X	X	X
2565	                                  X
8595		
6585                            x   
1548                                              x
9636
7845
9852			X
 
vorrei tanto ritrovarla cosi :
 
308-ND	x 1234
308-ND  x 2345
358-ND  x 2345
3510-ND x 2345
3510-ND x 6585
ect ect
 
in pratica credo si tratti di trasporre correttamente i dati.
 
nel contempo ho anche il problema inverso, ovvero passare dalla seconda tabela alla prima (sono altri dati ma la sostanza è la stessa).
E' possibile tramite VBA realizzare quanto sopra ?
Immagino di si (ci ho provato ....) e spero come sempre in una vostra illuminante soluzione.
Ringrazio !
Buon lunedi!
 
cla


Ho trovato una funzione scritta da Carlo Costarella e che a quanto pare dalla prova che ho fatto funziona (indipendentemente dal numero dei campi da trasporre)
 
Public Sub AccodaCampi()
Dim RCS As Recordset
Dim RCSCampi As Recordset, i As Long, ii As Integer
 
Set RCS = CurrentDb.OpenRecordset("TMatPomNot") 'la prima tabella
Set RCSCampi = CurrentDb.OpenRecordset("TCampi") 'la secomda tabella
 
RCS.MoveLast
RCS.MoveFirst
 
For i = 1 To RCS.RecordCount
    For ii = 1 To RCS.Fields.Count - 1
    '(- 1 perchč inizia a contare da 0) ("1 To" perchč il primo campo (0)
non ti interessa
    RCSCampi.AddNew
    RCSCampi!Campo1 = RCS!Data
    RCSCampi!Campo2 = RCS.Fields(ii)
    RCSCampi!Campo3 = RCS.Fields(ii).Name
    RCSCampi.Update
    Next ii
    RCS.MoveNext
Next i
 
RCS.Close
RCSCampi.Close
 
End Sub
 
E' corretta la mia interpretazione ?
Mi rimane sempre il problema ...inverso
 
grazie e scusate :)
 
cla

 3510-ND x 6585
 
Schiarisciti le idee.
 
Bruno
 
 

 Bruno
 

 grato ! Grazie e buona giornata a tutti Cla
 
Prova queste routine:
 
1 - Per andare da orizziontale a verticale
=============================================
Private Sub Trasposizione_HV_Click()
'
' Access 2013/64    11-11-2013    Trasposizione.accdb
' Form: Form_1    Button: Trasposizione_HV
'
Dim db As Database, SQL As String, i As Integer
Dim RS1 As Recordset, RS2 As Recordset
Dim SourceTable As String, TargetTable As String
Dim CommonField As String, DataField As String, n As Integer
Dim TargetTableDef As TableDef
 
'---  Definizioni   -----------------------------------------------
SourceTable = "Trasposizione_2"
TargetTable = "Trasposizione_3" ' TargetTable verrà creata ex-novo
CommonField = "Categoria"  ' Campo comune a SourceTable e TargetTable
DataField = "Dati"         ' Campo dati in TargetTable
n = 5                      ' numero campi Dati in SourceTable
' il campo comune (CommonField) dovrà esser in ambedue le tabelle
' il campo 0 (il primo campo).
'------------------------------------------------------------------
 
Set db = CurrentDb
Set RS1 = db.OpenRecordset(SourceTable, dbOpenDynaset)
 
' Crea TargetTable e ne definisce il Recordset (RS2)
On Error Resume Next
DoCmd.DeleteObject acTable, TargetTable
On Error GoTo 0
SQL = "CREATE TABLE " & TargetTable & _
      "(Categoria CHAR, " & _
      "Dati CHAR);"
db.Execute SQL
Set RS2 = db.OpenRecordset(TargetTable, dbOpenDynaset)
 
' Esegue la trasposizione
Do Until RS1.EOF
    For i = 1 To n
        If Not IsNull(RS1(i)) Then
            RS2.AddNew
            RS2(CommonField) = RS1(CommonField)
            RS2(DataField) = RS1(i)
            RS2.Update
        End If
    Next
    RS1.MoveNext
Loop
 
End Sub
=================================================
 
 
2 - Per andare da verticale a orizzontale
=================================================
Private Sub Trasposizione_VH_Click()
'
' Access 2013/64    11-11-2013    Trasposizione.accdb
' Form: Form_1    Button: Trasposizione_VH
'
Dim db As Database, SQL As String, i As Integer
Dim RS1 As Recordset, RS2 As Recordset, RS3 As Recordset
Dim SourceTable As String, TargetTable As String, n As Integer
Dim CommonField As String, DataField As String, RS4 As Recordset
 
'---   Definizioni   --------------------------------------------------
SourceTable = "Trasposizione_3"
TargetTable = "Trasposizione_22"    ' TargetTable verrà creata ex-novo
CommonField = "Categoria"    ' Campo comune a SourceTable e targetTable
DataField = "Dati"           ' Campo Dati in SourceTable
' il campo comune (CommonField) dovrà esser in ambedue le tabelle
' il campo 0 (il primo campo).
'----------------------------------------------------------------------
 
Set db = CurrentDb
SQL = "SELECT " & SourceTable & "." & CommonField & " FROM " & 
SourceTable & " "
SQL = SQL & "GROUP BY " & SourceTable & "." & CommonField & ";"
Set RS1 = db.OpenRecordset(SQL, dbOpenDynaset)
 
' Definisce il numero di campi da creare in Dati di TargetTable
SQL = "SELECT " & SourceTable & "." & CommonField & " "
SQL = SQL & "FROM " & SourceTable & " GROUP BY " & SourceTable & "." & 
CommonField & ";"
Set RS4 = db.OpenRecordset(SQL, dbOpenDynaset)
RS4.MoveLast
n = RS4.RecordCount ' numero campi da creare in Dati di TargetTable
 
' Crea TartgetTable
On Error Resume Next
DoCmd.DeleteObject acTable, TargetTable
On Error GoTo 0
SQL = "CREATE TABLE " & TargetTable & " (" & CommonField & " CHAR, "
For i = 1 To n - 1
    SQL = SQL & DataField & "_" & i & " CHAR, "
Next
SQL = SQL & DataField & "_" & i & " CHAR);"
db.Execute SQL
Set RS2 = db.OpenRecordset(TargetTable, dbOpenDynaset)
 
' Esegue la trasposizione
Do Until RS1.EOF
    RS2.AddNew
    RS2(CommonField) = RS1(CommonField)
    i = 0
    SQL = "SELECT " & SourceTable & ".* FROM " & SourceTable & " "
    SQL = SQL & "WHERE " & SourceTable & "." & CommonField & "='" & 
RS1(CommonField) & "';"
    Set RS3 = db.OpenRecordset(SQL, dbOpenDynaset)
    Do Until RS3.EOF
        i = i + 1
        RS2(CommonField) = RS3(CommonField)
        RS2(i) = RS3(DataField)
        RS3.MoveNext
    Loop
    RS2.Update
    RS1.MoveNext
Loop
 
End Sub
=================================================================
 
Bruno
 
 

 Bruno
 
Grazie infinite Bruno, adesso provo le tue soluzioni.
Certo è che mi hai dato un grandissimo aiuto, non sapevo proprio come uscirne.
Mi metto all'opera non prima di averti augurato una buona giornata!
Grazie ancora 
cla


Bruno, di nuovo ciao, ho provato la prima tua routine, e funziona perfettamente.
Ho fatto una modifica per ottenere i nomi dei campi (sempre in orizzontale) :
 
' Access 2013/64    11-11-2013    Trasposizione.accdb
' Form: Form_1    Button: Trasposizione_HV
'
Dim db As Database, SQL As String, i As Integer
Dim RS1 As Recordset, RS2 As Recordset
Dim SourceTable As String, TargetTable As String
Dim CommonField As String, DataField As String, n As Integer
Dim TargetTableDef As TableDef
 
'---  Definizioni   -----------------------------------------------
SourceTable = "S2"
TargetTable = "Trasposizione_3" ' TargetTable verrà creata ex-novo
CommonField = "Categoria"  ' Campo comune a SourceTable e TargetTable
DataField = "Dati"         ' Campo dati in TargetTable
DataField1 = "Modello"     ' Campo dati in TargetTable 'campo aggiunto
 
n = 12                      ' numero campi Dati in SourceTable
' il campo comune (CommonField) dovrà esser in ambedue le tabelle
' il campo 0 (il primo campo).
'------------------------------------------------------------------
 
Set db = CurrentDb
Set RS1 = db.OpenRecordset(SourceTable, dbOpenDynaset)
 
' Crea TargetTable e ne definisce il Recordset (RS2)
On Error Resume Next
DoCmd.DeleteObject acTable, TargetTable
On Error GoTo 0
SQL = "CREATE TABLE " & TargetTable & _
      "(Categoria CHAR, " & "Dati CHAR, " & "Modello CHAR);" aggiunto campo per tabella Trasposizione_3 
db.Execute SQL
Set RS2 = db.OpenRecordset(TargetTable, dbOpenDynaset)
 
' Esegue la trasposizione
Do Until RS1.EOF
    For i = 1 To n
        If Not IsNull(RS1(i)) Then
            RS2.AddNew
            RS2(CommonField) = RS1(CommonField)
            RS2(DataField) = RS1(i)
            RS2(DataField1) = RS1(i).Name ' per ottenere il nome dei campi in tabella Trasposizione_3
            RS2.Update
        End If
    Next
    RS1.MoveNext
Loop
 
End Sub
 
Ritieni sia corretto secondo te ? e se si per la trasposizione Verticale/orizzontale seguo la stessa logica ?
Scusa di nuovo il disturbo :)
Cla

gro cl explained on 14-11-13 :

Non so a che serva quel campo aggiunto, quali valori debba accogliere.
Se fai delle modifiche a un programma, poi convien che tu lo esegua per 
verificare ciò che succede.
Che cosa aspetti a farlo?
 
La trasposizione VH segue una logica specularmente invertita... deve 
eseguire l'operazione inversa!
 
Bruno
 
 

 Bruno
 
Ciao Bruno e grazie della tua risposta.
Ho aggiunto un campo perchè, come da primo topic, la tabella aveva la necessità di riportare anche i nomi dei campi in verticale, naturalmente l'ho verificata e a quanto pare fa il suo dovere :).
Seguirò, come da te suggerito, la stessa logica in quella da verticale a orizzontale.
Ciao e grazie !
cla