VBA技術解説
VBAにおける配列やコレクションの起点について

ExcelマクロVBAの問題点と解決策、VBAの技術的解説
公開日:2019-10-05 最終更新日:2023-07-22

VBAにおける配列やコレクションの起点について


VBAの配列を扱っていると、0から開始されていたり1から開始されていたりします。
さすがに、混乱したり、間違ってしまう事もあると思います。


0から開始される場合を、「0オリジン」英語では「zero-based」
1から開始される場合を、「1オリジン」英語では「one-based」
このような呼び方をします。
VBAでの、これらの違いについてお話したいと思います。

配列の起点について

VBAの配列の起点はOption Baseで指定できますが、Option Baseの影響を受けない関数等があります。

Option Base

Dim ary(3)
特に指定が無ければ、これは0オリジンで、0~3の配列になります。
特に指定が無ければと書きましたが、
Option Base 1
これを指定すると、1オリジンとなり、1~3の配列になります。

Option Baseでは、0or1が指定できます。
マイナスや2以上は指定できません。
既定は、Option Base 0です。

つまりVBAではOption Baseで、「0オリジン」と「1オリジン」を選択できるという事です。
もちろん、
Dim ary(1 To 3)
このようにすれば、Option Baseに関係なく1オリジンの配列になります。

セル範囲から作成される配列

Variant変数 = Range(・・・).Value
これで作成される配列は、
Option Baseの影響を受けることなく常に1オリジンの2次元配列になります。

逆に、配列をセル範囲に入れるときの、
Range(・・・).Value = 配列
この配列は0オリジンでも1オリジンでも、2次元配列でさえあればどっちでも構いません。
どちらでも、動作結果は同じになります。

Split関数とFilter関数で作成される配列

変数 = Split(文字列)
変数 = Filter(配列)
Split関数とFilter関数で作成される配列は、Option Baseの影響を受けることなく常に0オリジンになります。
Split関数とFilter関数の結果を1オリジンにする書き方は、私の知る限りでは存在しません。

Array関数で作成される配列

変数 = Split(・・・)
これで作成される配列は、Option Baseにより決定されます。
Base 0なら、0オリジンになります。
Base 1なら、1オリジンになります。
Base 0が既定ですので、通常は0オリジンという事です。

ですが、Base 1の時も0オリジンになる書き方があります。
変数 = VBA.Split(・・・)
変数 = VBA.[_HiddenModule].Array(・・・)
このようにタイプ ライブラリの名前で修飾した書き方をすると、
Option Baseの影響を受けずに常に0オリジンになります。

ParamArray指定の引数

プロシージャー名(ParamArray 引数名())
ParamArrayキーワードを指定した引数の配列は、Option Baseの影響を受けることなく常に0オリジンになります。
呼び出し側でこの引数を省略した場合は、LBoundは0、UBoundは-1となります。


コレクション

WorksheetsやWorkbooks等、Excelのコレクションは常に1オリジンです。
Worksheets(0)やWorkbooks(0)はエラーとなります。

コレクションと配列は全く別物です。
コレクションと配列の記述が同じになっているので混同されがちですが、
コレクションにおける、コレクション(インデックス)
これは、
コレクション.Item(インデックス)
この記述の省略形になります。

Itemがこれらコレクションの既定のメンバーとなっているため、
メンバーを省略した場合はItemを指定したことと同じになります。
Itemはプロパティですので、プロパティが引数を受け取って値を返しているので、
0オリジンか1オリジンかは、プロパティ次第という事です。
ただし、Excelに用意されているコレクションは全て1オリジンで統一されています。

クラスを自作して、0オリジンのItemプロパティを作ることは出来ますので、
あくまで、Excel作成したときの都合で1オリジンにしたというだけの事になります。


Collectionオブジェクト

VBAには、独自のコレクションを作成するためのオブジェクトとしてCollectionオブジェクトが用意されています。
このCollectionオブジェクトも常に1オリジンです。

Dim c As New Collection
c.Add "A"
Debug.Print c(1)

c(0)は、エラーとなります。
c(1)は、c.Item(1)の省略形です。

少し話が脱線しますが
CollectionのItemはプロパティではなくメソッドになっています。
なぜメソッドにしたのかは分かりませんが、
少なくともメソッドであるがゆえに、以下の記述はできなくなっています。
c(1) = "B"
メソッドですから、値を受け取ることはできても値を入れることはできません。
ただし、プロパティでも読み取り専用にすればよいので、これはメソッドにしている理由ではないでしょう。


その他:文字列関数

配列とは話が大分変ってしまいますが、文字列系の関数の文字位置は1オリジンになっています。
Right、Mid、Left、InStr等々
先頭から1文字目が1、これだけを見たらわかりやすいとは思います。
ですが、配列と合わせて使う場合には注意が必要になってきます。

配列の起点の原則

・既定は0オリジン
・Rangeから作成は1オリジン
・Splitは常に0オリジン
・ParamArrayは常に0オリジン
・Option Baseで変更できるのはDimおよびRedimの配列
・コレクションは1オリジン
・文字列関数は1オリジン

うーん、結局7つも原則があったら、混乱しますね。
原則として、Option Baseは使わないことにすれば、
・Rangeから作成は1オリジン
・コレクションは1オリジン
・文字列関数は1オリジン
・以外は0オリジン

これくらいなら覚えやすいのではないでしょうか。




同じテーマ「マクロVBA技術解説」の記事

PowerQueryの強力な機能をVBAから利用する方法

・説明に使用するデータ ・PowerQueryの操作方法 ・PowerQueryのマクロの記録 ・PowerQueryのVBA文法 ・PowerQueryの機能を利用したマクロVBA ・PowerQueryについて
ShapesとDrawingObjectsの相違点と使い方
・Shapes コレクション ・DrawingObjects コレクション ・ShapesとDrawingObjectsの相違点 ・DrawingObjectsの便利な使い道 ・最後に ・図形オートシェイプ(Shape)に関連する記事
新規挿入可能なシート名の判定
・シート名として使える文字列か判定 ・シートの存在確認:存在すればシートのオブジェクトを返す ・シートの挿入:存在すればシートのオブジェクトを返す
VBAにおける配列やコレクションの起点について
VBAのマルチステートメント(複数のステートメントを同じ行に)
・VBAでのステートメントという用語について ・行継続(1ステートメントを複数の行に) ・VBAマルチステートメントの基本 ・VBAマルチステートメントの応用 ・マルチステートメントの最後に
クリップボードに2次元配列を作成してシートに貼り付ける
・クリップボードのデータ取得/クリップボードへデータ送信 ・エクセルの行・列のデータ ・クリップボードに2次元配列を作成してシートに貼り付けるVBA ・クリップボードに2次元配列の最後に
ユーザー定義型の制限とクラスとの使い分け
・ユーザー定義型 ・クラスについて ・ユーザー定義型とクラスの速度比較 ・ユーザー定義型の制限 ・ユーザー定義型の制限とクラスとの使い分け
シングルクォートの削除とコピー(PrefixCharacter)
・シングルクォーテーション意味 ・VBAでシングルクォーテーションがコピーされる場合と消える場合 ・VBAでのシングルクォーテーションの取得方法 ・VBAでシングルクォーテーションを取り除くVBA ・VBAでシングルクォーテーションを含めて値コピーするVBA
空文字列の扱い方と処理速度について(""とvbNullString)
・String型変数のメモリ配置と取得する関数 ・空文字列について ・String変数に空文字列を入れる ・セルに空文字列を入れる ・Stringが空文字列か判定 ・InputBox関数の戻り値が空文字列判定 ・空文字列の処理方法による速度比較
VBAにおける変数のメモリアドレスについて
・メモリアドレスを取得する関数とメモリコピーのWindowsAPI ・メモリアドレスを確認するために使用したVBA ・文字列型Stringのメモリアドレス ・Integer, Long, Single, Double, Dateのメモリアドレス ・Variantのメモリアドレス ・配列のメモリアドレス ・オブジェクトのメモリアドレス ・ByRef,ByValのメモリアドレス
Evaluateメソッド(文字列の数式を実行します)
・Evaluateメソッドの構文 ・Evaluateメソッドの解説と使用例 ・Evaluateメソッドの最後に


新着記事NEW ・・・新着記事一覧を見る

エクセルが起動しない、Excelが立ち上がらない|エクセル雑感(2024-04-11)
ブール型(Boolean)のis変数・フラグについて|VBA技術解説(2024-04-05)
テキストの内容によって図形を削除する|VBA技術解説(2024-04-02)
ExcelマクロVBA入門目次|エクセルの神髄(2024-03-20)
VBA10大躓きポイント(初心者が躓きやすいポイント)|VBA技術解説(2024-03-05)
テンキーのスクリーンキーボード作成|ユーザーフォーム入門(2024-02-26)
無効な前方参照か、コンパイルされていない種類への参照です。|エクセル雑感(2024-02-17)
初級脱出10問パック|VBA練習問題(2024-01-24)
累計を求める数式あれこれ|エクセル関数応用(2024-01-22)
複数の文字列を検索して置換するSUBSTITUTE|エクセル入門(2024-01-03)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.RangeとCellsの使い方|VBA入門
6.ブックを閉じる・保存(Close,Save,SaveAs)|VBA入門
7.並べ替え(Sort)|VBA入門
8.メッセージボックス(MsgBox関数)|VBA入門
9.セルのクリア(Clear,ClearContents)|VBA入門
10.ひらがな⇔カタカナの変換|エクセル基本操作




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。


このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ