Newsgroup: it.comp.appl.access
Titolo: Trasposizione righe colonne

Ho fatto una ricerca ed ho trovato la seguente istruzione che potrei adattare alla mia situazione ma nonostante vari tentativi non ci sono riuscito
questa sarebbe la mia situazione:
TbPosizioni
NrPz   CodCol   Dimens
B12     700          Base
B12     710           Max
B12     730           Base
B12     740           Media
B12      750          Max
 
Vorrei ottenere:
B12  Base  700  730
B12  Max    710  750
B12  Media  740
 
Questa la funzione che vorrei adattare
 
Private Sub Transpose_Click()
Dim RS1_1 As Recordset, RS1_2 As Recordset, RS2 As Recordset
Dim SQL As String, S As String, SourceTable As String, TargetTable As
String
 
'-- Definizioni --
SourceTable = "S1"
TargetTable = "S2"
'------------------
 
SQL = "SELECT " & SourceTable & ".ID FROM " & SourceTable
SQL = SQL & " GROUP BY " & SourceTable & ".ID;"
Set RS1_1 = CurrentDb.OpenRecordset(SQL, dbOpenDynaset)
Set RS1_2 = CurrentDb.OpenRecordset(SourceTable, dbOpenDynaset)
 
Set RS2 = CurrentDb.OpenRecordset(TargetTable, dbOpenDynaset)
 
Do Until RS1_1.EOF
Do Until RS1_2.EOF
If RS1_2![ID] = RS1_1![ID] Then
S = S & RS1_2![Caratteristica] & " "
End If
RS1_2.MoveNext
Loop
RS2.AddNew
RS2![ID] = RS1_1![ID]
RS2![Caratteristica] = S
RS2.Update
S = ""
RS1_2.MoveFirst
RS1_1.MoveNext
Loop
 
Ringrazio in anticipo chiunque vorrà aiutarmi
Gabriele


Non mi piace molto questo codice e secondo me ci sono un po' di cose che non quadrano...
Ad esempio i campi inizialmente sono NrPz, CodCol, Dimens poi nel codice spunta Caratteristica
Comunque in basso trovi come lo farei io..
 
Private Sub Transpose_Click() 
Dim RS1 As Recordset, RS2 As Recordset 
Dim SQL As String, SourceTable As String, TargetTable As String 
 
SourceTable = "S1" 
TargetTable = "S2" 
 
DoCmd.RunSQL "DELETE FROM " & TargetTable 
 
SQL = "SELECT " & SourceTable & ".ID, " & SourceTable & ".Caratteristica FROM " & SourceTable 
Set RS1 = CurrentDb.OpenRecordset(SourceTable, dbOpenDynaset) 
 
Do Until RS1.EOF 
SQL = "SELECT " & TargetTable & ".ID, " & TargetTable & ".Caratteristica FROM " & TargetTable & " Where ID = " & RS1!ID
Set RS2 = CurrentDb.OpenRecordset(SQL, dbOpenDynaset) 
If RS2.EOF then
   SQL = "INSERT INTO " & TargetTable & " (ID, Caratteristica) VALUES (" & RS1!ID & "," & RS1!Caratteristica & ")"
else
   SQL = "UPDATE " & TargetTable & " SET Caratteristica = '" & RS1!Caratteristica & " " & RS2!Caratteristica & "' WHERE ID = RS1!ID
End if
DoCmd.RunSQL SQL
Loop
 
End Sub
 
 

 Comunque in basso trovi come lo farei io.. 
 
Definirei gli oggetti in modo Esplicito... DAO.Recordset, eventualmente vi siano entrambe le LIB referenziate senza aver fatto caso alla priorità.
Aprirei il RS1 in modalità ReadOnly e SnapShot, è più veloce.
 
Nel codice manca forse un MoveNext prima della chiusura del Loop...?
 
P.S. Chiudendo il tutto in una transazione diventa più performante.
 
Saluti
@Alex


MoveNext manca, certo... per le altre cose grazie! me le studio subito.

 > 
 
@Alex mi daresti un parere sul codice modificato?
L'ho cambiato un po' così per ogni ID faccio una sola query INSERT e nessun UPDATE
 
Private Sub Transpose_Click()
Dim RS1 As DAO.Recordset, RS2 As DAO.Recordset
Dim SQL As String, SourceTable As String, TargetTable As String
Dim Temp, IDTemp as string
 
SourceTable = "S1"
TargetTable = "S2"
 
Dim objCnn As ADODB.Connection
Set objCnn = CurrentProject.Connection
objCnn.BeginTrans
 
SQL = "DELETE FROM " & TargetTable
objCnn.Execute SQL, intRecAffected
IDTemp = -1
temp = ""
 
SQL = "SELECT " & SourceTable & ".ID, " & SourceTable & ".Caratteristica FROM " & SourceTable ORDER BY ID
Set RS1 = CurrentDb.OpenRecordset(SourceTable, dbOpenSnapshot, dbReadOnly) 
 
Do Until RS1.EOF
If IDTemp = RS1!ID Then
   temp = temp & " " & RS1!Caratteristica
else
   SQL = "INSERT INTO " & TargetTable & " (ID, Caratteristica) VALUES (" & IDTemp & "," & temp & ")"
   objCnn.Execute SQL, intRecAffected
   IDTemp = RS1!ID
   Temp = RS1!Caratteristica
end if
RS1.MoveNext
Loop
 
objConn.CommitTrans
End Sub

Perchè usi ADO...?
Non ha senso... 
 
La Transazione si apre cosi:
 
On Error GoTo Err_Handler
Dim mDB As DAO.Database
 
Set mDB=CurrentDb
 
DAO.DBEngine.BeginTrans
mDB.Execute "INSERT.... ", dbFailOnError
DAO.DBEngine.CommitTrans
Exit Sub/Function
 
Err_Handler:
DAO.DBEngine.Rollback
MsgBox "Transazione fallita. Error: " & Err.Description
End Sub/Function
 
La inserisci nel contesto specifico e vedrai che funziona.
@Alex


Grazie!


Ringrazio tutti per la pazienza e la disponibilità, ma non sono abbastanza ferrato da adattare il tutto alla mia situazione che sarebbe la seguente:
TbPosizioni
NrPz CodCol Dimens
B12 700 Base
B12 710 Max
B12 730 Base
B12 740 Media
B12 750 Max
 
Vorrei ottenere:
B12 Base 700 730
B12 Max 710 750
B12 Media 740
 
sarebbe molto gradito un ulteriore piccolo aiuto
  Gabriele

nel tuo caso, se non ho capito male, "ID" del mio codice corrisponde alla coppia B12 (il cui campo non penso si chiami NrPz) 
e Base/Media/Max (che non penso si chiami Dimens) 
Diciamo che i campi sono CodCol NrPz Dimens  per B12 / 700 / Dimens allora il codice diventa
quindi ID corrisponde alla coppia CodCol + Dimens
 
Private Sub Transpose_Click()
On Error GoTo Err_Handler
 
Dim mDB As DAO.Database
Dim RS1 As DAO.Recordset, RS2 As DAO.Recordset
Dim SQL As String, SourceTable As String, TargetTable As String
Dim Temp, DTemp, CCTemp as string
 
SourceTable = "TbPosizioni"
TargetTable = "TbPosizioniTrasp"
Set mDB=CurrentDb
 
DAO.DBEngine.BeginTrans
 
SQL = "DELETE FROM " & TargetTable
mDB.Execute SQL, dbFailOnError
DAO.DBEngine.CommitTrans
 
DTemp = ""
CCTemp = ""
temp = ""
 
SQL = "SELECT " & SourceTable & ".CodCol, " & SourceTable & ".Dimens, " & SourceTable & ".NrPz FROM " & SourceTable & _
" ORDER BY CodCol, Dimens"
Set RS1 = CurrentDb.OpenRecordset(SourceTable, dbOpenSnapshot, dbReadOnly)
If RS1.EOF then        'altrimenti appena entra nel ciclo parte la query di INSERT    
CCTemp = RS1!CodCol 
DTemp = RS1!Dimens 
End if
 
Do Until RS1.EOF
If CCTemp = RS1!CodCol and DTemp = RS1!Dimens Then
temp = temp & " " & RS1!NrPz
else
SQL = "INSERT INTO " & TargetTable & " (CodCol, Dimens, NrPezziTrasp) VALUES (" & CCTemp & "," & DTemp & ", " & temp & ")"
mDB.Execute SQL, dbFailOnError
CCTemp = RS1!CodCol
DTemp = RS1!Dimens
temp = RS1!NrPz
end if
RS1.MoveNext
Loop
 
DAO.DBEngine.CommitTrans
Exit Sub



Grazie Michele

È stata davvero utile. 
Ho scoperto le transazioni e ho capito finalmente DAO.
Grazie Alex!


potrebbe essere utile anche una query a campi incrociati?
 
TRANSFORM IIf(IsNull([espr1])=False,[codcol],"") AS Espr2
SELECT [nrpz] & " " & [Dimens] AS Espr1
FROM TbPosizioni
GROUP BY [nrpz] & " " & [Dimens]
PIVOT TbPosizioni.CodCol;
 
 
 
-- 
Questa e-mail è stata controllata per individuare virus con Avast antivirus.
https://www.avast.com/antivirus