【VBA基礎】配列(Array)とは? - 使い方や実例を画像付き解説

配列記事トップ画像

VBAの初心者にとって、「配列」は必ず乗り越えなければいけない壁。(最初は私も理解に苦しみました💦 )

しかし「習うより慣れよ」という言葉こそ、配列の理解にあたって最適なアドバイスだとも言えます。

この記事では配列の基礎を最短で理解できるよう、簡単な実例を踏まえてわかりやすくお教えします。

最速で理解!配列は「複数の値を入れられる変数」!

配列について解説する多くの記事では、「物をしまっておけるいくつかの箱が配列のイメージである」と説明されています。

筆者は正直なところ、これ系の説明ではまったくイメージできませんでした。
よって、もしあなたも似たような説明で配列をイメージできないなら、その説明は一切忘れてください。謎の箱をイメージするだけ無駄です。

以下の具体例を見ていただくとさらにイメージが明確になるでしょう。

【普通の変数】
普通の変数を使う時のコード画像

【配列】配列を使う時のコード画像

普通の変数と配列変数は、変数の宣言時からして大きな違いがあります。

普通の変数と配列変数の宣言の違い画像

普通の変数は、変数名とデータ型を指定して終わりです。しかし配列変数は、変数名のあとに「(9)」という謎の数字が付いていますね。

この (9) という部分を「添え字」または「インデックス」と言い、配列に入れられるデータの最大数を指します。

つまり配列変数を宣言するときは、「この配列には何個のデータを入れられますよ」と示さなければいけません。画像では (9) となっていますので、「この配列には最大で10個のデータを格納するよ!」と宣言しているというわけです。

当然、 (99) とすれば100個のデータを入れられるし、(1) としたら2個のデータしか入れられません。

「(9) ならデータを入れられる最大数は9個では?」 NO! 配列は0から始まる

慣れるのに少しだけ時間を要しますが、「配列は0から始まる」という大事なルールがあります。

つまり先ほどの「配列(9)」という宣言では10個のデータを入れられる変数を宣言したということです。

ほかのプログラミング言語においても配列という概念は共通して0から始まりますが、その理由を説明するととても長くなります。 よって配列の概念や使いかたを覚える今の段階では、「そういうもの」として覚えるにとどめましょう。

さてさて幸手。

なんで配列について学ぶ必要があるんでしょうか。
配列の何が便利なんでしょうか。

配列の最大のメリット「データの一括処理」と「処理スピード」!

VBAに限らず、プログラミングにおいて処理の軽さやスピードというのはすごく重要です。

その大事さを実感してもらうため、処理スピードのテストをしてみた結果をご覧ください。

【スピードテストの内容】

Sheet1にある10,000個のデータをSheet2に書き写す

スピードテストの内容画像

【実行方法】

  1. 一般的(?)な方法:Sheet1のセルをコピーして、Sheet2の同じセルにペーストする × 1万回
  2. 配列による方法:1万個の文字を配列に格納して、配列に格納した1万個の値をSheet2に入力していく

「少しだけVBAに慣れてきたかな」というかたなら、「1.」の方法を真っ先に思いつくのではないでしょうか。

コードの中身はさておいて、とりあえずスピードテストの結果をご覧ください。絶対に驚きますよ。

スピードテストの結果画像

一般的な方法による処理では、約4分もの時間がかかりました。 対する配列を使用したケースでは、なんと1秒かかりませんでした。

あまりの差に「嘘……だろ…?」と感じますが、本当のことです。

この約4分と1秒未満という処理速度の差を、「早いか遅いか」という単純な結果だけで捉えるべきではないでしょう。この速度の差は、VBA実行時における「パソコンへの負担」「メモリ領域の不必要な占有」でもあります。
状況によっては他のソフトウエアやアプリに悪影響を及ぼす可能性があるということです。

よって「え~、別にそんなにたくさんデータの処理しないし」ということであっても、配列は使用できるようになったほうがいいです。

データ処理において、もはやそのメリットを語るまでもなく配列を使うべきというのがお分かりいただけるのではないでしょうか。

【ルールはたった3つ】配列の使いかた・使いどころ

では、配列の超基本の使いかたです。

VBAの配列は、たった3つの基本ルールさえ覚えれば簡単に使えます。

配列の使いかた画像

ただ実際に配列を活用する際は、画像のような使いかたはしません。(そんなんやってる人、見たことないです)

そこで少し実践に近い配列の使いかたを見てみましょう。超便利ですよ。

【実践例】配列の使いどころ:配列はループ処理で真価を発揮する

配列は「一括処理が可能」「処理が超高速」という2つがメリットとお伝えしました。

では実際に配列がどういう場面で活躍するのか、具体例で見てみましょう。

実践例の実行前画像

Private Sub 印刷用シート入力ボタン_Click()
    Dim PL(260) As Long     '配列の宣言(261日分なので0~260までのインデックスを設定)
    Dim i As Integer        '配列のインデックスを更新するための変数
    Dim j As Integer        'セルの行数用の変数

'******① 毎日の収支を配列に格納する********************************************
  j = 2  'セルの行数用の変数を初期化(収支入力シートの2行目から開始するので)
    For i = 0 To 260
        PL(i) = ThisWorkbook.Worksheets("収支入力").Cells(j, 2)     '収支入力表の j 行2列目の値を配列に格納
        j = j + 1
    Next i

'******②配列に格納した値をプラスかマイナスかで制御して印刷用シートに入力********
  j = 2  'セルの行数用の変数をもう一度初期化(印刷用シートの2行目から入力するので)
    For i = 0 To UBound(PL)
        If PL(i) >= 0 Then      '配列の i 番目に格納した金額がプラスなら
            ThisWorkbook.Worksheets("印刷用シート").Cells(j, 2) = PL(i)     '配列の i 番目の金額を「利益」の欄に入力
        ElseIf PL(i) < 0 Then       '配列の i 番目に格納した金額がマイナスなら
            ThisWorkbook.Worksheets("印刷用シート").Cells(j, 3) = PL(i)     '配列の i 番目の金額を「損失」の欄に入力
        End If
        j = j + 1
    Next i
End Sub

※別のやり方もありますが、ここでは配列を解説するためにあえてまどろっこしい方法を取っています。

【解説】配列とコードを分解して理解しよう

(3~5行目)コメントアウトのとおりです。 PLという名前の配列を宣言して、261日分のデータが格納できるように260というインデックスを設定しています。
 i はループ文のカウンターで使うための変数、j はセルの行数を変化させるための変数です。

Dim PL(260) As Long     '配列の宣言(261日分なので0~260までのインデックスを設定)
Dim i As Integer        '配列のインデックスを更新するための変数
Dim j As Integer        'セルの行数用の変数

(9~16行目)①毎日の収支を配列に格納する

  j = 2  'セルの行数用の変数を初期化(収支入力シートの2行目から開始するので)
    For i = 0 To 260
        PL(i) = ThisWorkbook.Worksheets("収支入力").Cells(j, 2)     '収支入力表の j 行2列目の値を配列に格納
        j = j + 1
    Next i

このプロシージャは、配列のインデックス0からインデックス260まで、セルの行数を更新しながら同じ処理が行われるループ文であり For i = 0 to 260 という行の制御によって261個のデータが格納されるまで同じ処理が繰り返されます。

なお PL(i) = ThisWorkbook.Worksheets("収支入力").Cells(j, 2) を日本語にすると

「このExcelブックの収支入力という名前のシートの j 行目の 2 列目の値を PL配列の i 番目に格納せよ」です。

この命令が261回繰り返されることで、1月1日から12月29日までの収支データがすべて配列に格納されます。

(20~36行目)②配列に格納した値をプラスかマイナスかで制御して印刷用シートに入力

j = 2  'セルの行数用の変数をもう一度初期化(印刷用シートの2行目から入力するので)
For i = 0 To UBound(PL)
    If PL(i) >= 0 Then      '配列の i 番目に格納した金額がプラスなら
        ThisWorkbook.Worksheets("印刷用シート").Cells(j, 2) = PL(i)     '配列の i 番目の金額を「利益」の欄に入力
    ElseIf PL(i) < 0 Then       '配列の i 番目に格納した金額がマイナスなら
        ThisWorkbook.Worksheets("印刷用シート").Cells(j, 3) = PL(i)     '配列の i 番目の金額を「損失」の欄に入力
    End If
    j = j + 1
Next i

前のプロシージャと同じ、ループ文による処理をおこなっています。

UBound(PL):UBoundは関数です。「( )内に指定した配列の最大インデックス数を返す」という機能を果たします。
つまり For i = 0 To UBound(PL) このループ文で 「ループを0から始めて、配列の最大インデックス数(260)回までループせよ」 と命令しています。何をループ処理するかというと……

If PL(i) >= 0 Then      '配列の i 番目に格納した金額がプラスなら
    ThisWorkbook.Worksheets("印刷用シート").Cells(j, 2) = PL(i)     '配列の i 番目の金額を「利益」の欄に入力
ElseIf PL(i) < 0 Then       '配列の i 番目に格納した金額がマイナスなら
    ThisWorkbook.Worksheets("印刷用シート").Cells(j, 3) = PL(i)     '配列の i 番目の金額を「損失」の欄に入力
End If

配列に格納した数がプラス収支なら、このExcelブックの印刷用シートという名前のシートの 2 列目(利益欄)に入力。

配列に格納した数がマイナス収支なら、このExcelブックの印刷用シートという名前のシートの 3 列目(損失欄)に入力。

そんな命令をIF文で制御しながらループ処理しているというワケです。

【いざ実行!】光を超える早さこそVBAの配列が真価を発揮する瞬間(前半ウソ)

前期までのコードをコマンドボタンに埋め込み、簡単な動画にしてみましたのでご覧ください。

今回と同じ処理はExcelのセルに直接入力する関数でもできますし、なんならVBAで配列を使わなくても可能です。 ただ最初に申しあげたとおり、配列は「習うより慣れろ」が非常に大事だと個人的に思っています。

よって少し大げさですが、サラっと配列を使えるようになるまでは「ここは配列を使って処理できないか」ということを念頭にいちいち配列を使ってコードを書くと良いかなと思います。

「配列」を使えるあなたはVBA中級者!

配列をしっかり理解するには、今回の解説に加えて「静的配列「動的配列」「多次元配列」などの概念も学ばなければいけません。

それはまた別の記事にて解説しようと思いますが、個人的な意見として、VBAで配列を使えるようになったら「VBA中級者」と言って良いのではないかと思います。

それほど配列は難しくもあり、使えるようになると便利で効率的なデータ構造だと言えます。

ただ、配列が難しいと感じるのは最初だけです。
配列を使っていくうちに

「配列は使えるが……ここで配列を使うと逆に複雑なコードになるな……さてどうするか」

そんなことを考えるようになります。
そうなったら、あなたは紛れもなくVBA中級者と言えるでしょう。

Next Post Previous Post