Ricerca…


Copia di array

È possibile copiare un array VBA in un array dello stesso tipo usando l'operatore = . Gli array devono essere dello stesso tipo, altrimenti il ​​codice genererà un errore di compilazione "Can not assign to array".

Dim source(0 to 2) As Long
Dim destinationLong() As Long
Dim destinationDouble() As Double

destinationLong = source     ' copies contents of source into destinationLong
destinationDouble = source   ' does not compile

L'array sorgente può essere fisso o dinamico, ma l'array di destinazione deve essere dinamico. Cercando di copiare su un array fisso si genera un errore di compilazione "Can not assign to array". Tutti i dati preesistenti nell'array di ricezione vengono persi e i relativi limiti e dimensioni vengono modificati allo stesso array di origine.

Dim source() As Long
ReDim source(0 To 2)

Dim fixed(0 To 2) As Long
Dim dynamic() As Long

fixed = source   ' does not compile
dynamic = source ' does compile

Dim dynamic2() As Long
ReDim dynamic2(0 to 6, 3 to 99) 

dynamic2 = source ' dynamic2 now has dimension (0 to 2)

Una volta eseguita la copia, i due array sono separati in memoria, ovvero le due variabili non sono riferimenti agli stessi dati sottostanti, quindi le modifiche apportate a un array non vengono visualizzate nell'altro.

Dim source(0 To 2) As Long
Dim destination() As Long

source(0) = 3
source(1) = 1
source(2) = 4

destination = source
destination(0) = 2

Debug.Print source(0); source(1); source(2)                ' outputs: 3 1 4
Debug.Print destination(0); destination(1); destination(2) ' outputs: 2 1 4

Copia di matrici di oggetti

Con le matrici di oggetti vengono copiati i riferimenti a quegli oggetti, non gli oggetti stessi. Se viene apportata una modifica a un oggetto in una matrice, sembrerà che sia stata modificata nell'altra matrice: entrambi fanno riferimento allo stesso oggetto. Tuttavia, l'impostazione di un elemento su un oggetto diverso in un array non lo imposterà sull'altro array.

Dim source(0 To 2) As Range
Dim destination() As Range

Set source(0) = Range("A1"): source(0).Value = 3
Set source(1) = Range("A2"): source(1).Value = 1
Set source(2) = Range("A3"): source(2).Value = 4

destination = source

Set destination(0) = Range("A4")   'reference changed in destination but not source

destination(0).Value = 2           'affects an object only in destination
destination(1).Value = 5           'affects an object in both source and destination

Debug.Print source(0); source(1); source(2)                  ' outputs 3 5 4
Debug.Print destination(0); destination(1); destination(2)   ' outputs 2 5 4

Varianti contenenti una matrice

È anche possibile copiare un array in e da una variabile variante. Quando si copia da una variante, deve contenere una matrice dello stesso tipo dell'array ricevente, altrimenti genererà un errore di runtime "Tipo non corrispondente".

Dim var As Variant
Dim source(0 To 2) As Range
Dim destination() As Range

var = source
destination = var

var = 5
destination = var  ' throws runtime error

Restituzione di matrici da funzioni

Una funzione in un modulo normale (ma non in un modulo di classe) può restituire un array inserendo () dopo il tipo di dati.

Function arrayOfPiDigits() As Long()
    Dim outputArray(0 To 2) As Long
    
    outputArray(0) = 3
    outputArray(1) = 1
    outputArray(2) = 4

    arrayOfPiDigits = outputArray
End Function

Il risultato della funzione può quindi essere inserito in una matrice dinamica dello stesso tipo o di una variante. È anche possibile accedere agli elementi direttamente utilizzando una seconda serie di parentesi, tuttavia questa funzione chiamerà la funzione ogni volta, quindi è meglio memorizzare i risultati in una nuova matrice se si prevede di utilizzarli più di una volta

Sub arrayExample()

    Dim destination() As Long
    Dim var As Variant
    
    destination = arrayOfPiDigits()
    var = arrayOfPiDigits
    
    Debug.Print destination(0)          ' outputs 3
    Debug.Print var(1)                  ' outputs 1
    Debug.Print arrayOfPiDigits()(2)    ' outputs 4
    
End Sub

Si noti che ciò che viene restituito è in realtà una copia dell'array all'interno della funzione, non un riferimento. Quindi se la funzione restituisce il contenuto di una matrice statica, i suoi dati non possono essere modificati dalla procedura chiamante.

Emissione di una matrice tramite un argomento di output

Normalmente è buona pratica di codifica che gli argomenti di una procedura siano input e output tramite il valore di ritorno. Tuttavia, le limitazioni di VBA talvolta rendono necessaria una procedura per l'output di dati tramite un argomento ByRef .

Emissione su una matrice fissa

Sub threePiDigits(ByRef destination() As Long)
    destination(0) = 3
    destination(1) = 1
    destination(2) = 4
End Sub

Sub printPiDigits()
    Dim digits(0 To 2) As Long
    
    threePiDigits digits
    Debug.Print digits(0); digits(1); digits(2) ' outputs 3 1 4
End Sub

Emissione di una matrice da un metodo di classe

Un argomento di output può anche essere utilizzato per generare un array da un metodo / procedimento in un modulo di classe

' Class Module 'MathConstants'
Sub threePiDigits(ByRef destination() As Long)
    ReDim destination(0 To 2)
    
    destination(0) = 3
    destination(1) = 1
    destination(2) = 4
End Sub

' Standard Code Module
Sub printPiDigits()
    Dim digits() As Long
    Dim mathConsts As New MathConstants
    
    mathConsts.threePiDigits digits
    Debug.Print digits(0); digits(1); digits(2) ' outputs 3 1 4
End Sub

Passare gli array alle procedure

Le matrici possono essere passate alle procedure mettendo () dopo il nome della variabile di matrice.

Function countElements(ByRef arr() As Double) As Long
    countElements = UBound(arr) - LBound(arr) + 1
End Function

Le matrici devono essere passate per riferimento. Se non viene specificato alcun meccanismo di passaggio, ad esempio myFunction(arr()) , VBA assumerà ByRef per impostazione predefinita, tuttavia è buona pratica di codifica renderlo esplicito. Provando a passare un array in base al valore, ad esempio myFunction(ByVal arr()) comporterà un errore di compilazione "Argomento array deve essere ByRef" (o un errore di compilazione "Errore di sintassi" se Auto Syntax Check non è selezionato nelle opzioni VBE) .

Passare per riferimento significa che eventuali modifiche alla matrice verranno mantenute nella procedura di chiamata.

Sub testArrayPassing()
    Dim source(0 To 1) As Long
    source(0) = 3
    source(1) = 1
    
    Debug.Print doubleAndSum(source)  ' outputs 8
    Debug.Print source(0); source(1)  ' outputs 6 2
End Sub

Function doubleAndSum(ByRef arr() As Long)
    arr(0) = arr(0) * 2
    arr(1) = arr(1) * 2
    doubleAndSum = arr(0) + arr(1)
End Function

Se vuoi evitare di cambiare la matrice originale, fai attenzione a scrivere la funzione in modo che non cambi alcun elemento.

Function doubleAndSum(ByRef arr() As Long)
    doubleAndSum = arr(0) * 2 + arr(1) * 2
End Function

In alternativa, crea una copia funzionante della matrice e lavora con la copia.

Function doubleAndSum(ByRef arr() As Long)
    Dim copyOfArr() As Long
    copyOfArr = arr
    
    copyOfArr(0) = copyOfArr(0) * 2
    copyOfArr(1) = copyOfArr(1) * 2
    
    doubleAndSum = copyOfArr(0) + copyOfArr(1)
End Function


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow