プログラミング未経験者でも安心!Excelなどを自動化するVBAのすべてを学べる完全ガイドです。基本から実践的な応用例まで、50のステップで効率的に習得できます。
VBAはVisual Basic for Applicationsの略で、マイクロソフトが開発したプログラミング言語です。Office製品に組み込まれています。
ExcelやWordなどのOfficeアプリケーションを自動化し、繰り返し作業を効率化する強力なツールです。
マクロは操作を記録する機能、VBAはより柔軟なプログラミング言語です。VBAはマクロよりも高度な自動化が可能です。
2023年現在でも、多くの企業でレガシーシステムや日常業務の自動化に広く活用されています。
Microsoft Office(Excel、Word、Accessなど)がインストールされていることを確認しましょう。最新版でなくても問題ありませんが、2010以降のバージョンをお勧めします。
リボンの右クリック→「リボンのユーザー設定」→「開発」にチェックを入れます。これによりVBAエディタにアクセスするための「開発」タブが表示されます。
開発タブ→「マクロのセキュリティ」から、「すべてのマクロを有効にする」または「デジタル署名されたマクロを有効にする」を選択します。学習中は一時的に緩めの設定にしておくと便利です。
開発タブ→「マクロの記録」をクリックし、マクロ名を入力後、保存場所(個人用マクロブック/この本/新しいブック)を選びます。記録を終了するには「記録終了」ボタンをクリックします。
「相対参照を使用」ボタンをオンにすると、セルの相対的な位置関係が記録されます。オフの場合は絶対的なセル位置が記録されます。表の処理に適しているのは相対参照です。
開発タブ→「マクロ」から実行できます。記録されたマクロは「編集」ボタンからVBAエディタで内容を確認・修正できます。これがVBA学習の第一歩になります。
Visual Basic Editorは開発タブの「Visual Basic」ボタンから開きます。コードウィンドウ、プロジェクトエクスプローラ、プロパティウィンドウなどで構成されています。
「挿入」メニューから新しいモジュールを追加できます。モジュールはコードを保存・整理する場所で、関連する機能ごとに分けるとよいでしょう。
左側のツリー表示でプロジェクト内のすべてのモジュール、フォーム、参照設定などを確認・管理できます。ダブルクリックで対象を開きます。
F4キーで表示されるウィンドウで、選択したオブジェクトのプロパティを表示・変更できます。フォームやコントロールの設定に重要です。




VBAでは変数を使ってデータを保存します。データ型には数値(Integer、Long)、文字列(String)、日付(Date)などがあります。例:
Dim 名前 As String
Dim 年齢 As IntegerSubはプロシージャ(処理)、Functionは値を返す関数を定義します。例:
Sub 挨拶()
MsgBox "こんにちは"
End Sub変数は値を格納するための「箱」で、プログラム内でデータを管理するために使用します。適切なデータ型を選ぶことでメモリ効率とエラー防止になります。スコープは変数が有効な範囲を示し、必要最小限にすることが良い習慣です。
条件が真の場合のみ処理を実行
条件が真なら処理A、偽なら処理B
複数の条件を順に評価
If文の中にさらにIf文
' 単純なIf-Then
If 年齢 >= 20 Then
MsgBox "成人です"
End If
' If-Then-Else
If 点数 >= 60 Then
MsgBox "合格"
Else
MsgBox "不合格"
End If
' ElseIf
If 点数 >= 80 Then
等級 = "A"
ElseIf 点数 >= 60 Then
等級 = "B"
Else
等級 = "C"
End If
Select Case 評価式
Case 値1
' 値1の場合の処理
Case 値2
' 値2の場合の処理
Case Else
' どの値にも一致しない場合
End Select一つの変数や式に対して複数の値をチェックする場合、If文よりも読みやすく効率的です。
Select Case 得点
Case 90 To 100
評価 = "優"
Case 70 To 89
評価 = "良"
Case 60 To 69
評価 = "可"
Case Else
評価 = "不可"
End Select範囲指定(To)や複数値(,区切り)、Is演算子も使えます。複雑な条件分岐ではSelect Caseが適しています。
For i = 1 To 100: Next i の形で指定回数繰り返し
Step 2 で2つずつ増加(1,3,5...)
条件付きでループを抜ける
' 基本的なFor Next
For i = 1 To 10
Cells(i, 1).Value = i
Next i
' ステップ値を使う
For i = 10 To 1 Step -1
Debug.Print i ' 10から1までカウントダウン
Next i
' 条件付きでループを抜ける
For i = 1 To 1000
If Cells(i, 1).Value = "終了" Then
Exit For ' "終了"が見つかったらループを抜ける
End If
Next i
指定条件がTrueの間繰り返し
ループ内の処理を実行
条件に影響する値を更新
条件を再評価し継続か終了か決定
' Do While(最初に条件チェック)
Do While 残高 > 0
残高 = 残高 - 支出
月数 = 月数 + 1
Loop
' Do Until(条件がFalseの間繰り返し)
Do Until 完了フラグ = True
処理実行
If 条件 Then 完了フラグ = True
Loop
' Do-Loop While(最後に条件チェック)
Do
入力値 = InputBox("数値を入力してください")
Loop While Not IsNumeric(入力値)
For Eachループはコレクション(セル範囲、ファイル一覧など)の各要素に対して同じ処理を行う場合に最適です。要素数を事前に知る必要がなく、コードも簡潔になります。
選択範囲内の各セルに対する処理が簡単に書けます。For-Nextで行・列を指定するよりも直感的で、コードの可読性が高まります。
ワークシート、ブック、フォルダ内のファイルなど、様々なコレクションに適用できます。オブジェクト変数の型は適切に設定しましょう。
' 選択範囲内の全セルを処理
For Each セル In Selection
If セル.Value < 0 Then
セル.Font.Color = vbRed
End If
Next セル
' すべてのワークシートを処理
For Each シート In ThisWorkbook.Worksheets
シート.Cells(1, 1).Value = "会社名"
Next シート
エラーが発生してもコードの実行を続けます。エラーを無視したい場合や、エラーの可能性がある複数の処理を連続して行う場合に使用します。ただし、エラーの原因を特定しにくくなるので注意が必要です。
エラーが発生した場合、指定したラベルの場所にジャンプします。エラー情報を取得して適切に対応するコードを書くことができます。最も一般的なエラーハンドリング方法です。
Sub データ処理()
On Error GoTo エラー処理
' 処理コード
Exit Sub
エラー処理:
MsgBox "エラーが発生しました: " & Err.Description
End Sub
エラーハンドリングをリセットし、標準のエラー処理に戻します。一部の処理だけ特別なエラーハンドリングをした後、元に戻す場合に使用します。
Sub 給与計算(社員ID As String)
' 処理コード
MsgBox "計算完了"
End Sub値を返さない処理を実行します。単独で実行できるプロシージャで、ボタンクリックなどのイベントに紐づけることもできます。
Function 消費税計算(金額 As Long) As Long
消費税計算 = 金額 * 0.1
End Function処理結果を値として返します。Excelのセル内で関数として使用したり、他のコードから呼び出して結果を変数に格納したりできます。
再利用可能なコードを書くためには、一つのプロシージャに一つの機能を持たせ、適切な名前を付けることが重要です。引数を活用して柔軟な処理を実現しましょう。
Sub 処理(ByVal 数値 As Integer)
数値 = 数値 * 2
' 元の変数は変更されない
End Sub引数の値のコピーがプロシージャに渡されます。プロシージャ内で値を変更しても、呼び出し元の変数は変更されません。
Sub 処理(ByRef 数値 As Integer)
数値 = 数値 * 2
' 元の変数も変更される
End Sub引数の参照(メモリ上の位置)がプロシージャに渡されます。プロシージャ内での変更が呼び出し元の変数にも反映されます。VBAの既定値はByRefです。
Sub 挨拶(名前 As String, Optional 敬称 As String = "様") のように、省略可能な引数を設定できます。既定値を指定しておくと便利です。
Sub 合計(ParamArray 数値() As Variant) のように、任意の数の引数を受け取ることができます。
Excelアプリケーション自体
Excelファイル
ワークシート(シート)
セルまたはセル範囲
' オブジェクト参照の例
Application.Calculation = xlManual ' 計算方法の設定
Workbooks("売上.xlsx").Open ' ブックを開く
Worksheets("集計").Activate ' シートをアクティブにする
Range("A1:C10").ClearContents ' 範囲の内容をクリア
Cells(1, 2).Value = "項目名" ' 1行2列(B1)に値を設定
各オブジェクトには多数のプロパティ(属性)とメソッド(操作)があります。オブジェクト変数を使うと、コードが読みやすくなり効率も向上します。例:
Dim ws As Worksheet
Set ws = Worksheets("集計")
ws.Range("A1").Value = "合計"セルの値は .Value プロパティで取得できます。数式は .Formula、表示されている文字列は .Text プロパティを使います。
変数 = Range("A1").Value
変数 = Cells(1, 1).Value ' A1と同じ同様に .Value プロパティに代入することで値を設定できます。数式は .Formula に文字列で設定します。
Range("B2").Value = 100
Cells(2, 2).Formula = "=SUM(A1:A10)"フォントや色、罫線などの書式は様々なプロパティで設定できます。
Range("C3").Font.Bold = True
Range("C3").Interior.Color = RGB(255, 255, 0) ' 黄色特定のセル範囲を選択したり、条件に基づいて範囲を取得したりできます。
Range("A1:C10").Select
Range(Cells(1, 1), Cells(10, 3)).Select ' 同じ範囲
Rangeは多様な指定方法があります:
Range("A1") ' 単一セル
Range("A1:C5") ' 矩形範囲
Range("A1,C3,E5") ' 不連続範囲
Range("A:A") ' A列全体
Range("1:1") ' 1行全体
Range("TestName") ' 名前付き範囲データの量に応じて範囲を動的に決定できます:
' A列の使用範囲を取得
Set 範囲 = Range("A1").CurrentRegion
' 最終行を検出
最終行 = Cells(Rows.Count, 1).End(xlUp).Row
' 最終行までの範囲を設定
Set 範囲 = Range("A1:C" & 最終行)特定の条件に基づく高度な範囲操作:
' 条件付き書式の適用
Range("A1:D10").FormatConditions.Add _
Type:=xlCellValue, Operator:=xlGreater, _
Formula1:="100"
' 特定値のセルを検索
Set 検索結果 = Columns("A").Find("山田")シートの追加、削除、名前変更などを行えます。
Worksheets.Add.Name = "集計表"
Worksheets("Sheet1").Delete
Worksheets("Sheet2").Name = "データ"シート間でデータをコピーしたり移動したりできます。
Worksheets("元").Range("A1:C10").Copy _
Destination:=Worksheets("先").Range("D1")ブックの保存、閉じる、新規作成などの操作ができます。
ThisWorkbook.SaveAs "新ファイル名.xlsx"
Workbooks.Add
Workbooks.Open "C:\Data\売上.xlsx"
Workbooks("Book1").Close SaveChanges:=True異なるブック間でデータを転送できます。
Workbooks("元.xlsx").Worksheets("Sheet1"). _
Range("A1:C10").Copy _
Destination:=Workbooks("先.xlsx"). _
Worksheets("Sheet1").Range("A1")VBEの「挿入」メニューから「ユーザーフォーム」を選択すると、新しいフォームが作成されます。フォームのサイズや名前はプロパティウィンドウで変更できます。
ツールボックスから必要なコントロール(ボタン、テキストボックスなど)をフォームにドラッグ&ドロップします。各コントロールのプロパティは選択後に調整できます。
コントロールをダブルクリックすると、そのデフォルトイベント(ボタンならClick)のプロシージャが生成されます。そこにコードを書いて動作を定義します。
VBAコードからフォームを表示するには「UserForm1.Show」のように記述します。モーダル表示が基本ですが、vbModelessでノンモーダル表示も可能です。




TextBox(テキスト入力)とLabel(説明表示)が基本です。TextBox.Valueでテキストの取得や設定ができます。TextBox.PasswordCharで入力を*などに置換できます。
ComboBox(ドロップダウンリスト+入力)とListBox(複数選択可)でリスト選択を実現します。項目はAddItem/Listプロパティで設定します。
CheckBox(オン/オフ)とOptionButton(排他的選択)で選択肢を提供します。グループ化にはFrame(枠)が便利です。
フォームが読み込まれるときに実行されます。コンボボックスへの項目追加や初期値設定などを行います。
Private Sub UserForm_Initialize()
ComboBox1.Clear
ComboBox1.AddItem "東京"
ComboBox1.AddItem "大阪"
TextBox1.Value = ""
End Subボタンなどがクリックされたときに実行されます。ユーザー操作に対する応答を定義します。
Private Sub CommandButton1_Click()
' OKボタンの処理
If TextBox1.Value = "" Then
MsgBox "名前を入力してください"
Else
' データ処理
Me.Hide ' フォームを非表示に
End If
End Subテキストボックスやコンボボックスの値が変更されたときに実行されます。入力値の検証や関連項目の更新などに使用します。
Private Sub TextBox1_Change()
' 入力値に応じた処理
If IsNumeric(TextBox1.Value) Then
Label1.Caption = "数値です"
Else
Label1.Caption = "文字列です"
End If
End Subフォームが閉じられるときに実行されます。リソースの解放や最終処理を行います。
Private Sub UserForm_Terminate()
' フォーム終了時の処理
Debug.Print "フォームが閉じられました"
End Sub' ファイルをオープン
Open "C:\Data\input.txt" For Input As #1
' 処理コード
Close #1 ' ファイルを閉じる
Forキーワードの後にアクセスモードを指定します: ・Input:読み取り専用 ・Output:書き込み(新規作成) ・Append:追記 ・Binary:バイナリアクセス
' テキスト読み込み
Open "input.txt" For Input As #1
Do Until EOF(1)
Line Input #1, テキスト行
Debug.Print テキスト行
Loop
Close #1
' テキスト書き込み
Open "output.txt" For Output As #2
Print #2, "データ1"
Print #2, "データ2"
Close #2
CSV処理では、Split関数で分割、Join関数で結合が便利です。
ADO(ActiveX Data Objects)を使ってデータベースに接続します。
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Data\顧客.accdb"
cn.OpenSQL文を使ってデータの検索や更新を行います。
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open "SELECT * FROM 顧客 WHERE 地域='東京'", cn取得したレコードセットを処理します。
Do Until rs.EOF
Debug.Print rs!顧客名 & ", " & rs!電話番号
rs.MoveNext
Loopリソースを解放して接続を閉じます。
rs.Close
cn.Close
Set rs = Nothing
Set cn = NothingADOを使用するには、VBEの「ツール」→「参照設定」から "Microsoft ActiveX Data Objects x.x Library" を参照設定に追加してください。
ADOを使用してAccessデータベースに接続します。ACEプロバイダ(新しいAccess)またはJetプロバイダ(古いAccess)を選びます。
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Data\社員.accdb"
cn.OpenSQLを使ってテーブルのデータを操作します。SELECT, INSERT, UPDATE, DELETEなどが使用できます。
Set rs = cn.Execute("SELECT * FROM 社員マスタ")
' または
cn.Execute "UPDATE 社員マスタ SET 部署='営業' WHERE ID=123"取得したデータをExcelシートに転送します。レコードセットのすべてのフィールドとレコードを処理します。
' ヘッダー行の作成
For i = 0 To rs.Fields.Count - 1
Cells(1, i + 1).Value = rs.Fields(i).Name
Next i
' データの転送
Set シート = Worksheets("データ")
行番号 = 2
Do Until rs.EOF
For i = 0 To rs.Fields.Count - 1
シート.Cells(行番号, i + 1).Value = rs(i)
Next i
行番号 = 行番号 + 1
rs.MoveNext
Loop' 検索クエリの実行
Set rs = cn.Execute("SELECT * FROM 顧客 " & _
"WHERE 都道府県 = '東京都'")
' 更新クエリの実行
cn.Execute "UPDATE 在庫 SET 数量 = 数量 - 10 " & _
"WHERE 商品コード = 'A001'"
' レコード追加
cn.Execute "INSERT INTO 履歴 " & _
"(日付, 担当者, 内容) VALUES " & _
"(#" & Date & "#, '山田', '電話対応')"
' パラメータ化クエリ(SQL注入対策)
Dim cmd As ADODB.Command
Set cmd = New ADODB.Command
cmd.ActiveConnection = cn
cmd.CommandText = "SELECT * FROM 顧客 " & _
"WHERE 都道府県 = ?"
Dim prm As ADODB.Parameter
Set prm = cmd.CreateParameter("都道府県", _
adVarChar, adParamInput, 10, "東京都")
cmd.Parameters.Append prm
Set rs = cmd.Execute
' 静的配列(サイズ固定)
Dim 数値(1 To 5) As Integer
数値(1) = 10
数値(2) = 20
' 動的配列(サイズ可変)
Dim 名前() As String
ReDim 名前(1 To 10)
名前(1) = "鈴木"
' 初期値の一括設定
Dim 曜日(1 To 7) As String
曜日 = Array("日", "月", "火", "水", "木", "金", "土")
' 配列サイズの拡張
ReDim Preserve 名前(1 To 20)
' Preserveを付けると既存データを保持
' 多次元配列
Dim マトリックス(1 To 3, 1 To 3) As Integer
マトリックス(1, 1) = 100
マトリックス(2, 3) = 200
' 配列のクリア
Erase 数値
大量のセル値を扱う場合、一時的に配列に読み込み処理後、まとめて書き戻すと高速化できます。
Dim データ() As Variant
データ = Range("A1:Z100").Value ' 一括読み込み
' データ処理
Range("A1:Z100").Value = データ ' 一括書き込みLBound関数とUBound関数で配列の下限と上限を取得できます。特定の次元も指定可能です。
最小添字 = LBound(数値)
最大添字 = UBound(数値)
行数 = UBound(マトリックス, 1)
列数 = UBound(マトリックス, 2)



Collectionオブジェクトは動的に項目を管理できる汎用的なコンテナです。
Dim コレクション As New Collection
' 項目の追加
コレクション.Add "項目1", "Key1" ' キーは省略可能
コレクション.Add "項目2"
' 項目の取得
MsgBox コレクション(1) ' インデックスで取得(1始まり)
MsgBox コレクション("Key1") ' キーで取得
' 項目の削除
コレクション.Remove 1 ' インデックスで削除配列との主な違いは、動的な追加・削除が容易なこと、キーによるアクセスが可能なこと、インデックスが1から始まることです。For Eachループとの相性も良好です。
重複チェック、名前付きデータの管理、一時的なデータの集約などに適しています。ただし、大量データの処理では配列の方が高速な場合があります。
VBEの「ツール」→「参照設定」から "Microsoft Scripting Runtime" を選択してチェックを入れます。これによりDictionaryオブジェクトが使用可能になります。
キーと値のペアでデータを管理します。キーは一意である必要があります。
Dim 辞書 As New Scripting.Dictionary
' 項目の追加
辞書.Add "A001", "ノートパソコン"
辞書.Add "B002", "プリンタ"
' または直接代入
辞書("C003") = "マウス"
' 値の取得
MsgBox 辞書("A001") ' ノートパソコン
' 存在確認
If 辞書.Exists("D004") Then MsgBox "存在します"
' 削除
辞書.Remove "B002"すべてのキーと値を取得して処理できます。
Dim キー配列 As Variant
キー配列 = 辞書.Keys ' すべてのキーを配列で取得
For i = 0 To 辞書.Count - 1
Debug.Print キー配列(i) & ": " & 辞書(キー配列(i))
Next i高速な検索が必要な場合や、複雑なデータ構造を管理する場合に便利です。例えば商品コードと情報の対応付け、一意なIDでのデータ管理などに適しています。
現在日付 = Date() ' 2023/9/18 など
現在時刻 = Time() ' 15:30:45 など
日時両方 = Now() ' 2023/9/18 15:30:45
' 日付の作成
特定日 = DateSerial(2023, 9, 18)
特定時刻 = TimeSerial(15, 30, 0)明日 = Date() + 1
来週 = Date() + 7
来月 = DateAdd("m", 1, Date())
前日 = DateAdd("d", -1, Date())
' 日数の差分
経過日数 = DateDiff("d", 開始日, 終了日)
経過月数 = DateDiff("m", 開始日, 終了日)
経過年数 = DateDiff("yyyy", 開始日, 終了日)短い日付 = Format(Date(), "yyyy/mm/dd")
長い日付 = Format(Date(), "yyyy年m月d日")
曜日付き = Format(Date(), "yyyy年m月d日 (aaa)")
時刻表示 = Format(Now(), "hh:nn:ss")' 平日のみカウント
平日数 = 0
For i = 開始日 To 終了日
If Weekday(i) <> vbSunday And _
Weekday(i) <> vbSaturday Then
平日数 = 平日数 + 1
End If
Next i' CSVデータの解析
データ = "鈴木,30,東京"
項目 = Split(データ, ",")
名前 = 項目(0) ' 鈴木
年齢 = 項目(1) ' 30
地域 = 項目(2) ' 東京
' 文字の置換
住所 = "東京都港区青山1-2-3"
県名 = Left(住所, InStr(住所, "都") - 1) ' 東京
' 文字列整形
コード = "000123"
表示用 = Right("000000" & 番号, 6) ' 6桁に整形
' 正規表現の利用には参照設定が必要
' Microsoft VBScript Regular Expressions
Dim regex As New RegExp
regex.Pattern = "\d{3}-\d{4}" ' 郵便番号パターン
regex.Global = True
' マッチング確認
If regex.Test("123-4567") Then
MsgBox "郵便番号の形式です"
End If
' 一致箇所の抽出
Set matches = regex.Execute("問い合わせ先: 123-4567")
For Each m In matches
MsgBox m.Value ' 123-4567
Next
グラフの元になるデータ範囲を指定します。動的に範囲を決定することも可能です。
Dim データ範囲 As Range
Dim 終了行 As Long
終了行 = Cells(Rows.Count, 1).End(xlUp).Row
Set データ範囲 = Range("A1:C" & 終了行)Charts.Addでグラフシートを作成するか、Shapes.AddChartでシート内にグラフを埋め込みます。
Dim グラフ As Chart
Set グラフ = Charts.Add
グラフ.SetSourceData Source:=データ範囲
' または埋め込みグラフ
Set グラフオブジェクト = ActiveSheet.Shapes.AddChart
Set グラフ = グラフオブジェクト.Chartグラフの種類を設定します。Excel VBAは多数のグラフ種類をサポートしています。
グラフ.ChartType = xlColumnClustered ' 棒グラフ
' または
グラフ.ChartType = xlLine ' 折れ線グラフ
' または
グラフ.ChartType = xlPie ' 円グラフタイトル、軸ラベル、凡例、色などを設定してグラフをカスタマイズします。
With グラフ
.HasTitle = True
.ChartTitle.Text = "売上推移"
.Axes(xlCategory).HasTitle = True
.Axes(xlCategory).AxisTitle.Text = "月"
.Axes(xlValue).HasTitle = True
.Axes(xlValue).AxisTitle.Text = "金額(千円)"
.HasLegend = True
.Legend.Position = xlLegendPositionBottom
End With画面更新や計算の一時停止で大幅に高速化
早期変数解放とデータ型最適化で節約
実装すべき基本的な高速化手法
' 処理開始前
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.DisplayStatusBar = False
' 処理コード
' 処理終了後に元に戻す
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.DisplayStatusBar = True
Application.StatusBar = False
' 早期のオブジェクト解放
Set obj = Nothing
' 配列の使用
Dim データ As Variant
データ = Range("A1:Z1000").Value
' 配列で処理
Range("A1:Z1000").Value = データ
' With構文の活用
With Worksheets("Sheet1")
.Range("A1").Value = "値1"
.Range("A2").Value = "値2"
End With
' 適切なデータ型の選択
Dim i As Long ' 大きい整数の場合
Dim フラグ As Boolean ' 真偽値
コードの特定の行で実行を一時停止します。行をクリックしてF9キーを押すか、行番号の左側の余白をクリックして設定します。赤い点で表示され、その行に到達すると実行が停止します。
F8キーで1行ずつコードを実行できます。プロシージャ内に入る場合はF8、飛ばす場合はShift+F8を使用します。Ctrl+F8で現在の行からプロシージャの終わりまで実行します。
変数や式の値を監視します。「表示」→「ウォッチウィンドウ」で表示し、「ウォッチ式の追加」で監視したい変数や式を追加できます。実行中の値の変化を確認できます。
Ctrl+Gで表示できます。コードの一部を即時実行したり、変数値を表示したりできます。「?変数名」と入力すると値が表示されます。デバッグ中の検証に便利です。
デバッグはコードの問題を特定・修正するための重要なスキルです。ブレークポイントを設定し、変数の値を確認しながらステップ実行することで、コードの動作を詳細に把握できます。
' 基本的なメッセージ表示
MsgBox "処理が完了しました"
' タイトル付きメッセージ
MsgBox "保存しますか?", vbQuestion, "確認"
' ボタンの種類を指定
結果 = MsgBox("続行しますか?", _
vbYesNoCancel + vbQuestion, "選択")
' 結果の判定
If 結果 = vbYes Then
' はいが選択された場合の処理
ElseIf 結果 = vbNo Then
' いいえが選択された場合の処理
Else
' キャンセルが選択された場合の処理
End If
' 基本的な入力ダイアログ
名前 = InputBox("名前を入力してください")
' タイトルと初期値付き
年齢 = InputBox("年齢を入力してください", _
"情報入力", "20")
' 入力値の検証
Do
入力値 = InputBox("数値を入力してください")
If 入力値 = "" Then
Exit Do ' キャンセル時
End If
Loop Until IsNumeric(入力値)
' Application.InputBoxは型指定が可能
範囲 = Application.InputBox( _
"範囲を選択してください", _
Type:=8) ' 8=Range
Excelの標準ダイアログを表示できます。例えばファイル選択ダイアログは:
Application.GetOpenFilename("Excelファイル (*.xlsx), *.xlsx")より複雑な入力が必要な場合は、ユーザーフォームを作成します。これにより複数の入力フィールドやコントロールを配置した専用画面が作れます。
VBEの「挿入」→「クラスモジュール」で新しいクラスを作成します。クラス名は「プロパティ」ウィンドウで「Name」プロパティを変更して設定します。
クラスのデータ属性を定義します。
Private m社員ID As String
Private m氏名 As String
Public Property Get 社員ID() As String
社員ID = m社員ID
End Property
Public Property Let 社員ID(値 As String)
m社員ID = 値
End Propertyクラスの動作(処理)を定義します。
Public Sub 表示()
MsgBox "社員ID: " & m社員ID & vbCrLf & _
"氏名: " & m氏名
End Sub
Public Function 年収計算(月給 As Long) As Long
年収計算 = 月給 * 12 + ボーナス計算(月給)
End Function通常のモジュールからクラスのインスタンスを作成して使用します。
Dim 社員1 As New 社員クラス
社員1.社員ID = "E001"
社員1.氏名 = "山田太郎"
社員1.表示
年収 = 社員1.年収計算(300000)クラスを使うと、関連するデータと処理をひとつの単位にまとめることができ、コードの整理・再利用性・保守性が向上します。複雑なプロジェクトでは特に有効です。
ブックレベルのイベントはThisWorkbookオブジェクトに記述します。
Private Sub Workbook_Open()
' ブックが開かれたときの処理
MsgBox "ようこそ!"
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
' 保存前の処理
If MsgBox("保存しますか?", vbYesNo) = vbNo Then
Cancel = True ' 保存をキャンセル
End If
End Subシートレベルのイベントは各シートオブジェクトに記述します。
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
' セル選択変更時の処理
StatusBar = "選択: " & Target.Address
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
' セル値変更時の処理
If Target.Column = 1 Then
' A列変更時の処理
End If
End SubExcel全体のイベントはクラスモジュールでWithEventsを使用します。
' クラスモジュール内
Public WithEvents App As Application
Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
' 任意のブックが開かれたときの処理
End Sub
' 通常モジュール内で初期化
Dim AppEvents As New イベントクラス
Sub 初期化()
Set AppEvents.App = Application
End Subイベントが発生したときにのみコードが実行される設計です。常に監視するのではなく、必要なときだけ処理を行うため効率的です。ユーザー操作に応じた柔軟な対応が可能になります。
VBEの「ツール」→「参照設定」から "Microsoft Outlook XX.0 Object Library" を選択します(XXはバージョン番号)。これによりOutlookオブジェクトモデルにアクセスできます。
Outlookを使ってメールを送信します。
Sub メール送信()
Dim olApp As Outlook.Application
Dim olMail As Outlook.MailItem
' Outlookアプリケーション取得
Set olApp = New Outlook.Application
' メール作成
Set olMail = olApp.CreateItem(olMailItem)
With olMail
.To = "test@example.com"
.CC = "cc@example.com"
.Subject = "テスト送信"
.Body = "これはVBAから送信されたテストメールです。"
' 添付ファイル追加
.Attachments.Add "C:\Report.xlsx"
' 送信
.Send ' または .Display で表示のみ
End With
Set olMail = Nothing
Set olApp = Nothing
End SubOutlookのカレンダーに予定を追加します。
Sub 予定追加()
Dim olApp As Outlook.Application
Dim olAppt As Outlook.AppointmentItem
Set olApp = New Outlook.Application
Set olAppt = olApp.CreateItem(olAppointmentItem)
With olAppt
.Subject = "プロジェクト会議"
.Location = "会議室A"
.Start = #5/10/2023 10:00:00 AM#
.End = #5/10/2023 11:00:00 AM#
.ReminderMinutesBeforeStart = 15
.Save
End With
End SubOutlookから受信メールを取得して処理します。
Sub メール処理()
Dim olApp As Outlook.Application
Dim olNamespace As Outlook.Namespace
Dim olFolder As Outlook.Folder
Dim olItem As Object
Set olApp = New Outlook.Application
Set olNamespace = olApp.GetNamespace("MAPI")
' 受信トレイを取得
Set olFolder = olNamespace.GetDefaultFolder(olFolderInbox)
' メールを処理
For Each olItem In olFolder.Items
If TypeOf olItem Is Outlook.MailItem Then
With olItem
If InStr(.Subject, "報告") > 0 Then
' 「報告」を含むメールの処理
Debug.Print .SenderName & ": " & .Subject
End If
End With
End If
Next
End SubVBEの「ツール」→「参照設定」から "Microsoft Word XX.0 Object Library" を選択します(XXはバージョン番号)。これによりWordオブジェクトモデルにアクセスできます。
Dim wdApp As Word.Application
Dim wdDoc As Word.Document
' Wordアプリケーション起動
Set wdApp = New Word.Application
wdApp.Visible = True ' 表示する場合新規文書の作成や既存文書の開き方です。
' 新規文書
Set wdDoc = wdApp.Documents.Add
' 既存文書を開く
Set wdDoc = wdApp.Documents.Open("C:\Template.docx")
' 基本的な文書編集
wdDoc.Content.Text = "これはVBAからの文書です。"
wdApp.Selection.TypeText "段落を追加します。"
wdApp.Selection.TypeParagraphブックマークや差し込みフィールドを使ったテンプレート活用法です。
' ブックマークを使った置換
wdDoc.Bookmarks("顧客名").Range.Text = "山田太郎"
' テンプレートフィールドの更新
Dim フィールド名 As String
Dim フィールド値 As String
フィールド名 = "OrderDate"
フィールド値 = Format(Date, "yyyy年mm月dd日")
For Each fld In wdDoc.Fields
If InStr(fld.Code, フィールド名) > 0 Then
fld.Result.Text = フィールド値
End If
Next fldExcelデータを使った差し込み印刷の設定と実行方法です。
' 差し込み印刷の設定
With wdDoc.MailMerge
.MainDocumentType = wdFormLetters
.OpenDataSource _
Name:=ThisWorkbook.FullName, _
Connection:="Excel Files", _
SQLStatement:="SELECT * FROM [Sheet1$]"
' 実行
.Execute
' または指定レコードのみ
.Execute Pause:=False, _
Range:=wdSendToNewDocument, _
From:=1, To:=10
End WithVBEの「ツール」→「参照設定」から "Microsoft PowerPoint XX.0 Object Library" を選択します(XXはバージョン番号)。これによりPowerPointオブジェクトモデルにアクセスできます。
PowerPointを起動し新規プレゼンテーションを作成します。
Dim ppApp As PowerPoint.Application
Dim ppPres As PowerPoint.Presentation
' PowerPoint起動
Set ppApp = New PowerPoint.Application
ppApp.Visible = True ' 表示する
' プレゼンテーション作成
Set ppPres = ppApp.Presentations.Add
' または既存を開く
' Set ppPres = ppApp.Presentations.Open("C:\Template.pptx")スライドを追加し、内容を編集します。
Dim ppSlide As PowerPoint.Slide
' スライド追加
Set ppSlide = ppPres.Slides.Add( _
ppPres.Slides.Count + 1, _
ppLayoutTitleAndContent) ' レイアウト指定
' タイトル設定
ppSlide.Shapes.Title.TextFrame.TextRange.Text = _
"四半期売上レポート"
' 本文テキスト追加
Dim txtBox As PowerPoint.Shape
Set txtBox = ppSlide.Shapes(2) ' 本文プレースホルダ
txtBox.TextFrame.TextRange.Text = _
"• 第1四半期:前年比20%増" & vbCrLf & _
"• 第2四半期:前年比15%増" & vbCrLf & _
"• 第3四半期:前年比18%増"ExcelのデータやグラフをPowerPointに転送します。
' 表の埋め込み
Dim データ範囲 As Excel.Range
Set データ範囲 = Worksheets("データ").Range("A1:D10")
データ範囲.Copy
ppSlide.Shapes.PasteSpecial(DataType:=ppPasteOLEObject)
ppApp.ActiveWindow.Selection.ShapeRange.Left = 100
ppApp.ActiveWindow.Selection.ShapeRange.Top = 200
' グラフの埋め込み
Dim グラフオブジェクト As Excel.ChartObject
Set グラフオブジェクト = Worksheets("グラフ").ChartObjects(1)
グラフオブジェクト.Chart.CopyPicture
Set ppSlide = ppPres.Slides.Add( _
ppPres.Slides.Count + 1, ppLayoutBlank)
ppSlide.Shapes.Paste
' 参照設定: Microsoft Internet Controls
Dim IE As Object
Set IE = CreateObject("InternetExplorer.Application")
With IE
.Visible = True ' 表示する場合
.Navigate "https://example.com"
' ページ読み込み完了まで待機
Do While .Busy Or .ReadyState <> 4
DoEvents
Loop
End With
最新のEdgeを使用する場合は:
Set Edge = CreateObject("Shell.Application")
Edge.ShellExecute "msedge", URL, "", "", 1' 参照設定: Microsoft HTML Object Library
Dim Doc As MSHTML.HTMLDocument
Set Doc = IE.Document
' タグによる要素取得
Dim 要素群 As MSHTML.IHTMLElementCollection
Set 要素群 = Doc.getElementsByTagName("div")
For Each 要素 In 要素群
Debug.Print 要素.innerText
Next
' IDによる要素取得
Dim 要素 As MSHTML.IHTMLElement
Set 要素 = Doc.getElementById("content")
Debug.Print 要素.innerText
' クラスによる要素取得
Set 要素群 = Doc.getElementsByClassName("item")
ログインフォームなどを自動入力します。
Dim 入力欄 As MSHTML.HTMLInputElement
Set 入力欄 = Doc.getElementById("username")
入力欄.Value = "ユーザー名"
' ボタンクリック
Dim ボタン As MSHTML.HTMLButtonElement
Set ボタン = Doc.getElementById("login")
ボタン.ClickWebページのテーブルデータを抽出してExcelに格納します。
Dim テーブル As MSHTML.HTMLTable
Set テーブル = Doc.getElementsByTagName("table")(0)
For i = 0 To テーブル.Rows.Length - 1
For j = 0 To テーブル.Rows(i).Cells.Length - 1
Cells(i + 1, j + 1).Value = _
テーブル.Rows(i).Cells(j).innerText
Next j
Next i処理が完了したらブラウザを適切に終了します。
IE.Quit
Set IE = NothingWebリクエストにはMSXML2.XMLHTTP/Microsoft.XMLHTTP/WinHttp.WinHttpRequestなどが使用できます。
JSONの解析と生成には、VBA-JSONライブラリやScriptControl(IE依存)などを利用します。
Basic認証、APIキー、OAuth等の認証方式に対応するコードを実装します。
' HTTPリクエスト送信
Sub API呼び出し()
Dim Http As Object
Set Http = CreateObject("MSXML2.XMLHTTP")
' GETリクエスト
Http.Open "GET", "https://api.example.com/data", False
' ヘッダー設定(認証など)
Http.setRequestHeader "Content-Type", "application/json"
Http.setRequestHeader "Authorization", "Bearer " & APIトークン
' 送信と応答取得
Http.send
' 応答確認
If Http.Status = 200 Then
Debug.Print Http.responseText
' JSONデータを処理
JSON解析 Http.responseText
Else
Debug.Print "エラー: " & Http.Status & " " & Http.statusText
End If
End Sub
' POSTリクエスト例
Sub データ送信()
Dim Http As Object
Set Http = CreateObject("MSXML2.XMLHTTP")
Http.Open "POST", "https://api.example.com/data", False
Http.setRequestHeader "Content-Type", "application/json"
' JSONデータ作成
Dim データ As String
データ = "{""name"":""テスト"",""value"":123}"
Http.send データ
' 応答確認
Debug.Print Http.Status
Debug.Print Http.responseText
End Sub
Excelのマクロセキュリティ設定には4つのレベルがあります:すべてのマクロを有効化、署名付きマクロのみ、警告を表示、すべてのマクロを無効化。開発タブ→「マクロのセキュリティ」から設定できます。
デジタル証明書を取得し、VBAプロジェクトに署名することで信頼性を高められます。VBEの「ツール」→「デジタル署名」で設定します。自己署名証明書はテスト用に作成できますが、本番環境では認証局発行の証明書を推奨します。
VBAプロジェクトはパスワードで保護できます。VBEの「ツール」→「VBAプロジェクトのプロパティ」→「保護」タブから設定します。ただし、この保護は絶対的なものではなく、専用ツールで解除される可能性があることを理解しておきましょう。
ユーザー入力は必ず検証し、危険なファイル操作や実行コマンドには注意します。特に、Shell関数やFileSystemObjectの使用時は権限を最小限に保ちます。また、重要データの暗号化や、APIキー等の機密情報をハードコーディングしない対策も重要です。
コメントは単に「何を」ではなく「なぜ」にフォーカスすると有益です。プロシージャの先頭に目的、入力、出力を説明し、複雑なロジックには理由を記述します。
' ===================================================
' 目的: 売上データを集計しレポートを作成する
' 引数: 開始日 - 集計期間の開始日 (Date)
' 終了日 - 集計期間の終了日 (Date)
' 戻り値: Boolean - 成功=True、失敗=False
' 作成者: 山田太郎
' 作成日: 2023/08/15
' 更新履歴: 2023/09/01 - エラーハンドリング追加
' ===================================================
Function 売上レポート作成(開始日 As Date, 終了日 As Date) As Boolean各モジュールの先頭や専用シートに変更履歴を記録します。日付、担当者、変更内容、バージョン番号を含めると追跡しやすくなります。
' 変更履歴
' v1.0.0 2023/07/01 山田 - 初期バージョン
' v1.0.1 2023/07/15 鈴木 - バグ修正:計算式の誤り
' v1.1.0 2023/08/10 佐藤 - 新機能:CSV出力関連する機能ごとにモジュールを分け、命名規則を統一します。接頭辞(mod_, cls_, frm_)を使うと種類が分かりやすくなります。大規模プロジェクトではモジュール間の依存関係を文書化すると理解しやすくなります。
GitなどのバージョンコントロールシステムはVBAコードにも適用できます。モジュールのエクスポートと外部管理の自動化には、VBAのコード自体でエクスポート処理を実装したり、専用のツール(例:Rubberduck)を使用します。
アーキテクチャとモジュール構成の計画
機能別の適切なモジュール分割
再利用可能なコード集の整備
プロジェクトのパッケージ化と展開
大規模プロジェクトは以下の原則で整理します:
VBAには本来の名前空間はありませんが、接頭辞で疑似的に実現できます:
最適化の第一歩は問題箇所の特定です。実行時間計測コードを挿入して各セクションの処理時間を測定します。
Dim 開始時間 As Double
開始時間 = Timer
' 処理コード
Debug.Print "処理時間: " & Timer - 開始時間 & "秒"大量のオブジェクト参照や不要な変数はメモリを圧迫します。使い終わったオブジェクトは Set obj = Nothing で解放し、変数は適切なスコープで宣言します。特に大きな配列は注意が必要です。
セルの個別アクセスを避け、Range.Valueで配列として一括処理することで劇的に速度が向上します。また、不要なSelection/Activeを避け、Range/Cellsで直接参照するのも効果的です。
Power Query(または「取得と変換」)はExcelのデータ変換エンジンです。データの抽出、変換、結合を視覚的に行えます。M言語というクエリ言語で動作し、複雑なデータ変換を効率的に実行できます。
VBAは自動化とユーザーインターフェース、Power Queryはデータ変換に強みがあります。両者を組み合わせることで、使いやすく高性能なソリューションを構築できます。特に大量データや複雑な変換処理が必要な場合に有効です。
VBAからPower Queryを実行・更新します。
Sub PowerQuery更新()
' すべてのクエリを更新
ActiveWorkbook.RefreshAll
' 特定のクエリのみ更新
Dim qry As WorkbookQuery
Set qry = ThisWorkbook.Queries("Query1")
ThisWorkbook.Connections("Query1").Refresh
End SubVBAで入力値を受け取り、Power Queryに渡します。
Sub パラメータ設定()
' Power Query パラメータを設定
ThisWorkbook.Queries("開始日").Formula = _
"= #date(" & Year(開始日) & ", " & _
Month(開始日) & ", " & Day(開始日) & ")"
' 更新を実行
ThisWorkbook.Connections("売上データ").Refresh
End Sub複雑なデータ処理フローを構築します。
Sub データ処理ワークフロー()
' 1. VBAでユーザー入力を取得
日付 = InputBox("対象日を入力")
' 2. パラメータをPower Queryに設定
' (上記のコード)
' 3. Power Query実行
' (上記のコード)
' 4. 結果データにVBA処理を適用
' 追加の処理、レポート生成など
End SubVBAコードをテキストファイルとして保存する方法です。VBE内の手動操作(モジュールを右クリック→「ファイルにエクスポート」)のほか、VBAコード自体でも可能です。
Sub モジュールエクスポート()
Dim コンポーネント As Object
Dim パス As String
パス = ThisWorkbook.Path & "\バックアップ\"
' フォルダ作成
On Error Resume Next
MkDir パス
On Error GoTo 0
' 各コンポーネントをエクスポート
For Each コンポーネント In ThisWorkbook.VBProject.VBComponents
コンポーネント.Export パス & コンポーネント.Name & _
拡張子取得(コンポーネント.Type)
Next
End Sub外部ファイルからコードをインポートする方法です。新規モジュール追加や既存モジュールの置換ができます。
Sub モジュールインポート()
Dim ファイル名 As String
Dim コンポーネント As Object
' ファイル選択ダイアログ
ファイル名 = Application.GetOpenFilename("VBA Files (*.bas;*.cls;*.frm), *.bas;*.cls;*.frm")
If ファイル名 <> "False" Then
' 同名モジュールがあれば削除
モジュール名 = Left(ファイル名, _
InStrRev(ファイル名, ".") - 1)
For Each コンポーネント In ThisWorkbook.VBProject.VBComponents
If コンポーネント.Name = モジュール名 Then
ThisWorkbook.VBProject.VBComponents.Remove コンポーネント
Exit For
End If
Next
' インポート
ThisWorkbook.VBProject.VBComponents.Import ファイル名
End If
End SubExcel アドイン(.xlam)は、複数のブックで使用できるVBAコードをパッケージ化するための方法です。作成手順: 1. 通常のExcelファイルにコードを実装 2. ユーザーにとって使いやすいインターフェースを追加 3. 「名前を付けて保存」で「Excel アドイン(*.xlam)」形式を選択 4. 「Excelのオプション」→「アドイン」で管理/追加できます
汎用的に使えるコード集をライブラリとして管理します。 - 機能別にモジュール分割 - 共通関数はエクスポートして複数プロジェクトで再利用 - バージョン管理とドキュメント作成 - 重要なプロジェクトは定期的にバックアップ
経費データの入力、承認ワークフロー、レポート生成を自動化します。ユーザーフォームで入力を受け付け、入力チェックと計算を行い、承認者へのメール通知機能も実装します。複数シートに分散したデータを一元管理できます。
売上データを視覚的に分析するインタラクティブなダッシュボードです。ピボットテーブルと連動したグラフ、フィルタリング機能、KPI表示などを実装。データ更新ボタンで最新情報に更新でき、PDFやPowerPointへの出力も可能です。
商品の入出庫管理、在庫状況の可視化、発注管理などを行うシステムです。バーコードスキャナーとの連携、在庫アラート機能、発注書・納品書の自動生成なども実装。データベースに接続して大量データを効率的に管理します。
' 経費精算システムの例
Sub 経費申請フォーム表示()
UserForm_経費申請.Show
End Sub
' 売上分析の例
Sub データ更新()
' データ取得
With Sheets("データ")
最終行 = .Cells(.Rows.Count, 1).End(xlUp).Row
データ = .Range("A2:F" & 最終行).Value
End With
' ピボットテーブル更新
Sheets("分析").PivotTables("売上集計").PivotCache.Refresh
' グラフ更新
Call グラフ更新処理
MsgBox "データを最新情報に更新しました"
End Sub
Microsoft 365でも継続サポート。レガシーシステムやデスクトップ向け自動化の主力ツール。Office 2021/365には引き続き搭載されていますが、新機能追加は限定的です。
Webベース版ExcelのマクロとしてJavaScript/TypeScriptベースで開発。クラウド環境に最適化され、今後の主力になる可能性があります。記録機能も備え、VBAからの移行パスを提供しています。
ローコード/ノーコードで業務プロセスを自動化。Office 365やWebサービスとの統合が容易で、VBAよりも広範囲な自動化が可能です。クラウドサービスとの相性が良く、非開発者にも操作できます。
Excel 365の最新バージョンではPython機能が追加され、データ分析やAI処理が可能になります。pandas, matplotlib等のライブラリを活用した高度な分析が、ExcelのUIから直接実行できるようになります。
VBAは当面存続しますが、新しい技術への段階的な移行を検討すべき時期です。特にクラウド環境での利用が増える場合は、Office ScriptsやPower Automateの習得が有利になるでしょう。複数の技術を状況に応じて使い分けるハイブリッドアプローチが最も現実的です。
VBA初心者向け完全ガイド:基礎から応用まで