【2026年7月最新】VBA リストボックスの使い方完全ガイド|初期化・値取得・複数選択・エラー対策まで

【2026年7月最新】VBA リストボックスの使い方完全ガイド|初期化・値取得・複数選択・エラー対策まで

Excelで入力フォーム(UserForm)を作っていると、必ずと言っていいほど登場するのが「リストボックス」というコントロールです。プルダウンのように選択肢から値を選ばせたいとき、複数の項目を一覧で見せて選ばせたいとき——どちらもListBoxコントロールで実現できます。

ただ、いざ使おうとすると「AddItemとRowSourceって何が違うの?」「選んだ値をどうやって取り出すの?」「複数選択させるにはどうすれば?」といった疑問にぶつかり、検索しても断片的な情報しか出てこず、結局サンプルコードをコピペして動かすだけで終わってしまう人が多いのが実情です。

この記事では、VBAのListBoxコントロールについて、初期化・値の取得・複数選択・主要プロパティ/メソッド・よくあるエラーまで、実務でそのまま使えるコード例つきで体系的に解説します。さらに後半では、「VBAマクロの保守が特定の担当者に依存してしまう」という多くの現場が抱える課題と、その解決の選択肢としてAIエージェントを使う考え方も紹介します。

代表菅澤 代表菅澤
VBAのリストボックスは、一度仕組みを理解すれば決して難しくありません。ただ「AddItemで追加する方法」と「RowSourceでセル範囲を紐づける方法」を混同して詰まる人がとても多い印象です。この記事では、その違いを最初にはっきりさせます。
AI鬼管理山崎 AI鬼管理山崎
今日は実務でよく使う場面を想定しながら、コピペしてすぐ動くコード例を中心に解説していきます。後半では、こうしたExcelマクロの保守を「誰が担うか」という経営課題にも触れますので、情シス担当者の方だけでなく経営者の方もぜひ最後まで読んでみてください。

この記事を最後まで読むと、次の7つが明確になります。

✔️リストボックスとコンボボックスの違いと、使い分けの判断基準
✔️AddItem/List/RowSourceという3つの初期化方法の違いと使い分け
✔️ListIndex・Value・Selectedを使った値の取得方法(単一選択・複数選択それぞれ)
✔️MultiSelectプロパティによる複数選択の実装方法
✔️ListBoxの主要プロパティ・メソッド一覧と、実務でよく使うものの見分け方
✔️実行時エラーの典型パターンと、その回避コード
✔️VBAマクロの属人化リスクと、AIエージェントによる保守の考え方
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理
📌 この記事の結論
【2026年7月最新】VBA リストボックスの使い方完全ガイド|初期化・値取得・複数選択・エラー対策まで
VBA(Visual Basic for Applications)のリストボックスの使い方を初心者向けに解説。AddItem/RowSource/ListIndexによる初期化・値取得・複数選択・エラー対策まで、実務で使えるコード例つきで紹介します。

01 リストボックスとは?他のコントロールとの違い UserFormで「一覧から選ばせる」ための基本コントロール

リストボックス(ListBox)とは、Excel VBAのUserForm(ユーザーフォーム)上に配置できるコントロールの一つで、あらかじめ用意した選択肢を一覧表示し、その中からユーザーに選ばせるための部品です。担当者一覧から名前を選ぶ、支店名の一覧から拠点を選ぶ、といった「入力ミスを防ぎたい選択項目」で頻繁に使われます。

📚 用語解説

UserForm(ユーザーフォーム):VBAで作成できる独自の入力ダイアログ画面のこと。テキストボックス・ボタン・リストボックスなどの部品(コントロール)を自由に配置して、Excel標準のセル入力とは別に、専用の入力画面を作ることができます。VBEditor(VBE)の「挿入」メニューから追加します。

1-1. コンボボックスとの違い

リストボックスとよく混同されるのがコンボボックス(ComboBox)です。どちらも「選択肢から選ぶ」という点は同じですが、表示のされ方が異なります。

項目リストボックス (ListBox)コンボボックス (ComboBox)
表示形式選択肢が常に一覧表示される普段は1行のみ表示、クリックで展開
占有スペース複数行分のスペースが必要省スペース(1行分でOK)
複数選択対応(MultiSelectプロパティ)非対応(単一選択のみ)
直接入力不可(一覧からの選択のみ)Styleプロパティの設定(fmStyleDropDownCombo)によっては手入力も可能
向いている用途選択肢を常に見せたい/複数選ばせたい選択肢が多い/画面を省スペースにしたい
💡 使い分けの目安

選択肢が5〜10個程度で、常に一覧を見せながら選ばせたい・複数選択させたい場合はリストボックス。選択肢が多く、画面スペースを節約したい場合や単一選択で十分な場合はコンボボックスが向いています。フォームの用途に迷ったら「複数選択が必要かどうか」で判断すると早いです。

1-2. どんな業務シーンで使われるか

実務では、以下のようなシーンでリストボックスが使われます。

✔️担当者一覧から複数名を選んでタスクを割り振る入力フォーム
✔️支店・部署一覧から対象を選んで絞り込み検索を行う画面
✔️在庫管理システムで、商品カテゴリを一覧から選んで登録する画面
✔️アンケートフォームで、複数の選択肢にチェックを入れさせる画面
代表菅澤 代表菅澤
個人的な経験で言うと、リストボックスは「入力ミスを構造的になくしたい」場面で真価を発揮します。テキストボックスに自由入力させると「東京都」「東京」「Tokyo」のように表記ゆれが起きますが、リストボックスなら選択肢が固定されるので、後工程の集計が圧倒的に楽になります。

02 リストボックスの配置と呼び出し方 デザイナーでの配置からコード上での参照方法まで

リストボックスを使うには、まずUserForm上にコントロールを配置する必要があります。手順は次の通りです。

1
VBE(VBAエディタ)を開く「Alt + F11」でVisual Basic Editorを起動します。
2
UserFormを挿入するプロジェクトエクスプローラーで右クリック →「挿入」→「ユーザーフォーム」を選択します。
3
ツールボックスからListBoxを配置するツールボックスのListBoxアイコン(横線が並んだリスト風の四角いアイコン)をクリックし、フォーム上にドラッグして配置します。
4
オブジェクト名を確認するプロパティウィンドウの「(オブジェクト名)」欄で名前を確認します(既定では ListBox1)。

配置が完了したら、コード側から次のようにリストボックスを参照します。ポイントは、フォーム名.コントロール名の形式でアクセスすることです。

' フォームモジュール内(UserForm1のコード内)では
' 単純にコントロール名だけで参照できる
ListBox1.AddItem "サンプル項目"

' 標準モジュールなど、フォームの外から参照する場合は
' フォームを明示的にインスタンス化してから参照する
Dim frm As UserForm1
Set frm = New UserForm1
frm.ListBox1.AddItem "サンプル項目"
frm.Show

📚 用語解説

コントロール:UserFormやワークシート上に配置できる部品の総称。ボタン・テキストボックス・リストボックス・コンボボックス・チェックボックスなどが該当します。VBAでは「フォーム名.コントロール名.プロパティ」という形式で操作します。

⚠️ フォームモジュール内とそれ以外での参照方法の違い

UserFormのコードモジュール(フォーム自身のコード)内では、ListBox1のようにコントロール名だけで直接参照できます。一方、標準モジュールなどフォームの外部からリストボックスを操作する場合は、フォームをインスタンス化してから frm.ListBox1 のようにアクセスする必要があります。この違いを理解していないと「オブジェクトが必要です」というエラーの原因になります。

AI鬼管理山崎 AI鬼管理山崎
フォームの外からコントロールを直接触ろうとしてエラーになる、というのはVBA初心者が最初にぶつかる壁の一つです。「今どのモジュールにコードを書いているか」を意識するだけで、この手のエラーはかなり減ります。

03 リストボックスの初期化(3つの方法) AddItem/List配列/RowSource、それぞれの使い所

リストボックスに選択肢を表示させることを「初期化」と呼びます。初期化には主に3つの方法があり、それぞれメリット・デメリットが異なります。多くの解説記事はAddItemしか紹介しませんが、実務ではこの3つを使い分けられるかどうかで、コードの保守性が大きく変わります。

3-1. 方法1:AddItemメソッドで1件ずつ追加する

最も基本的な方法がAddItemメソッドです。フォームが開くタイミング(UserForm_Initializeイベント)で、1件ずつ項目を追加していきます。

Private Sub UserForm_Initialize()
    ListBox1.AddItem "東京"
    ListBox1.AddItem "大阪"
    ListBox1.AddItem "名古屋"
    ListBox1.AddItem "福岡"
End Sub

セルのデータをループで読み込んで動的に追加することもできます。件数が可変のリストを作りたい場合はこちらが定番です。

Private Sub UserForm_Initialize()
    Dim i As Long
    Dim lastRow As Long
    lastRow = Worksheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row

    For i = 1 To lastRow
        ListBox1.AddItem Worksheets("Sheet1").Cells(i, 1).Value
    Next i
End Sub

📚 用語解説

AddItemメソッド:リストボックスやコンボボックスに、項目を1件追加するメソッド。ListBox1.AddItem "値" のように書き、複数列を持たせたい場合は追加後に List(行番号, 列番号) で個別の列に値を設定します。

3-2. 方法2:RowSourceプロパティでセル範囲と連動させる

RowSourceプロパティに、ワークシート上のセル範囲を文字列で指定すると、コードをほぼ書かずにリストを表示できます。

Private Sub UserForm_Initialize()
    ListBox1.RowSource = "Sheet1!A1:A10"
End Sub

RowSourceは指定したセル範囲と直接連動するため、フォームを開いたままセルの内容を書き換えると、リストボックスの表示もそれに応じて変わります。コード量が最小で済むのが最大のメリットですが、範囲外にセルが増減しても自動追従はしない点には注意が必要です。

3-3. 方法3:Listプロパティに配列を一括代入する

Listプロパティに配列を直接代入すると、ループを書かずに一括でリストを初期化できます。件数が多い場合、AddItemをループで回すより高速に動作します。

Private Sub UserForm_Initialize()
    ListBox1.List = Array("東京", "大阪", "名古屋", "福岡")
End Sub

値を直接書き並べる代わりに、セル範囲の値をまとめて配列として渡すことも可能です。これは上記とは別の実装例です。同じフォームにUserForm_Initializeを2つ書くと「Ambiguous name detected」というコンパイルエラーになるため、どちらか一方だけを使ってください。

Private Sub UserForm_Initialize()
    ListBox1.List = Worksheets("Sheet1").Range("A1:A10").Value
End Sub
方法コード量実行速度(大量データ時)セルとの連動向いている場面
AddItemやや多い(ループ処理向き)普通なし(一度追加したら独立)条件付きで動的に項目を組み立てたい場合
RowSource最小普通あり(セル変更が反映される)シンプルにセル範囲をそのまま出したい場合
List配列代入少ない速い(一括処理)なし(代入時点のスナップショット)件数が多い・処理速度を優先したい場合
💡 迷ったらこの基準で選ぶ

セル範囲をそのまま出すだけならRowSource、条件分岐しながら項目を組み立てるならAddItem、件数が多く速度を優先したいならList配列代入、というのが実務でのおおまかな使い分けの目安です。3つとも一度書けるようになっておくと、後から仕様変更が入っても対応しやすくなります。

代表菅澤 代表菅澤
RowSourceは便利ですが、「セルの値が変わったのにリストが更新されない」という相談を受けることがあります。これはRowSourceが不連続な範囲を認識できない、あるいは初期化のタイミングがズレているケースがほとんどです。迷ったらList配列代入の方がトラブルは少ない印象です。
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

04 リストボックスから値を取得する方法 ListIndex・Value・List(index)の関係を正しく理解する

リストに選択肢を表示できたら、次に必要なのは選ばれた値を取得する処理です。ここでつまずく人が非常に多いポイントなので、丁寧に見ていきます。

4-1. ListIndexプロパティ:選択位置を取得する

ListIndexプロパティは、選択されている項目の位置(インデックス)を返します。重要なのは、先頭の項目が0番から始まる点、そして何も選択されていない場合は-1が返る点です。

Private Sub CommandButton1_Click()
    If ListBox1.ListIndex = -1 Then
        MsgBox "リストから項目を選択してください"
        Exit Sub
    End If

    MsgBox "選択位置: " & ListBox1.ListIndex & vbCrLf & _
           "選択項目: " & ListBox1.List(ListBox1.ListIndex)
End Sub

📚 用語解説

ListIndexプロパティ:リストボックス内で選択されている項目の位置(0始まりの番号)を返すプロパティ。先頭の項目は0、2番目は1……という数え方になります。何も選択されていない状態では-1が返ります。

⚠️ ListIndex = -1 のチェックを忘れると起きるエラー

何も選択されていない状態で ListBox1.List(ListBox1.ListIndex) を実行すると、ListIndexが-1のため「実行時エラー 381:オブジェクト配列のインデックスが有効範囲にありません」が発生します。ボタンを押す処理の先頭で、必ず ListIndex = -1 かどうかをチェックする習慣をつけてください。

4-2. Valueプロパティ:選択項目の値を直接取得する

Valueプロパティを使うと、ListIndexを経由せずに選択項目の値を直接取得できます。単一選択のリストボックスであれば、こちらの方がシンプルに書けます。

Private Sub CommandButton1_Click()
    If ListBox1.ListIndex = -1 Then
        MsgBox "リストから項目を選択してください"
        Exit Sub
    End If

    MsgBox "選択項目: " & ListBox1.Value
End Sub

複数列のリストボックス(ColumnCountを2以上に設定している場合)では、ValueはBoundColumnプロパティで指定した列の値を返します。既定ではBoundColumnは1(1列目)です。

📚 用語解説

BoundColumnプロパティ:複数列のリストボックスで、Valueプロパティが「どの列の値を返すか」を指定するプロパティ。既定値は1(1列目)。例えば1列目にID、2列目に名称を表示させ、実際に取得したいのがIDだけという場合、BoundColumn = 1 のままにしておけば、表示は2列でもValueはIDだけを返すよう制御できます。

4-3. List(index) と Value の違い

取得方法書き方特徴
ListIndex + List(index)ListBox1.List(ListBox1.ListIndex)位置(何番目か)を経由して値を取る。複数列の任意の列を指定して取得できる
ValueListBox1.ValueBoundColumnで指定した列の値を直接取得。単一選択ならこちらがシンプル
TextListBox1.Text表示上のテキストを取得(多くの場面でValueと同じ挙動になる)
AI鬼管理山崎 AI鬼管理山崎
「ListIndexで位置を取る」か「Valueで値を直接取る」かは、正直どちらでも動きます。ただ、複数列のリストで特定の列だけ取り出したいケースが出てきたら、List(ListIndex, 列番号)のように列番号まで指定できるListIndex経由の書き方を覚えておくと応用が利きます。

05 複数選択を扱う方法(MultiSelect) MultiSelectプロパティとSelected配列の組み合わせ

リストボックスの大きな強みの一つが、複数の項目を同時に選択できることです。これを実現するのがMultiSelectプロパティです。

5-1. MultiSelectプロパティの3つの設定値

設定値定数名動作
0(既定値)fmMultiSelectSingle単一選択のみ。1項目しか選べない
1fmMultiSelectMultiクリックするたびに選択/解除が切り替わる複数選択
2fmMultiSelectExtendedShiftキーで範囲選択、Ctrlキーで個別追加選択(Windowsのエクスプローラーと同じ操作感)
Private Sub UserForm_Initialize()
    ListBox1.List = Array("東京", "大阪", "名古屋", "福岡", "札幌")
    ListBox1.MultiSelect = fmMultiSelectMulti
End Sub

📚 用語解説

MultiSelectプロパティ:リストボックスで複数項目の同時選択を許可するかどうかを設定するプロパティ。既定は単一選択(fmMultiSelectSingle)。複数選択を有効にする場合はfmMultiSelectMulti(クリックでトグル)またはfmMultiSelectExtended(Shift/Ctrl併用)を指定します。

5-2. Selected配列で複数の選択項目を取得する

MultiSelectを有効にすると、ListIndexやValueは正しく機能しなくなります(単一の位置・値しか表せないため)。複数選択された項目を取得するには、Selectedプロパティをループで走査します。

Private Sub CommandButton1_Click()
    Dim i As Long
    Dim result As String

    For i = 0 To ListBox1.ListCount - 1
        If ListBox1.Selected(i) Then
            result = result & ListBox1.List(i) & vbCrLf
        End If
    Next i

    If result = "" Then
        MsgBox "1件も選択されていません"
    Else
        MsgBox "選択された項目:" & vbCrLf & result
    End If
End Sub

📚 用語解説

Selectedプロパティ:リストボックスの各項目が選択されているかどうかを、項目のインデックスを指定してTrue/Falseで返す(または設定する)プロパティ。ListBox1.Selected(0) のように書き、複数選択モードで「どの項目が選ばれているか」を1件ずつ確認する際に使います。

⚠️ MultiSelect有効時にValueを使うと起きるエラー

MultiSelectをfmMultiSelectMultiまたはfmMultiSelectExtendedに設定した状態でListBox1.Valueを参照すると、複数選択・未選択の状態によって正しい値が返らず、想定外の動作や実行時エラー380(プロパティの値が不正です)につながることがあります。複数選択モードでは、必ずSelected配列をループで確認する書き方に統一してください。

代表菅澤 代表菅澤
ここは実務でのバグ報告が多いポイントです。「複数選択できるようにしたのに、Valueで値を取ろうとして動かない」という相談を何度も受けています。MultiSelectを有効にした時点で、値の取得方法もSelected配列に切り替える、とセットで覚えておくと事故が減ります。

06 主要メソッド・プロパティ体系一覧 ListBoxで実務上よく使うものを1枚で把握する

ここまで登場したものも含め、リストボックスでよく使うメソッド・プロパティを体系的に整理します。

6-1. メソッド一覧

メソッド説明
AddItemリストに項目を1件追加する
RemoveItem指定したインデックスの項目を1件削除する(例: ListBox1.RemoveItem 2)
Clearリスト内の全項目を削除する(RowSource経由のデータには使用不可)

6-2. プロパティ一覧

プロパティ説明
Listリストの内容を配列として取得・設定する
ListCountリストに含まれる項目数を取得する(読み取り専用)
ListIndex選択されている項目の位置(0始まり、未選択は-1)
Value選択項目の値(BoundColumnで指定した列)を取得・設定する
Text選択項目の表示テキストを取得・設定する
Selected各項目の選択状態をTrue/Falseで取得・設定する
MultiSelect複数選択の可否・モードを設定する
ColumnCount表示する列数を設定する(既定は1列)
ColumnWidths各列の幅をポイント単位の文字列で指定する(例: "50pt;100pt")
BoundColumnValueプロパティが参照する列番号を指定する
RowSource連動させるワークシート上のセル範囲を指定する
ListStyleリストの見た目(プレーン表示/オプションボタン風表示)を切り替える
TopIndexスクロール位置(一番上に表示される項目のインデックス)を取得・設定する

📚 用語解説

ColumnCountプロパティ:リストボックスに何列分のデータを表示するかを指定するプロパティ。既定は1列。2以上に設定すると、AddItemで追加した際にList(行, 列)で各列に値を設定でき、例えば「1列目にID、2列目に氏名」のような複数列表示が可能になります。

💡 複数列リストボックスの作り方

ColumnCountを2以上に設定したうえで、AddItemで1列目を追加した後にList(ListBox1.ListCount - 1, 1) = "2列目の値" のように列を個別に指定すると、複数列のリストボックスを組み立てられます。列幅はColumnWidthsで "60pt;120pt" のように調整します。

AI鬼管理山崎 AI鬼管理山崎
プロパティが多くて最初は圧倒されますが、実務で頻繁に使うのはListIndex・Value・Selected・List・ListCountの5つ程度です。まずこの5つを押さえて、必要になったタイミングで他のプロパティを調べる、という進め方で十分です。
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

07 よくあるエラーとトラブルシューティング 実務でつまずきやすい3つのパターンと対処法

リストボックス関連の実行時エラーは、原因パターンがある程度決まっています。ここでは代表的な3つを、症状・原因・対処法のセットで解説します。

7-1. 実行時エラー381「オブジェクト配列のインデックスが有効範囲にありません」

最も頻出するエラーです。ListIndexが-1(未選択)の状態で List(ListIndex) や Selected(ListIndex) にアクセスしようとすると発生します。

' NG例:未選択チェックがない
Private Sub CommandButton1_Click()
    MsgBox ListBox1.List(ListBox1.ListIndex)  ' 未選択時にエラー
End Sub

' OK例:先頭で必ずチェックする
Private Sub CommandButton1_Click()
    If ListBox1.ListIndex = -1 Then
        MsgBox "項目を選択してください"
        Exit Sub
    End If
    MsgBox ListBox1.List(ListBox1.ListIndex)
End Sub

7-2. 実行時エラー380「プロパティの値が不正です」

RowSourceで既にセル範囲を指定しているリストボックスに対して、AddItemやListプロパティで追加の書き込みを行おうとすると発生することがあります。RowSourceによる「連動」とAddItem等による「個別追加」は同時に使えないという制約があるためです。

⚠️ RowSourceとAddItemは混在させない

RowSourceでセル範囲を指定したリストボックスに対して、さらにAddItemで項目を追加しようとすると、実行時エラーや意図しない挙動の原因になります。「RowSourceで連動させる」か「AddItem/Listで個別に組み立てる」かは、初期化の設計段階でどちらか一方に決めておくことをお勧めします。

7-3. フォームを開き直すたびに選択肢が重複する

エラーメッセージは出ないものの実務でよくあるトラブルが、フォームを再度開くたびにリストの項目が二重・三重に増えていくという現象です。これは、UserForm_InitializeでAddItemを実行する際に、既存の項目をClearしないまま追加していることが原因です。

' NG例:Clearを忘れると開くたびに項目が増える
Private Sub UserForm_Initialize()
    Dim i As Long
    For i = 1 To 10
        ListBox1.AddItem Worksheets("Sheet1").Cells(i, 1).Value
    Next i
End Sub

' OK例:追加前に必ずClearする
Private Sub UserForm_Initialize()
    Dim i As Long
    ListBox1.Clear
    For i = 1 To 10
        ListBox1.AddItem Worksheets("Sheet1").Cells(i, 1).Value
    Next i
End Sub
💡 初期化処理の鉄則

AddItemやList配列代入でリストボックスを初期化する処理は、必ず先頭でListBox1.Clearを実行してから項目を追加する習慣にしてください。これだけで「開き直すたびに項目が重複する」というトラブルの大半は防げます。

エラー発生
実行時エラー
メッセージを確認
ListIndexを疑う
-1(未選択)で
アクセスしていないか
初期化方法を疑う
RowSourceとAddItemが
混在していないか
Clear忘れを疑う
開き直すたびに
項目が増えていないか
代表菅澤 代表菅澤
VBAのエラーは、慣れてくると「あ、これはいつものパターンだ」と原因の見当がつくようになります。ただ、その「勘」を持っている人が社内に1人しかいない、というケースを本当によく見かけます。次の章では、この「属人化」の話をします。

08 【独自】VBAマクロが「属人化」する構造的リスク 動くコードと、保守できる組織は別の問題

ここまで、リストボックスの使い方を技術的に解説してきました。ここからは少し視点を変えて、「このマクロを、誰が長く保守していくのか」という経営・組織側の問題を取り上げます。多くの現場で見落とされがちですが、実はここが最も大きなリスクです。

8-1. なぜVBAマクロは属人化しやすいのか

VBAマクロやUserFormを使った入力システムは、多くの場合「業務に詳しい特定の1人」が独学で作り上げるという経緯をたどります。その人にとっては使い慣れた資産でも、組織全体から見ると次のようなリスクを抱えています。

✔️作成した本人しかコードの構造を理解しておらず、修正できる人が社内に1人しかいない
✔️コードにコメントが少なく、後任者が読んでも意図が分からない
✔️バージョン管理(Gitのような変更履歴の仕組み)がされておらず、「いつ・誰が・何を変えたか」が追えない
✔️作成者が異動・退職すると、エラーが出ても誰も直せず、業務そのものが止まる

📚 用語解説

属人化:特定の業務やシステムの運用・保守が、特定の担当者の知識やスキルに依存してしまい、その人がいないと業務が回らなくなる状態のこと。VBAマクロは「動けば良い」という性質上、コメントや設計文書が省略されがちで、属人化が起きやすい典型例です。

8-2. 「動くコード」と「保守できる組織」は別の問題

この記事で紹介したリストボックスの初期化や複数選択の処理も、正直なところ「1回動くコードを書く」だけならそれほど難しくありません。難しいのは、そのコードを半年後・1年後に別の人が読んで、正しく修正できる状態を保つことです。

弊社(株式会社GENAI)でも、社内のExcel業務効率化のためにマクロやスクリプトを組む場面が日常的にありますが、以前は「作った人しか触れない」状態のコードが積み上がっていく問題を抱えていました。これはVBAに限らず、業務効率化のために書かれた小規模なコード全般に共通する課題です。

⚠️ 属人化コストは「見えない負債」になりやすい

マクロが問題なく動いている間は、属人化のリスクは表面化しません。しかし作成者が異動・退職した瞬間に「誰も直せない」「仕様が分からない」という形で一気に顕在化します。日頃から「このマクロ、自分以外に誰が触れるか」を意識しておくことが、地味ですが最も有効なリスク対策です。

AI鬼管理山崎 AI鬼管理山崎
属人化対策というと「マニュアルを整備しよう」という話になりがちですが、マニュアル自体を作る・更新するのも結局は人の工数がかかります。ここ数年で状況が変わってきたのは、コード自体の説明や修正を、AIエージェントに任せられるようになったことです。

09 【独自】フォーム開発をAIエージェントに任せる時代へ VBAの読解・修正・ドキュメント化をClaude Codeに任せる考え方

前章で触れた「属人化」の問題に対して、近年現実的な選択肢になってきたのがAIコーディングエージェントの活用です。ここでは、Anthropic社が提供するClaude Codeを例に、VBAのようなレガシーな社内システムの保守にAIエージェントをどう組み込めるかを紹介します。

📚 用語解説

Claude Code(クロードコード):Anthropic社が提供するAIコーディングエージェント。人間が「このマクロのエラーを直して」「このコードにコメントを付けて仕様書を作って」といった自然な言葉で指示すると、AIがファイルを読み込み、修正案を提示・実行してくれるツール。従来のチャット型AIと異なり、実際にファイルの読み書きや複数手順の作業を自律的に進められる点が特徴です。

9-1. 属人化した既存VBAコードの「読解」をAIに任せる

属人化の最大の問題は「誰もコードを読めない・意図が分からない」ことでした。この点、Claude CodeのようなAIエージェントは既存のVBAコードを読み込み、処理内容を自然な日本語で説明することが得意です。「このリストボックスの初期化処理は何をしているか説明して」と尋ねれば、AddItemなのかRowSourceなのか、どのセル範囲を参照しているのかまで含めて言語化してくれます。

これにより、後任者が過去のマクロを引き継ぐ際に、作成者本人に確認しなくてもコードの意図を把握できるようになります。属人化対策として最も工数がかかっていた「仕様の言語化」を、AIエージェントに代行させられるということです。

9-2. 新規フォーム・リストボックスの実装もAIに指示できる

読解だけでなく、新しいUserFormやリストボックスの実装自体も、AIエージェントに任せられる範囲が広がっています。「担当者一覧をリストボックスで複数選択できるフォームを作って」といった業務要件を自然言語で伝えるだけで、AddItemやMultiSelectを含むコードの叩き台を生成させることが可能です。人間の役割は、生成されたコードをレビューし、業務要件と合っているかを確認することに変わります。

Step 1
業務要件を
自然言語で伝える
Step 2
AIがコードの
叩き台を生成
Step 3
人間が動作確認・
レビューする
Step 4
仕様書・コメントも
AIに整備させる
💡 レガシーマクロの棚卸しにも活用できる

社内に「誰が作ったか分からない」「動いているが仕様不明」というマクロが眠っている場合、Claude Codeにコードを読み込ませて仕様書化させておくと、属人化のリスクを下げられます。動いているマクロを壊さずに、まず「説明できる状態」にすることが第一歩です。

9-3. GENAI社内での実運用(参考値)

弊社(株式会社GENAI)では、Claude Max 20xプラン(月額$200・約30,000円)を契約し、経営・営業・広告・開発・経理・秘書業務まで社内のあらゆる業務でClaude Codeを活用しています。開発領域では、WordPressやLP制作、業務効率化のためのスクリプトを都度書いては使い捨てる運用が中心で、コードを書く工数自体を大きく圧縮できている肌感です。

もちろん、AIが生成したコードをそのまま無条件に信用するのではなく、人間による最終レビューは必須です。特にExcelマクロは業務データを直接扱うため、生成されたコードが意図通り動くかの確認工程は省略できません。それでも、「ゼロから調べながら書く」「属人化した過去のコードを1行ずつ追う」といった作業の初速を、AIエージェントが大きく引き上げてくれるのは実感として間違いありません。

🏆
VERDICT
使い分けが正解
コードを書く速度はAIエージェント、業務要件との整合性の最終確認は人間。役割分担が現実的な落としどころ。
代表菅澤 代表菅澤
VBAのリストボックス1つ実装するだけなら、正直誰がやっても大差はありません。ただ「社内に10本・20本とマクロが積み上がった状態を、誰がどう保守していくか」という規模になると、AIエージェントを組み込んだ運用体制があるかどうかで、数年後の保守コストが大きく変わってきます。
Claude Code 完全解説セミナー|経営者・会社役員専用 1on1 60分 無料Claude Codeを経営に活かしたい方へ — AI鬼管理

10 まとめ リストボックスの使い方から、保守体制の作り方まで

この記事では、VBAのリストボックスについて、基本的な配置方法から初期化・値取得・複数選択・主要プロパティ・エラー対策まで、実務で使えるコード例つきで解説しました。最後にポイントを振り返ります。

✔️リストボックスは選択肢を常に一覧表示するコントロール。省スペースが必要ならコンボボックス
✔️初期化はAddItem/RowSource/List配列代入の3方式。用途に応じて使い分ける
✔️値の取得はListIndexの-1チェックが最重要。未選択のままアクセスするとエラー381になる
✔️複数選択はMultiSelectプロパティを設定し、Selected配列をループで確認して取得する
✔️よくあるエラー(381・380・重複)は原因パターンがほぼ決まっているため、対処法を型として覚える
✔️VBAマクロは属人化しやすい構造的リスクを抱えており、保守体制の設計が本質的な課題
✔️コードの読解・実装・仕様書化をAIエージェントに任せることで、属人化リスクを下げる選択肢が現実的になっている

リストボックス自体の実装は、この記事のコード例をベースにすれば十分に対応できるはずです。一方で、「このマクロを長期的に誰が保守するのか」という問いに答えを持っている会社は、実はまだ多くありません。VBAに限らず、社内の業務効率化コードをどう資産として残していくか、AIエージェントの活用も含めて検討してみることをお勧めします。

AI鬼管理山崎 AI鬼管理山崎
弊社では「AI鬼管理」というサービスで、Claude Codeを使った業務自動化の設計から、既存の業務プロセスの棚卸し・伴走支援まで行っています。「社内に眠っているマクロや業務ツールをどう整理すればいいか分からない」という段階でも、無料相談でお気軽にご相談いただけます。

VBAマクロの保守・AIエージェント活用を、AI鬼管理が一緒に設計します

「作った人しか触れないマクロ」を、AIエージェントで説明可能・修正可能な状態に。
弊社の実運用ノウハウをベースに、個別に導入設計のご相談を承ります。

代表菅澤 代表菅澤
「社内のExcel業務・VBAマクロをどう引き継げばいいか分からない」という方に最適です。まずは無料相談で、貴社の業務の中でAI活用のインパクトが大きい領域を一緒に見つけましょう。

NEXT STEP

この記事の内容を、あなたのビジネスで
実践してみませんか?

AI活用を自社で回せるようになりたい方へ

AI鬼管理

Claude Code・Cowork導入支援から業務設計・社内浸透まで実践ベースで伴走。「自社で回せる組織」を90日で作る経営者向けトレーニング。

よくある質問

Q. リストボックスとコンボボックスは結局どちらを使えばいいですか?

A. 選択肢を常に一覧表示させたい場合や、複数の項目を同時に選ばせたい場合はリストボックスが適しています。逆に、選択肢の数が多くて画面スペースを節約したい場合や、単一選択で十分な場合はコンボボックスの方が使いやすいです。フォームのレイアウトと「複数選択が必要かどうか」の2点で判断すると迷いにくくなります。

Q. AddItemとRowSource、どちらで初期化するのが正解ですか?

A. どちらも正解になり得ますが、性質が異なります。RowSourceはセル範囲とコードの記述量が最小で済む一方、条件分岐しながら項目を組み立てるような柔軟な処理には向きません。AddItemやList配列代入はコード量は増えますが、条件付きの動的な項目組み立てがしやすく、実行速度も安定します。用途に応じて使い分けるのが実務での基本です。

Q. リストボックスで何も選択されていないかどうかはどう判定しますか?

A. ListIndexプロパティを確認します。何も選択されていない状態ではListIndexが-1になるため、条件分岐で「If ListBox1.ListIndex = -1 Then」のように判定します。この確認を行わずにList(ListIndex)などにアクセスすると、実行時エラー381(オブジェクト配列のインデックスが有効範囲にありません)が発生するため、値を取得する処理の先頭には必ずこのチェックを入れてください。

Q. 複数選択したリストボックスから、選択された全項目を取得する方法を教えてください。

A. MultiSelectプロパティを有効にした状態では、ListIndexやValueで単一の値を取得することはできません。代わりに、For文でListCount回ループを回しながら、Selected(i)プロパティがTrueかどうかを1件ずつ確認し、Trueだった項目のList(i)を配列や文字列に集める処理を書きます。この記事のサンプルコードをそのまま流用できます。

Q. フォームを何度も開くとリストの項目が増えていくのはなぜですか?

A. UserForm_Initializeイベント内でAddItemを実行する際に、既存の項目をClearしないまま追加を繰り返していることが原因です。フォームを開くたびにInitializeイベントが実行されるため、Clearを挟まないと項目が二重・三重に積み上がっていきます。AddItemやList代入の直前に必ずListBox1.Clearを実行することで解消します。

Q. リストボックスに複数列(IDと名称など)を表示させることはできますか?

A. 可能です。ColumnCountプロパティを2以上に設定したうえで、AddItemで1列目を追加した後にList(行番号, 列番号)の形式で2列目以降の値を個別に設定します。列幅はColumnWidthsプロパティで調整でき、実際に取得する値の列はBoundColumnプロパティで指定できます。ID・名称のペアを表示しつつ、Valueで取得するのはIDだけ、といった制御が可能です。

Q. VBAマクロの保守が属人化してしまった場合、何から手をつければいいですか?

A. まず、現在動いているマクロの一覧と、それぞれの目的・使用頻度を洗い出すところから始めます。次に、コードの意図が分からないものについては、AIコーディングエージェントにコードを読み込ませて仕様を言語化させるのが効率的です。すべてを一度に作り直す必要はなく、「使用頻度が高く、担当者が1人しかいないマクロ」から優先的に説明可能な状態にしていくのが現実的な進め方です。

AIAI鬼管理

AI鬼管理へのお問い合わせ

この記事を読んで気になった方へ。
AI鬼管理の専門スタッフが、御社に最適な
業務自動化プランを無料でご提案します。

会社名を入力してください
業種を選択してください
お名前を入力してください
※法人・事業用のメールアドレスでお願いします(Gmail等の個人用フリーメールは受付できません)
正しいメールアドレスを入力してください

1つ以上選択してください
1つ以上選択してください
月額コストを選択してください

約1時間のオンライン面談(Google Meet)です

空き枠を取得中...
面談日時を選択してください

予約確定後、Google Calendarの招待メールをお届けします。
しつこい営業は一切ございません。

監修 最終更新日: 2026年8月3日
菅澤孝平
菅澤 孝平 株式会社GENAI 代表取締役
  • AI業務自動化サービス「AI鬼管理」を運営 — Claude Code を活用し、経営者の業務を「AIエージェントに任せる仕組み」へ転換するパーソナルトレーニングを 伴走構築 で提供。日報・採用・問い合わせ対応・経費精算・議事録・データ集計・営業リスト等の定型業務を、AIに代行させる体制を経営者と一緒に作り込む
  • Claude Code 実装ノウハウを 経営者・法人クライアント に直接指導。生成AIを「便利ツール」ではなく 「業務を任せる存在」 として運用する手法を体系化
  • 「やらせ切る管理」メソッドの開発者。シンゲキ株式会社(2021年設立・鬼管理専門塾運営)にて累計3,000名以上の学習者を志望校合格に導いた管理メソッドを、AI × 経営者支援 に転用
  • 著書『3カ月で志望大学に合格できる鬼管理』(幻冬舎)、『親の過干渉こそ、最強の大学受験対策である。』(講談社)
  • メディア出演: REAL VALUE / カンニング竹山のイチバン研究所 / ええじゃないかBiz 他
  • 明治大学政治経済学部卒
現在は AI鬼管理(Claude Code活用の伴走型パーソナルトレーニング)を主事業とし、経営者と二人三脚で「AIに業務を任せる仕組み」を実装。「実行を強制する環境」を AI で構築する手法を、自社の実運用知見をもとに発信している。