0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GASの常識がVBAで通用しなかった話(2次元配列に行をPushできない)

Last updated at Posted at 2026-01-02

初投稿です。GAS(Google Apps Script)とVBAを用いた業務効率化をやっております!

はじめに

GASでは頻出の 「配列に配列をPushしていく」 という処理※が、VBAではそのまま使えませんでした。

GASでは当たり前だったこと

GASでは、スプレッドシートAPIの呼び出し回数が処理速度に直結します。そのため、API呼び出しを極力減らすことが重要になります。

そこで一般的だったのが、1次元配列を push してデータを集め、最後に2次元配列としてまとめて書き戻す という方法です。これはI/Oの観点で 強く推奨される、最もシンプルな設計でした。

⇒せいろそばを1枚ずつおかわりして積んでいく イメージです。
1枚(1行)ずつ完成したものを、下にどんどん追加していきます。

const rows = [];
rows.push(["A", 100, "OK"]);
rows.push(["B", 200, "NG"]);
rows.push(["C", 300, "OK"]);

console.log(rows);
// [ ["A",100,"OK"], ["B",200,"NG"], ["C",300,"OK"] ]

VBAで同じことをやろうとして詰んだ話

同じ感覚で、VBAでも2次元配列に行を追加しようとしました。

' 2次元配列に行を追加しようとしたコード
Dim result() As Variant
ReDim result(1 To 1, 1 To 3)

' 1行目は普通に代入できる
result(1, 1) = "A"
result(1, 2) = 100
result(1, 3) = "OK"

' 2行目を追加したいが…
' ↓ こうしたい気持ちはある
'ReDim Preserve result(1 To 2, 1 To 3)  ' 行方向は拡張できない

ところがVBAには、配列に対して行を push するための仕組みがありません

仮の配列に対して、GASの push に相当する操作が存在しないのです。
⇒おかわり厳禁でした。


なぜVBAでは行のPushができないのか

これは単なるバグや制約ではなく、VBAの仕様です。

VBAの標準配列では、後からサイズを変更できるのは最後の次元(列方向)のみで、行方向に広げることはできません。

arr(行, 列)
列 → 1  2  3
行1 A 100 OK
行2 B 200 NG
行3 C 300 OK

👉 行は増やせず、列だけ増やせます。初見では驚くポイントです。


実務的には行を増やしたい

業務データでは、

  • 列 = 属性(例:商品名・金額・ステータス)
  • 行 = レコード(例:1件の注文・1人のユーザー)

という構造が一般的です。

つまり、ユースケースとして圧倒的に多いのは 行(レコード)の追加 ですが、VBAの標準配列ではこれが直接サポートされていません。


回避方法:Collection of 配列

そこで実務的な回避策としてよく使われるのが、Collectionを使う方法です。

1行分のデータを一次元配列として作り、それをCollectionに追加していきます。

Dim rows As New Collection
rows.Add Array("A", 100, "OK")
rows.Add Array("B", 200, "NG")
rows(1)(2)  ' → 100

この方法であれば、行を柔軟に追加できます。


Collection of Dictionary について

※ 行をDictionaryとして扱う方法もありますが、RC参照ができないため、本記事では説明を省きます。


Transpose について

Transpose を使って回避する考え方もありますが、配列の向きを常に意識する必要があり、可読性が下がりやすいため、本記事では詳細な説明は省きます。


配列は最後だけ使う

VBAでは、配列は 最終的にExcelに書き戻すための器 と割り切るのが実務的です。

ReDim result(1 To rows.Count, 1 To 3)

For r = 1 To rows.Count
    For c = 1 To 3
        result(r, c) = rows(r)(c)
    Next c
Next r

Sheet1.Range("A1").Resize(rows.Count, 3).Value = result

👉 配列は 完成したデータを一気に渡す箱 として使います。


まとめ

  • VBAの2次元配列は行を push できない
  • これは仕様であり回避不可
  • 行を集める処理にはCollectionを使う
  • 配列は入出力専用と割り切ると楽になる
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?