VBA配列のスライス設計を下限と負数インデックスから考える
Copyright © 2026 LWP 山中 一弘
本資料は、出典を明記いただければ、商用・非商用を問わず、ご自由に複製・改変・再配布していただけます。なお、著作権表示は改変せず、そのまま記載してご利用くださいますようお願いいたします。
記事要約
配列のスライスは、単に「一部を切り出す」だけなら簡単に見えます。
しかし、VBAで汎用的なスライス関数を作ろうとすると、下限、上限、負数インデックス、開始位置、終了位置、ステップをどう定義するかが問題になります。
この記事では、VBA配列のスライス設計を、下限と負数インデックスの関係から整理します。
本記事の対象とゴール
VBAで配列操作ライブラリを作りたい人
LBound と UBound の扱いで迷う人
Python風の負数インデックスやスライスをVBAへ持ち込みたい人
先に結論
VBAで汎用スライスを作るなら、下限を無視して決め打ちするのは危険です。
VBA配列には、0始まり、1始まり、任意下限があり得ます。さらに、最後の要素を -1 と表すような負数インデックスを入れると、設計の選択肢が一気に増えます。
そのため、スライス関数は「どの下限体系で、負数をどう正規化するか」を明示して設計する必要があります。
<!-- LWP_REWRITE_EXPANSION_記事106 -->
1. 配列のスライスは範囲指定の設計である
VBAには、Pythonのような配列スライス構文はありません。そのため、配列の一部を取り出す処理は自分で設計する必要があります。ここで問題になるのが、下限、上限、負数インデックス、空範囲の扱いです。
スライスを単なる便利関数として作ると、境界条件で壊れます。どこを含み、どこを含まないのか。範囲外をエラーにするのか、丸めるのか。先に仕様を決める必要があります。
2. 下限を無視しない
VBA配列には下限があります。Option Base や Array、Excel範囲から取得した二次元配列によって、下限が0だったり1だったりします。配列処理を安定させるには、LBound と UBound を基準にします。
下限を0固定で考えると、Excel由来の配列でずれます。逆に1固定で考えると、通常の配列やAPI由来の配列でずれます。VBAでは、配列の範囲を常に実測する癖が必要です。
3. 負数インデックスは便利だが仕様が要る
末尾から数える負数インデックスは便利です。ただし、VBA標準ではありません。導入するなら、-1 は末尾、-2 は末尾の1つ前、という対応を明文化します。
さらに、範囲外の負数をどう扱うかも決めます。実務ライブラリでは、便利さよりも、間違った指定を早く検出できることが重要です。
スライスで決めるべきこと
配列 a, b, c, d, e, f から一部を取り出すとします。
start = 2end = 3step = 1このとき、start と end は何を意味するのでしょうか。
実際の配列添字なのか
0始まりの論理位置なのか
1始まりの論理位置なのか
end は含むのか、含まないのか
負数は末尾から数えるのか
ここを決めないと、スライス関数は使うたびに迷います。
負数インデックスが必要になる理由
スライスを便利に使うには、末尾から指定できることが重要です。
たとえば、最後の要素を取りたい、最後から2番目までを対象にしたい、末尾だけ除きたい、といった処理はよくあります。
そのためには、負数インデックスが欲しくなります。
-1 = 最後の要素-2 = 最後から2番目の要素この考え方は直感的です。
しかし、VBAでは配列下限が常に0とは限りません。ここが難所です。
下限が0の場合
下限が0で、要素数が m の配列を考えます。
添字: 0 1 2 3値 : a b c d負数: -4 -3 -2 -1この場合、負数表記は比較的分かりやすくなります。
neg = i - m最後の要素は 3 - 4 = -1 です。
下限が1の場合
下限が1の場合は、同じ式ではずれます。
添字: 1 2 3 4値 : a b c d同じように最後の要素を -1 としたいなら、下限を考慮する必要があります。
neg = i - m - lbここで lb は配列下限です。
この式にすると、任意下限でも負数表記を正規化できます。
決め打ちしない設計
配列スライスを共通化するとき、0始まりに決め打ちしたくなります。
しかし、それをすると、使う側が常に変換を要求されます。
VBAでは、配列の下限が意味を持つ場面があります。ワークシート由来の配列、手作りの配列、外部ライブラリ由来の配列で前提が違います。
だから、スライス関数の内部で、次の正規化を行う設計が必要です。
Function NormalizeIndex(ByVal index As Long, ByVal lb As Long, ByVal ub As Long) As Long Dim count As Long count = ub - lb + 1 If index < 0 Then NormalizeIndex = index + count + lb Else NormalizeIndex = index End IfEnd Functionこれは考え方を示す簡略例です。実際には、範囲外、end の含む・含まない、step の正負も決める必要があります。
まとめ
VBAの配列スライスは、見た目より設計が難しい機能です。
理由は、VBA配列に下限があり、0始まりだけを前提にできないからです。
負数インデックスを便利に使うなら、下限と要素数を使ってインデックスを正規化する必要があります。
スライス関数を作るときは、開始、終了、ステップ、負数、範囲外の扱いを仕様として明示することが重要です。
出典メモ- 元Posfie URL: https://posfie.com/@hoehoe1234/p/n6b48Ty
元Posfieタイトル: 2022-02-23 VBA 配列のスライスはどうあるべきか
投稿者: hoehoe1234
投稿数: 17
画像確認: 画像なし
取得・確認日: 2026-06-11
