Mancini was thinking very hard :
> Anch'io mi sono allenato un po dei muscoletti che mi sono rimasti
>
> ho provato a rifarla totalmente senza query cross ( che non mi piacciono )
>
>
> Public Function Incrocia()
> ' testato con Access2013
> ' ( se lo usi sul 2003 devi rivedere i riferimenti )
[...]
Ho provato la tua procedura e funziona perfettamente.
Però su una tabella di Record x Campi = 1 000 000 x 32
la mia impiega 13.57 sec, la tua 688.55 sec.
Credo ci sia qualcosa da migliorare
nella sezione che t'ha fatto sudare...
Ti allego la mia così puoi fare anche tu
prove comparate di efficienza:
================================================
Public Sub Transpose_N()
'
' Access 2013/64 11-11-2013 Trasposizione.accdb
' Form: Form1 Button: Transpose (Numeric Fields)
'
' Trasposizione
' Trasforma la tabella TN_1 nella tabella TN_2, e VICEVERSA
'
' Per il VICEVERSA, cioè se ottenuta TN_2 si vuole ritornare a TN_1,
' occorre Modificare opportunamente i Valori SourceTbale e TargetTable,
ed inoltre
' occorre invertire i valori di CategorySourceField e DataSourceField.
'
' Se la prima operazione è coi parametri:
' SourceTable = "TN_1"
' TargetTable = "TN_2"
' CategorySourceField = "Prodotti"
' DataSourceField = "Clienti"
'
' l'operazione inversa saà coi parametri:
' SourceTable = "TN_2"
' TargetTable = "TN_1"
' CategorySourceField = "Clienti"
' DataSourceField = "Prodotti"
'
'
' Tabella TN_1 (SourceTable)
'
' ------ Clienti -------
'Prodotti CLI_1 CLI_2 CLI_3
'P1 147 151 56
'P2 45 78 96
'P1 63 25 78
'P3 112 89 74
'P5 113 98 74
'P1 69 78 101
'P5 166 108 90
'
' Funziona solo se i dati di SourceTable sono numerici, ancorché ZERO o
NULL
' Tabella TN_2 (TargetTable)
'
' ---- Prodotti ----
'Clienti P1 P2 P3 P5
'CLI_1 279 45 112 279
'CLI_2 254 78 89 206
'CLI_3 235 96 74 164
'
'
'
Dim db As Database, RS_Source As Recordset, T As Double
Dim i As Long, j As Long, k As Long, RS_Target As Recordset
Dim TargetTableDef As TableDef, SQL As String, RS As Recordset
Dim SourceTable As String, TargetTable As String
Dim CategorySourceField As String, DataSourceField As String
'------ Definizioni ----------
SourceTable = "TN_1"
TargetTable = "TN_2"
CategorySourceField = "Prodotti"
DataSourceField = "Clienti"
'---------------------------------
T = Timer
DoCmd.Hourglass True
Set db = CurrentDb
Set RS_Source = db.OpenRecordset(SourceTable, dbOpenDynaset)
On Error Resume Next
DoCmd.DeleteObject acTable, TargetTable
On Error GoTo 0
' Crea la nuova tabella
Set TargetTableDef = db.CreateTableDef(TargetTable)
' Crea il primo campo (text) dei record di TargetTable (quello che
indica
' i campi relazionati dal 2° all'n° in SourceTable)
TargetTableDef.Fields.Append
TargetTableDef.CreateField(DataSourceField, dbText, 255)
' Definisce i valori unici da porre in TargetTable
SQL = "SELECT " & SourceTable & "." & CategorySourceField & " FROM " &
SourceTable & " "
SQL = SQL & "GROUP BY " & SourceTable & "." & CategorySourceField & ";"
Set RS = db.OpenRecordset(SQL, dbOpenDynaset)
' Crea i campi successivi (Numeric)
Do Until RS.EOF
k = k + 1
TargetTableDef.Fields.Append
TargetTableDef.CreateField(RS(CategorySourceField), dbLong)
RS.MoveNext
Loop
db.TableDefs.Append TargetTableDef
Set RS_Target = db.OpenRecordset(TargetTable, dbOpenDynaset)
SQL = "SELECT " & SourceTable & "." & CategorySourceField & ", "
For i = 1 To RS_Source.Fields.Count - 2
SQL = SQL & "Sum(" & SourceTable & "." & RS_Source.Fields(i).Name &
") "
SQL = SQL & "AS " & RS_Source.Fields(i).Name & ", "
Next
SQL = SQL & "Sum(" & SourceTable & "." & RS_Source.Fields(i).Name & ")
"
SQL = SQL & "AS " & RS_Source.Fields(i).Name & " "
SQL = SQL & "FROM " & SourceTable & " "
SQL = SQL & "GROUP BY " & SourceTable & "." & CategorySourceField & ";"
Set RS_Source = db.OpenRecordset(SQL, dbOpenDynaset)
'SQL_TO_QUERY SQL, "Z" ' per vedere cosa fa...
' APPEND i record necessari in TargetTable compilando i campi Categoria
For i = 2 To RS_Source.Fields.Count
RS_Target.AddNew
RS_Target(0) = RS_Source(i - 1).Name
RS_Target.Update
Next
' Compila i campi Dati in TargetTable
RS_Source.MoveFirst: k = 0
RS_Target.MoveFirst: j = 0
Do Until RS_Target.EOF
j = j + 1
RS_Source.MoveFirst: k = 0
Do Until RS_Source.EOF
k = k + 1
RS_Target.Edit
RS_Target(k) = RS_Source(j)
RS_Target.Update
RS_Source.MoveNext
Loop
RS_Target.MoveNext
Loop
DoCmd.Hourglass False
MsgBox "Time = " & Timer - T
End Sub
=================================================
Bruno