수색…


배열 복사

VBA 배열을 = 연산자를 사용하여 같은 유형의 배열로 복사 할 수 있습니다. 배열은 같은 유형이어야합니다. 그렇지 않으면 코드가 "배열에 할당 할 수 없습니다"컴파일 오류가 발생합니다.

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

소스 배열은 고정되거나 동적 일 수 있지만 대상 배열은 동적이어야합니다. 고정 배열로 복사하려고하면 "배열에 할당 할 수 없습니다"라는 컴파일 오류가 발생합니다. 수신 배열의 기존 데이터가 손실되고 해당 범위와 차원이 소스 배열과 동일하게 변경됩니다.

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)

복사본이 만들어지면 두 개의 배열이 메모리에서 분리됩니다. 즉, 두 변수가 동일한 기본 데이터를 참조하지 않으므로 한 배열의 변경 사항이 다른 배열에 나타나지 않습니다.

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

객체 배열 복사하기

객체 배열을 사용하면 해당 객체에 대한 참조 가 복사되며 객체 자체는 복사되지 않습니다. 한 배열의 객체가 변경되면 다른 배열에서도 변경된 것처럼 보입니다. 두 배열은 모두 같은 객체를 참조합니다. 그러나 요소를 하나의 배열에서 다른 객체로 설정해도 그 객체에 다른 배열을 설정하지는 않습니다.

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

배열을 포함하는 변형

Variant 변수로 배열을 복사 할 수도 있습니다. 변형에서 복사 할 때 수신 배열과 동일한 유형의 배열을 포함해야합니다. 그렇지 않으면 "유형 불일치"런타임 오류가 발생합니다.

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

함수에서 배열 반환

일반 모듈 (클래스 모듈은 아님)의 함수는 데이터 유형 다음에 () 를 배치하여 배열을 반환 할 수 있습니다.

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

    arrayOfPiDigits = outputArray
End Function

그런 다음 함수의 결과를 동일한 유형 또는 변형의 동적 배열에 넣을 수 있습니다. 두 번째 대괄호를 사용하여 요소에 직접 액세스 할 수도 있지만 매번 함수를 호출하므로 두 번 이상 사용할 계획이라면 결과를 새로운 배열에 저장하는 것이 가장 좋습니다

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

반환되는 것은 실제로는 참조가 아닌 함수 내부의 배열 복사본입니다. 따라서 함수가 정적 배열의 내용을 반환하면 호출 프로 시저에서 해당 데이터를 변경할 수 없습니다.

출력 인수를 통해 배열 출력

프로 시저의 인수가 입력이되고 반환 값을 통해 출력되는 것이 일반적으로 좋은 코딩 방법입니다. 그러나 VBA의 제한으로 인해 프로 시저가 ByRef 인수를 통해 데이터를 출력 ByRef 있습니다.

고정 배열로 출력하기

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

클래스 메서드에서 배열 출력

출력 인수는 클래스 모듈의 메소드 / 프로 시저로부터 배열을 출력하는 데에도 사용할 수 있습니다

' 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

배열을 프로 시저로 전달

배열은 배열 변수의 이름 뒤에 put () 을 사용하여 프로 시저로 전달할 수 있습니다.

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

배열 참조로 전달 되어야합니다 . 전달 메커니즘이 지정되지 않은 경우 myFunction(arr()) 예 : myFunction(arr()) , VBA는 기본적으로 ByRef 를 가정하지만 명확하게 지정하는 것이 좋습니다. 예를 들어 myFunction(ByVal arr()) 값을 기준으로 배열을 전달하려고하면 VBE 옵션에서 Auto Syntax Check 가 선택되어 있지 않으면 "Array 인수가 ByRef 여야 함"컴파일 오류가 발생합니다 (또는 구문 오류가 발생합니다) .

참조로 전달한다는 것은 배열에 대한 모든 변경 사항이 호출 절차에서 보존된다는 것을 의미합니다.

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

원래 배열을 변경하지 않으려면 모든 요소를 ​​변경하지 않도록 함수를 작성해야합니다.

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

또는 배열의 작업 복사본을 만들고 복사본으로 작업하십시오.

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
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow