web-dev-qa-db-ja.com

VBAで配列変数を宣言するにはどうすればよいですか?

配列に変数を追加する必要があります

_Public Sub Testprog()

Dim test As Variant
Dim iCounter As Integer

If test = Empty Then
    iCounter = 0
    test(iCounter) = "test"
Else
    iCounter = UBound(test)
End If
End Sub
_

test(iCounter) = "test"でエラーを取得しています

解決策を提案してください

24
Vba Dev

通常、Variantではなく、特定のタイプの変数を宣言する必要があります。この例では、test変数はString型でなければなりません。

また、配列であるため、変数を宣言するときに具体的に示す必要があります。配列変数を宣言する方法は2つあります。

  1. プログラムを作成するときに配列のサイズ(含まれる要素の数)がわかっている場合は、宣言の括弧内にその数を指定できます。

    Dim test(1) As String   'declares an array with 2 elements that holds strings
    

    このタイプの配列は、サイズが固定または静的であるため、static配列と呼ばれます。

  2. アプリケーションの作成時に配列のサイズがわからない場合は、dynamic配列を使用できます。動的配列は、サイズが宣言(Dimステートメント)で指定されていないが、ReDimステートメントを使用してプログラムの実行中に後で決定される配列です。例えば:

    Dim test() As String
    Dim arraySize As Integer
    
    ' Code to do other things, like calculate the size required for the array
    ' ...
    arraySize = 5
    
    ReDim test(arraySize)  'size the array to the value of the arraySize variable
    
32
Cody Gray

Cody Grayの答えに加えて、3番目の方法があります(そこにあるものはすべて彼女にも当てはまります)。

その場でサイズ変更されるdynamic配列を使用することもできます。

Dim test() as String
Dim arraySize as Integer

Do While someCondition
    '...whatever
    arraySize = arraySize + 1
    ReDim Preserve test(arraySize)
    test(arraySize) = newStringValue
Loop

Preserveキーワードに注意してください。それがなければ、配列を再次元化すると、すべての要素も初期化されます。

12
RolandTumble

他の人が指摘したように、問題は配列を宣言していないことです

以下では、意図したとおりに機能するようにプログラムを再作成しようとしました。可能な限り残すようにしました(配列をバリアントとして残すなど)

Public Sub Testprog()
    '"test()" is an array, "test" is not
    Dim test() As Variant
    'I am assuming that iCounter is the array size
    Dim iCounter As Integer

    '"On Error Resume Next" just makes us skip over a section that throws the error
    On Error Resume Next

    'if test() has not been assigned a UBound or LBound yet, calling either will throw an error
    '   without an LBound and UBound an array won't hold anything (we will assign them later)

    'Array size can be determined by (UBound(test) - LBound(test)) + 1
    If (UBound(test) - LBound(test)) + 1 > 0 Then
        iCounter = (UBound(test) - LBound(test)) + 1

        'So that we don't run the code that deals with UBound(test) throwing an error
        Exit Sub
    End If

    'All the code below here will run if UBound(test)/LBound(test) threw an error
    iCounter = 0

    'This makes LBound(test) = 0
    '   and UBound(test) = iCounter where iCounter is 0
    '   Which gives us one element at test(0)
    ReDim Preserve test(0 To iCounter)

    test(iCounter) = "test"
End Sub
6
Alter

Coland Grayの答えに対するRolandTumbleの答えに加えて、両方のすばらしい答えがあります。 1、10、20、および50を含む配列を作成するだけです。これもバリアント宣言を使用しますが、ReDimは使用しません。 Rolandの答えのように、配列要素の数の列挙されたカウントは特に知られている必要はありませんが、uBoundを使用して取得できます。

sub Demo_array()
    Dim MyArray as Variant, MyArray2 as Variant, i as Long

    MyArray = Array(1, 10, 20, 50)  'The key - the powerful Array() statement
    MyArray2 = Array("Apple", "Pear", "Orange") 'strings work too

    For i = 0 to UBound(MyArray)
        Debug.Print i, MyArray(i)
    Next i
    For i = 0 to UBound(MyArray2)
        Debug.Print i, MyArray2(i)
    Next i
End Sub

配列を作成する他の方法よりもこれが大好きです。すばらしいのは、Arrayステートメントで配列のメンバーをすぐに追加または削除できることです。他にコードを作成する必要はありません。 3要素の食品配列にEggを追加するには、単に入力します

、 "卵"

適切な場所で、これで完了です。食品配列には4つの要素があり、Dimでは何も変更する必要がなく、ReDimは完全に省略されています。

0ベースの配列が望ましくない場合、つまりMyArray(0)を使用する場合、1つの解決策は、その最初の要素に0または ""を詰め込むことです。

これは、コーディングの純粋主義者によってはひどく見なされる可能性があることに注意してください。 1つの公正な異議は、「ハードデータ」がルーチンのコードステートメントではなく、Constステートメントにあるべきだということです。別の牛肉は、36個の要素を配列に固定する場合、constを36に設定する必要があります。それを無視してコードを作成する必要はありません。後者の異議は、uBoundに依存するのではなく、36でConstを維持する必要があるため、議論の余地があります。 37番目の要素を追加し、Constを36のままにすると、トラブルが発生する可能性があります。

配列変数を配列として宣言する必要があります。

Dim test(10) As Variant
2
Mark Cidade