VBA 配列

Written by

Editorial Team

Reviewed by

Steve Rynearson

Translated by

masahiro yoshida

Last updated on 4月 26, 2022

VBAでは、配列は複数の値を保持することができる単一の変数です。 配列は、セルの範囲のようなものだと考えてください。配列は、1次元(1つの列を考える)、2次元(複数の行と列を考える)、または多次元にすることができます。 配列の値は、配列内の位置(インデックス番号)でアクセスすることができます。

VBA配列クイックシート

配列

説明
VBAコード
作成する
Dim arr(1 To 3 ) As Variant
arr(1) = “one”
arr(2) = “two”
arr(3) = “three”
Excelから作成する
Dim arr(1 To 3 ) As Variant
Dim cell As Range, i As Integer
i = LBound(arr)
For Each cell In Range(“A1:A3”)
i = i + 1
arr(i) = cell.value
Next cell
全項目を読み込む
Dim i as Long
For i = LBound(arr) To UBound (arr)
MsgBox arr(i)
Next i
消去する
Erase arr
配列を文字列へ変換する
Dim sName As String
sName = Join(arr, “:”)
サイズを大きくする
ReDim Preserve arr(0 To 100)
値を設定する
arr(1) = 22

VBAの配列の例

具体的な説明に入る前に、完全な例を見てみましょう。

Sub ArrayExample()
    Dim strNames(1 to 4) as String

    strNames(1) = "シェリー".
    strNames(2) = "スティーブ"
    strNames(3) = "ニーマ"
    strNames(4) = "ホセ"

    msgbox strNames(3)
End Sub

ここでは、サイズ4(4つの値を格納できる)の1次元文字列配列:strNamesを作成し、4つの値を代入しています。最後に、3番目の値をメッセージボックスに表示しています。 この場合、配列の使用によるメリットは小さく、4つの変数宣言の代わりに1つの変数宣言が必要なだけです。

では、配列の真の力を示す例を見てみましょう。

Sub ArrayExample2()
    Dim strNames(1 To 60000) As String
    Dim i As Long

    For i = 1 To 60000
        strNames(i) = Cells(i, 1).Value
    Next i
End Sub

ここでは、6万個の値を格納できる配列を作成し、ワークシートのA列から素早く配列に代入しています。

配列の利点は? – スピード!

配列はExcelのワークシートに似ていると思われるかもしれません。

  • 各セル(または配列の項目)ごとに値を設定することができる
  • 各セル(または配列の項目)は、その行と列の位置でアクセスできる。
    • ワークシートの例:cells(1,4).value = “1行目、4列目”
    • 配列の例:arrVar(1,4) = “1行目、4列目”

では、なぜわざわざ配列なのでしょうか? Excelのセルに直接値を読み書きすればいいのでは? 一言で言えば、「速い」のです。 Excelのセルへの読み書きは時間がかかります。それに比べると配列の方がはるかに速いのです。

配列の作成と宣言

注意: 配列は複数の「次元」を持つことができます。注意:配列は複数の「次元」を持つことができますが、ここではシンプルにするため、1次元の配列のみを扱います。このチュートリアルの後半で、複数次元の配列について紹介します。

静的な配列

静的配列は、サイズを変更することができない配列です。逆に、動的な配列はサイズを変更することができます。 宣言の仕方も少し違います。まず、静的配列について見てみましょう。

注意:もし配列のサイズが変わらないのであれば、静的な配列を使いましょう。

静的配列変数の宣言は、通常の変数の宣言とほとんど変わりませんが、配列のサイズを定義する必要があります。配列のサイズを指定する方法にはいくつか種類があります。

Sub StaticArray1()

    '添字が 1,2,3,4 の配列を作成する
    Dim arrDemo1(1 To 4) As String
    
    '添字が 4,5,6,7 の配列を作成する
    Dim arrDemo2(4 To 7) As Long
    
    '添字が 0,1,2,3 の配列を作成する
    Dim arrDemo3(0 To 3) As Long

End Sub

また、配列のサイズだけを入力することもできます。

Sub StaticArray2()

    '添字が 0,1,2,3 の配列を作成する
    Dim arrDemo1(3) As String

End Sub

重要!配列はデフォルトで0から始まるので、Dim arrDemo1(3)は 0,1,2,3 の添字を持つ配列を作成することに注意してください。 モジュールの先頭でOption Base 1を宣言すれば、配列が 1 の位置から始まるようになります。

Option Base 1

Sub StaticArray3()

    '添字 1,2,3 を持つ配列を作成します。
    Dim arrDemo1(3) As String

End Sub

しかし、配列の開始位置と終了位置を明示的に宣言する方が、はるかに簡単で、混乱も少ないと思います。

動的な配列

動的な配列は、サイズが変更可能な(あるいはサイズを定義する必要のない)配列です。 動的配列の宣言方法は2通りあります。

Variant型配列

動的な配列を宣言する最初の方法は、配列の型をVariant型に設定することです。

Dim arrVar() As Variant

Variant型配列では、配列のサイズを定義する必要はありません。サイズは自動的に調整されます。 ただ、配列は添字は0から始まることを覚えておいてください。(モジュールのトップにOption Base 1を追加していない限り。)

Sub VariantArray()
    Dim arrVar() As Variant
    
    '値の定義 (添字= 0,1,2,3)
    arrVar = Array(1, 2, 3, 4)
    
    '値の変更(添字=0,1,2,3,4)
    arrVar = Array("1a", "2a", "3a", "4a", "5a")。

    '位置4のを出力("5a")
    MsgBox arrVar(4)

End Sub

非Variant型の動的配列

非Variant型の配列では、配列に値を代入する前に、配列のサイズを定義する必要があります。ただし、配列を作成する処理は少し異なります。

Sub DynamicArray1()
    Dim arrDemo1() As String

    '位置1,2,3,4で配列のサイズを変更する
    ReDim arrDemo1(1 To 4)
    
End Sub

まず、配列のサイズを省略する以外は、静的配列と同じように配列を宣言します。

Dim arrDemo1() As String

配列のサイズを設定する場合は、ReDimコマンドを使用して配列のサイズを設定します。

'配列のサイズを 1,2,3,4 の位置で変更します。
ReDim arrDemo1(1 To 4)

ReDimは配列のサイズを変更します。ReDimとReDim Preserveの違いについては、以下をお読みください。

ReDimとReDim Preserveの比較

ReDimコマンドを使用すると、配列から既存の値をすべて消去します。 代わりに、ReDim Preserveを使用すると、配列の値を保持することができます。

'位置1,2,3,4で配列のサイズを変更する(既存の値を保持する)
ReDim Preserve arrDemo1(1 To 4)

配列の宣言の簡略化

上記の内容を読んで、あなたは圧倒されたように感じるかもしれません。そこで、この後は静的な配列を使って説明します。

配列の値を設定する

配列の値を設定するのはとても簡単です。 静的配列の場合、配列の各位置を一度に定義する必要があります。

Sub ArrayExample()
    Dim strNames(1 to 4) as String

    strNames(1) = "シェリー".
    strNames(2) = "スティーブ"
    strNames(3) = "ニーマ"
    strNames(4) = "ホセ"
End Sub

Variant型配列では、1行で配列全体を定義することができます。(小さな配列の場合のみ実用的です。)

Sub ArrayExample_1Line()
    Dim strNames() As Variant

    strNames = Array("シェリー", "スティーブ", "ニーマ", "ホセ")

End Sub

存在しない配列の位置に値を定義しようとすると、「Subscript Out of Range」エラーが発生します。

strNames(5) = "シャノン"

vba set array value 配列 エラー

以下、「セルの範囲を配列に代入する」では、ループを使って大量の値を素早く配列に代入する方法を紹介します。

配列の値の取得

配列の値も同じように取得することができます。 以下の例では、配列の値をセルに書き込んでいます。

    Range("A1").Value = strNames(1)
    Range("A2").Value = strNames(2)
    Range("A3").Value = strNames(3)
    Range("A4").Value = strNames(4)

セルの範囲を配列に代入する

範囲を配列に代入するには、ループを使用します。

Sub RangeToArray()
    Dim strNames(1 To 60000) As String
    Dim i As Long

    For i = 1 To 60000
        strNames(i) = Cells(i, 1).Value
    Next i
End Sub

これは、セルA1:A60000をループして、セルの値を配列に代入しています。

配列から範囲への出力

また、ループを使って、配列をセルの範囲に代入することもできます。

    For i = 1 To 60000
       Cells(i, 1).Value = strNames(i)
    Next i

これは先の例とは逆に、配列の値をセルA1:A60000に代入することになります。

2次元・多次元配列

これまで、1次元の配列だけを扱ってきました。 しかし、配列は最大で32次元まで持つことができます。 1次元配列はExcelのセル1行や1列、2次元配列は複数の行と列を持つExcelワークシート全体、3次元配列は複数の行と列を持つシートを含むワークブック全体と考えてください(3次元配列はルービックキューブのようなものだとも言えます)。

多次元配列の例

次に、異なる次元の配列を扱う例を示します。

1次元配列の例

このプロシージャは、これまでの配列の例を1つのプロシージャにまとめ、実際の配列の使い方を示しています。

Sub ArrayEx_1d()
    Dim strNames(1 To 60000) As String
    Dim i As Long
 
    '配列に値を代入する
    For i = 1 To 60000
        strNames(i) = Cells(i, 1).Value
    Next i
    
    '配列の値を範囲に出力する
    For i = 1 To 60000
        Sheets("Output").Cells(i, 1).Value=strNames(i)。
    Next i
End Sub

2次元配列の例

このプロシージャには、2次元配列の例が含まれています。

Sub ArrayEx_2d()
    Dim strNames(1 To 60000, 1 To 10) As String
    Dim i As Long, j As Long
 
    '配列に値を割り当てる
    For i = 1 To 60000
        For j = 1 To 10
            strNames(i, j) = Cells(i, j).Value
        Next j
    Next i
    
    '配列の値を範囲に出力する
    For i = 1 To 60000
        For j = 1 To 10
            Sheets("Output").Cells(i, j).Value = strNames(i, j)
        Next j
    Next i
End Sub

3次元配列の例

このプロシージャには、複数のシートを操作するための3次元配列の例が含まれています。

Sub ArrayEx_3d()
    Dim strNames(1 To 60000, 1 To 10, 1 To 3) As String
    Dim i As Long, j As Long, k As Long
 
    '配列に値を代入する
    For k = 1 To 3
        For i = 1 To 60000
            For j = 1 To 10
                strNames(i, j, k) = Sheets("Sheet" & k).Cells(i, j).Value
            Next j
        Next i
    Next k
    
    '配列の値を範囲に出力する
    For k = 1 To 3
        For i = 1 To 60000
            For j = 1 To 10
                Sheets("Output" & k).Cells(i, j).Value = strNames(i, j, k)
            Next j
        Next i
    Next k
End Sub

配列の長さ・サイズ

これまで、さまざまな種類の配列について紹介し、配列の宣言方法と配列の値の取得/設定方法を説明しました。次に、配列を扱うために必要なその他のトピックに焦点を当てます。

UBound関数とLBound関数

配列の長さ/サイズを取得する最初のステップは、UBound関数とLBound関数を使用して配列の上下の境界を取得することです。

Sub UBoundLBound()
    Dim strNames(1 To 4) As String
    
    MsgBox UBound(strNames)
    MsgBox LBound(strNames)
End Sub

2つの値の差に1を足し、長さを求めます。

GetArrLength = UBound(strNames) - LBound(strNames) + 1

配列の長さ関数

1次元の配列の長さを求める関数を以下に示します。

Public Function GetArrLength(a As Variant) As Long
   If IsEmpty(a) Then
      GetArrLength = 0
   Else
      GetArrLength = UBound(a) - LBound(a) + 1
   End If
End Function

2次元配列のサイズを計算する必要がありますか?次のチュートリアルをご覧ください:配列のサイズを計算する

配列のループ処理

配列の中をループする方法は2つあります。 ひとつは、配列の番号の位置に対応する整数をループする方法です。配列のサイズがわかっている場合は、サイズを直接指定することができます。

Sub ArrayExample_Loop1()
    Dim strNames(1 To 4) As String
    Dim i As Long

    strNames(1) = "シェリー".
    strNames(2) = "スティーブ"
    strNames(3) = "ニーマ"
    strNames(4) = "ホセ"
    
    For i = 1 To 4
        MsgBox strNames(i)
    Next i
End Sub

ただし、配列のサイズがわからない場合(配列が動的な場合)には、前節のLBound関数とUBound関数を使用することができます。

Sub ArrayExample_Loop2()
    Dim strNames(1 To 4) As String
    Dim i As Long

    strNames(1) = "シェリー"
    strNames(2) = "スティーブ"
    strNames(3) = "ニーマ"
    strNames(4) = "ホセ"
    
    For i = LBound(strNames) To UBound(strNames)
        MsgBox strNames(i)
    Next i
End Sub

For Eachによる配列のループ

2つ目の方法は、For Eachループを使う方法です。これは、配列の各項目をループします。

Sub ArrayExample_Loop3()
    Dim strNames(1 To 4) As String
    Dim Item

    strNames(1) = "シェリー"
    strNames(2) = "スティーブ"
    strNames(3) = "ニーマ"
    strNames(4) = "ホセ"
    
    For Each Item In strNames
        MsgBox Item
    Next Item
End Sub

For Eachによる配列のループは、1次元配列だけでなく、多次元配列でも動作します。

2次元配列のループ処理

UBound関数とLBound関数を使って、多次元配列をループ処理することもできます。この例では、2次元配列の中をループします。 UBound関数とLBound関数では、上限と下限を求める配列の次元を指定できます。(1次元は1、2次元は2)

Sub ArrayExample_Loop4()
    Dim strNames(1 To 4, 1 To 2) As String
    Dim i As Long, j As Long

    strNames(1, 1) = "シェリー"
    strNames(2, 1) = "スティーブ"
    strNames(3, 1) = "ニーマ"
    strNames(4, 1) = "ホセ"
    
    strNames(1, 2) = "シェルビー"
    strNames(2, 2) = "スティーブン"
    strNames(3, 2) = "ニモ"
    strNames(4, 2) = "ジェシー"
    
    For j = LBound(strNames, 2) To UBound(strNames, 2)
        For i = LBound(strNames, 1) To UBound(strNames, 1)
            MsgBox strNames(i, j)
        Next i
    Next j
End Sub

その他の配列タスク

配列のクリア

配列全体を消去するには、Eraseステートメントを使用します。

Erase strNames

使用例:

Sub ArrayExample()
    Dim strNames(1 to 4) as String

    strNames(1) = "シェリー"
    strNames(2) = "スティーブ"
    strNames(3) = "ニーマ"
    strNames(4) = "ホセ"

    Erase strNames
End Sub

また、配列の一部を消去して、サイズを変更するReDimも可能です。

ReDim strNames(1 to 2)

これは、配列のサイズを2に変更し、3番目と4番目の要素を削除しています。

配列のカウント

前述のUBound関数とLBound関数を使って、配列の各次元のサイズを得ることができます。 また、入力された項目(または特定の条件を満たす項目)の数を数えるには、配列の中をループさせます。

この例では、オブジェクトの配列をループして、その中で見つかった空白でない文字列の数を数えます。

Sub ArrayLoopandCount()
    Dim strNames(1 To 4) As String
    Dim i As Long, n As Long

    strNames(1) = "シェリー"
    strNames(2) = "スティーブ"
    
    For i = LBound(strNames) To UBound(strNames)
        If strNames(i) <> "" Then
            n = n + 1
        End If
    Next i
    
    MsgBox n & " 個の空白でない値が見つかりました。"
End Sub

重複の除去

ある時点で、配列から重複を削除したくなることがあります。残念ながら、VBAにはこれを行うためのビルトインの機能がありません。しかし、配列から重複を削除する関数を作成しました(長すぎるので、このチュートリアルでは紹介しませんが、詳細はリンク先をご覧ください)。

Filter

VBAのFilter関数を使うと、配列にフィルタをかけることができます。これは、フィルタリングされた値のみを含む新しい配列を作成することによって行われます。 下記は簡単な例ですが、様々なニーズに対応するため、より多くの例について記事を読むようにしてください。

Sub Filter_Match()
 
    '配列を定義する
    Dim strNames As Variant
    strNames = Array("スティーブ・スミス", "シャノン・スミス", "ライアン・ジョンソン")
    '配列をフィルタする
    Dim strSubNames As Variant
    strSubNames = Filter(strNames, "スミス")
    'フィルタされた配列を数える
    MsgBox UBound(strSubNames) - LBound(strSubNames) + 1 & " 名の名前が見つかりました。"
 
End Sub

IsArray関数

変数が配列かどうかを調べるには、IsArray Functionを使用します。

Sub IsArrayEx()

    '配列を作成する
    Dim arrDemo1(3) As String
    
    '通常の文字列変数を作成する
    Dim str As String
    
    MsgBox IsArray(arrDemo1)
    MsgBox IsArray(str)

End Sub

配列の結合

Join関数を使って、配列全体をすばやく「結合」することができます。

Sub Array_Join()
    Dim strNames(1 To 4) As String
    Dim joinNames As String

    strNames(1) = "シェリー"
    strNames(2) = "スティーブ"
    strNames(3) = "ニーマ"
    strNames(4) = "ホセ"
    
    joinNames = Join(strNames, ",")
    MsgBox joinNames
End Sub

文字列を配列に分割する

VBAのSplit関数は、文字列を元の文字列から値を含む配列に分割します。例を見てみましょう。

Sub Array_Split()
    Dim Names() As String
    Dim joinedNames As String
    
    joinedNames = "シェリー,スティーブ,ニーマ,ホセ"
    Names = Split(joinedNames, ",")

    MsgBox Names(1)
End Sub

ここでは、”シェリー,スティーブ,ニーマ,ホセ”という文字列をカンマ区切り(”,”)でサイズ4の配列に分割しています。

配列定数

VBAでは、配列を定数として宣言することが出来ません。しかし、Arrayとして使用する関数を作成することで、これを回避することができます。

' ConstantArrayを定義
Function ConstantArray()
    ConstantArray = Array(4, 12, 21, 100, 5)
End Function

' ConstantArrayの値を取得
Sub RetrieveValues()
    MsgBox ConstantArray(3)
End Sub

vba const array 定数 配列

配列のコピー

VBAを使用して、配列をコピーするビルトインの機能はありません。ある配列から別の配列に値を割り当てるためには、ループを使用する必要があります。

Sub CopyArray()

    Dim Arr1(1 To 100) As Long
    Dim Arr2(1 To 100) As Long
    Dim i As Long
    
    '配列に初期値を代入
    For i = 1 To 100
        Arr1(i) = i
    Next i
    
    'Arr1からArr2へコピー
    For i = 1 To 100
        Arr2(i) = Arr1(i)
    Next i
    
    MsgBox Arr2(74)

End Sub

転置

VBAのビルトイン関数には、配列を転置する関数はありません。しかし、2次元の配列をTransposeする関数を書きました。詳しくは、記事を読んでください。

返り値が配列の関数

VBAの開発者がよく抱く疑問は、配列を返す関数をどのように作成するかということです。ほとんどの困難は、変量配列を使用することで解決されると思います。このトピックに関する記事を書きました。こちらをご覧ください:返り値が配列の関数

Access VBAで配列を使う

上記の配列の例のほとんどは、Access VBAでもExcel VBAと全く同じように動作します。 一つ大きな違いは、Accessのデータを使って配列を生成する場合、RangeオブジェクトではなくRecordSetオブジェクトをループする必要があることです。

Sub RangeToArrayAccess()
   On Error Resume Next
   Dim strNames() As String
   Dim i As Long
   Dim iCount As Long
   Dim dbs As Database
   Dim rst As Recordset
   Set dbs = CurrentDb
   Set rst = dbs.OpenRecordset("tblClients", dbOpenDynaset)
   With rst
      .MoveLast
      .MoveFirst
      iCount = .RecordCount
      ReDim strNames(1 To iCount)
      For i = 1 To iCount
         strNames(i) = rst.Fields("ClientName")
         .MoveNext
      Next i
   End With
   rst.Close
   Set rst = Nothing
   Set dbs = Nothing
End Sub

[テーブル id=21 row_highlight=”YES” /].

vba-free-addin

VBA Code Examples Add-in

Easily access all of the code examples found on our site.

Simply navigate to the menu, click, and the code will be inserted directly into your module. .xlam add-in.

(No installation required!)

Free Download

Return to VBA Code Examples