和風スパゲティのレシピ

日本語でコーディングするExcelVBA

配列の要素数を取得する - Ubound・Lbound関数

配列の要素数を求める方法を解説します。

最大要素番号を求めるUbound関数と、
最小要素番号を求めるLbound関数を用いて、
「要素数 = Ubound - Lbound + 1」で求めます。

一次元配列の要素数を求めるコード

一次元配列で配列の要素数を求めるには以下のコードを使用します。

Dim 配列(1 To 10)
Dim 要素数 As Long
要素数 = UBound(配列) - LBound(配列) + 1

Debug.Print 要素数 ' 10 - 1 + 1 で10

セルの行数・列数を数えるときにもよく出てくる最大 - 最小 + 1 の計算ですね。

  • 配列(5 To 10) であれば「6」
  • Split("りんご,みかん,いちご"), ",") であれば「3」
  • Array(1, 2, 3, 4) であれば「4」

をそれぞれ求めることができます。


なお、配列の第1要素番号が何番になるのかは、以下の仕様に沿います。

  • Dim 配列(10) などのようにToを省略して書いた場合は「0」始まり
  • Split関数やArray関数で生成した配列も「0」始まり
  • DictioanryのKeys,Itemsで取得した配列も「0」始まり
  • Range.Valueで生成した場合のみ「1」始まり


この並びを見るとわかる通り、
「セルから取得した配列以外はすべて0始まり」
と覚えても問題ありません。

※ ただしセルから取得した場合は後述の二次元配列となります。
Option Base 1 による配列の開始番号変更がある場合はご注意ください。

よって上記の方法で取得した配列に関しては、
以下のようにLboundを省略した式で求めてしまっても大丈夫です。

要素数 = UBound(配列) + 1

 

二次元配列の要素数(大きさ)を求めるコード

Ubound/Lbound関数を二次元配列に対して使用した場合は、
各次元の最大番号、最小番号を求めることができます。

どの次元の要素数を求めるかは第2引数で指定できます。

Dim 配列(1 To 10, 2 To 5)
Dim 第一次元の要素数 As Long, 第二次元の要素数 As Long
第一次元の要素数 = UBound(配列, 1) - LBound(配列, 1) + 1
第二次元の要素数 = UBound(配列, 2) - LBound(配列, 2) + 1

Debug.Print 第一次元の要素数 ' 10 - 1 + 1 で10
Debug.Print 第二次元の要素数 ' 5 - 2 + 1 で4

一次元配列の時と同様(Ubound - Lbound + 1)を計算することで、
二次元配列の要素数(大きさ)を求めることができますね。

この例では「10×4」の配列であることを求めています。


ちなみにこのブロックのタイトルは「二次元配列」としていますが、
Ubound(配列, n)と記載すればn次元目の要素数を求めることもできます。

三次元以上の配列を扱う際もこのコードを利用してください。

要素数の取得を関数化する

今回のコードは理屈は簡単なのですが、いちいち書くとなると面倒です。

こういう「簡単だけど書くのが手間な処理」は、汎用関数にして持っておきましょう。

' 配列の要素数取得を関数化
Function Count配列の要素数(Arr, Optional 次元 = 1) As Long
    Count配列の要素数 = UBound(Arr, 次元) - LBound(Arr, 次元) + 1
End Function

' 標準モジュールはこう書けるようになる
Dim 配列(1 To 10)
Debug.Print Count配列の要素数(配列) ' 10
    
Dim 配列(1 To 10, 2 To 5)
Debug.Print Count配列の要素数(配列, 1) ' 10
Debug.Print Count配列の要素数(配列, 2) ' 4

本体コードが非常に書きやすくなっているのがわかります。

今回のように関数を英字始まりにしておけば、
Count + Ctrl + Space で日本語入力をONにせず入力できるのも嬉しいですね。


こういったちょっとした計算が必要なコードは汎用関数にして持っておきましょう。

汎用関数の作り方に関してはこちらの記事をご覧ください。

www.limecode.jp


求めた要素数(大きさ)を使って配列をセルに一括出力する

求めた要素数をRangeオブジェクトのResizeプロパティに渡すことで、
配列をセルに一括出力することができます。


◇ 一次元配列をセルに一括出力するコード

' 出力したい配列が一次元配列の場合
Dim 配列(1 To 10)
配列(2) = 1: 配列(6) = 2: 配列(10) = 3 ' 適当なテスト値

Dim 要素数 As Long
要素数 = UBound(配列) - LBound(配列) + 1
    
' 横方向→ に出力する場合
Range("A1").Resize(1, 要素数).Value = 配列

' 縦方向↓ に出力する場合
Range("A1").Resize(要素数, 1).Value = WorksheetFunction.Transpose(配列)

 
◇ 出力結果
一次元配列のセルへの出力結果

一次元配列を縦に出したいときだけTranspose関数が必要なので覚えておきましょう。


続いて二次元配列を出力するコードがこちらです。

◇ 二次元配列をセルに一括出力するコード

' 出力したい配列が2次元配列の場合
Dim 配列(1 To 10, 2 To 5)
配列(1, 2) = 1
配列(2, 3) = 2
配列(3, 4) = 3
配列(4, 5) = 4
配列(10, 5) = 5

Dim 行数 As Long, 列数 As Long
行数 = UBound(配列, 1) - LBound(配列, 1) + 1
列数 = UBound(配列, 2) - LBound(配列, 2) + 1

Range("A1").Resize(行数, 列数) = 配列

 
◇ 出力結果

二次元配列をセルに出力した結果


出力起点セル.Resize(行数, 列数)という記述がとても読みやすいですね。


この例を見ると

  • 配列インデックスが「2~5」であっても
  • 出力される列は「1(A)~4(D)」列になっている

のがわかります。


このコードで行うセルへの出力はインデックスの開始番号に影響されません。

大きささえしっかり合っていればOKということになります。


このコードが配列をセルに書き出す基本コードになりますので、
今回の「配列の要素数取得」コードと一緒に覚えてしまってください。



ちなみに先ほど作成した汎用関数を利用すれば、

' 横方向→ に出力する場合
Range("A1").Resize(1, Count配列の要素数(配列)).Value = 配列

' 縦方向↓ に出力する場合
Range("A1").Resize(Count配列の要素数(配列), 1).Value = WorksheetFunction.Transpose(配列)

' 二次元配列を出力する場合
Range("A1").Resize(Count配列の要素数(配列, 1), Count配列の要素数(配列, 2)).Value = 配列

このように変数なし1行で読みやすく書けるようになります。

かなり便利に使える関数ですので、
配列を頻繁に扱うようになったら、作ってお供にしておきましょう。