Memorizzare una Matrice in un'altra Matrice
Il problema
Chi, come me, è abituato a lavorare spesso con le Matrici, prima o poi si imbatte nella necessità di trasferire il contenuto di una Matrice in un'altra. Il motivo più ovvio per eseguire questa operazione è quella di mantenere invariati i dati memorizzati nella Matrice pur volendo eseguire su di essi delle elaborazioni.
Mi spiego meglio.
In una Matrice memorizzo i prezzi di acquisto dei singoli articoli netti dall'IVA.
Voglio controllare i prezzi che gli stessi articoli avrebbero se comprensivi di IVA senza peraltro mutare i prezzi originali.
Per compiere questa operazione è sufficiente copiare i dati della Matrice di origine in un'altra Matrice di destinazione ed eseguire su questi i nostri calcoli.
Il metodo più ovvio, ma anche più lento, è quello di leggere con un ciclo For ... Next il contenuto della prima Matrice e copiarne i valori in una seconda Matrice:
ReDim Lordo(LBound(Netto) To
UBound(Netto)) ' questo
per essere sicuri che la Matrice di destinazione
' abbia la stessa dimensione di
quella di origine
For x = LBound(Netto) To UBound(Netto)
Lordo(x) = Netto(x)
Next
In VBA e, naturalmente, in VB6, per compiere questa azione, abbiamo anche un altro metodo più veloce e più breve da scrivere:
Lordo = Netto
Per quest'ultimo metodo il problema nasce quando dobbiamo dichiarare le due variabili usate per le Matrici.
In un articolo sul VB, postato su un sito italiano, si legge: "... L'array di destinazione non deve essere di tipo Variant ... Gli array devono essere dello stesso tipo (cioè entrambi integer, entrambi string, ecc.)..."
Contrariamente a quanto si legge, per mia esperienza, è proprio ponendo a Variant la Matrice di destinazione che non si incorre in nessun errore.
Si tenga presente che una dichiarazione fatta nella forma: Dim NomeVariabile (senza dichiarare il Tipo di variabile) è assimilata per default a una variabile di tipo Variant.
Nelle verifiche comunque fatte, dopo la lettura dell'articolo su citato, sono arrivato a queste conclusioni:
la Matrice di origine può essere statica o dinamica (vedere a riguardo i miei precedenti articoli in http://ennius.interfree.it/mike/procedure/mikevba020.htm del vecchio sito e negli atri articoli presenti in questo)
la Matrice di destinazione deve essere solo dinamica
se la Matrice di origine è statica è obbligatorio dichiararla con Dim ArrayOrig(1 To 5) nella zona delle dichiarazioni
se la Matrice di origine è dinamica è obbligatoria la dichiarazione con ReDim ArrayOrig(init To fine)
entrambe le Matrici possono essere dello stesso tipo: Variant, Integer, String, ecc
Dim ArrayOrig
Dim ArrayDest
'(del tipo Variant) la dichiarazione avviene come per delle comuni
variabili
Dim ArrayOrig As
Variant
Dim ArrayDest As Variant
'anche in questo caso la dichiarazione avviene come per delle comuni
variabili
Dim ArrayOrig() As
String
Dim ArrayDest() As String
'in questo caso nella dichiarazione sono presenti le doppie
parentesi tonde
la Matrice di destinazione può essere di tipo Variant anche se la Matrice di origine è di tipo diverso
Dim ArrayOrig() As
String
Dim ArrayDest
'la Matrice di destinazione è di tipo Variant
Dim ArrayOrig() As
String
Dim ArrayDest As Variant
'anche in questo caso la Matrice di destinazione è di tipo Variant
la Matrice di destinazione non può essere di altro tipo se la Matrice di origine è di tipo Variant
Dim ArrayOrig() As
Variant
Dim ArrayDest() As String
'questa è sbagliata
Soluzione
Da queste semplici regole vi posso mostrare tre versioni diverse dello stesso esempio. In tutte memorizzo delle stringhe nella Matrice di origine e poi le copio nella Matrice di destinazione.
Per verificare l'avvenuta transazione visualizzo il contenuto della Matrice di destinazione nella finestra immediata del VBE (Visualizza / Finestra immediata).
Sub prova()
Dim ArrayOrig
Dim ArrayDest
ReDim ArrayOrig(1 To 5)
For x = 1 To 5
ArrayOrig(x) = Cells(x, 1)
Next
ArrayDest = ArrayOrig
For x = LBound(ArrayDest) To UBound(ArrayDest)
Debug.Print ArrayDest(x)
Next
End Sub
Sub prova1()
Dim ArrayOrig() As String
Dim ArrayDest() As String
ReDim ArrayOrig(1 To 5)
For x = 1 To 5
ArrayOrig(x) = Cells(x, 1)
Next
ArrayDest = ArrayOrig
For x = LBound(ArrayDest) To UBound(ArrayDest)
Debug.Print ArrayDest(x)
Next
End Sub
Sub prova3()
Dim ArrayOrig() As String
Dim ArrayDest
ReDim ArrayOrig(1 To 5)
For x = 1 To 5
ArrayOrig(x) = Cells(x, 1)
Next
ArrayDest = ArrayOrig
For x = LBound(ArrayDest) To UBound(ArrayDest)
Debug.Print ArrayDest(x)
Next
End Sub
Conclusioni
Per copiare velocemente una Matrice in un'altra possiamo agire come più ci aggrada.
prelevato sul sito www.ennius.altervista.org