この記事で分かること
- どんなマクロにもよく登場する「部品」10個の書き方
- それぞれのコードを「なぜその書き方にするのか」の理由
- コピペしてそのまま使える形での実装例
「マクロを書くたびに、最終行の取得方法などを毎回検索している」という方に向けて書いています。
どんな場面で使うか
- 新しいマクロを書くたびに、同じような処理を毎回ゼロから書いている
- 部署内でマクロのコードパターンを統一したい
- 「この書き方で合っているか」を確認しながら学習したい
基本説明
VBAのマクロは、業務内容が違っても「土台」の部分は共通していることがほとんどです。最終行を取得する、シートが存在するか確認する、ファイルを選ばせる——こうした部品を都度検索するのは非効率です。
この記事では、実務でよく使う10個のスニペットを、それぞれ「なぜこの書き方が安全か」という理由つきでまとめます。すべてOption Explicitを使い、Select・Activateは使いません。
手順
使い方
気になるスニペットをそのままコピーし、Sub〜End Subの中身だけを自分の処理に置き換えて使ってください。変数名(ws、lastRowなど)は用途に応じて変更してかまいません。
サンプルコードまたは例
1. 最終行を取得する
Option Explicit
Sub Snippet01_最終行取得()
Dim ws As Worksheet
Dim lastRow As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Debug.Print "最終行: " & lastRow
End Sub
Rows.Countで「シートの一番下」からEnd(xlUp)(Ctrl+↑相当)で上に向かって最初の値がある行を探します。データが何行あっても対応できます。
2. 最終列を取得する
Sub Snippet02_最終列取得()
Dim ws As Worksheet
Dim lastCol As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
Debug.Print "最終列: " & lastCol
End Sub
1行目(見出し行)を基準に、右端からEnd(xlToLeft)で左に向かって探すのが定番です。
3. シートの存在確認
Function Snippet03_シート存在確認(sheetName As String) As Boolean
Dim ws As Worksheet
Snippet03_シート存在確認 = False
For Each ws In ThisWorkbook.Worksheets
If ws.Name = sheetName Then
Snippet03_シート存在確認 = True
Exit Function
End If
Next ws
End Function
存在しないシート名をWorksheets("〇〇")で直接指定するとエラーで止まります。処理前にこの関数で確認し、Falseのときはメッセージを出して中断するようにします。
4. ファイル選択ダイアログ
Sub Snippet04_ファイル選択()
Dim filePath As Variant
filePath = Application.GetOpenFilename("Excelブック,*.xlsx;*.xls", , "取り込むファイルを選択")
If filePath = False Then
MsgBox "ファイルが選択されませんでした。"
Exit Sub
End If
Debug.Print "選択されたファイル: " & filePath
End Sub
GetOpenFilenameは選択がキャンセルされると論理値Falseを返します。Variant型で受け取り、キャンセル判定をしてから使うのが安全です。
5. フォルダ内ファイルの列挙
Sub Snippet05_フォルダ内ファイル列挙()
Dim folderPath As String
Dim fileName As String
folderPath = "C:\work\import\"
fileName = Dir(folderPath & "*.csv")
Do While fileName <> ""
Debug.Print fileName
fileName = Dir()
Loop
End Sub
Dir関数は引数なしで呼ぶと「前回の続き」を返す仕様です。ループの中でDir()を呼び続けることで、フォルダ内の全ファイルを順番に取得できます。
6. 画面更新の停止と復帰
Sub Snippet06_画面更新停止()
Application.ScreenUpdating = False
' ここに時間のかかる処理を書く
Application.ScreenUpdating = True
End Sub
大量のセル操作を行う前に画面更新を止めると、ちらつきがなくなり処理も速くなります。必ず処理の最後(エラー時も含めて)にTrueへ戻すのを忘れないようにします。
7. 処理時間の計測
Sub Snippet07_処理時間計測()
Dim startTime As Double
startTime = Timer
' ここに計測したい処理を書く
Debug.Print "処理時間: " & Format(Timer - startTime, "0.00") & "秒"
End Sub
Timerは日付が変わる深夜0時をまたぐと正しく測れない点だけ注意してください。
8. セルが空かどうかの判定
Sub Snippet08_空セル判定()
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Sheet1")
If Len(ws.Range("A2").Value) = 0 Then
Debug.Print "A2は空です"
Else
Debug.Print "A2の値: " & ws.Range("A2").Value
End If
End Sub
= ""との比較でも判定できますが、Len(...) = 0のほうが数値・文字列どちらの空判定でも意図通りに動きます。
9. 配列に読み込んで高速処理する
Sub Snippet09_配列化()
Dim ws As Worksheet
Dim dataArr As Variant
Dim i As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
dataArr = ws.Range("A2:A1000").Value
For i = LBound(dataArr, 1) To UBound(dataArr, 1)
' dataArr(i, 1) を使って処理する(セルに毎回アクセスしない)
Next i
End Sub
セル範囲をまとめて配列に読み込むと、1件ずつセルにアクセスするより大幅に高速になります。行数の多い集計処理で効果があります。
10. エラー処理の基本形
Sub Snippet10_エラー処理基本形()
On Error GoTo ErrHandler
' ここに処理を書く
Dim x As Long
x = 1 / 0 ' ← わざとエラーを起こす例
Exit Sub
ErrHandler:
MsgBox "エラーが発生しました: " & Err.Description
End Sub
On Error GoToでエラー発生時の行き先を指定し、正常終了時はExit Subでエラー処理をスキップします。エラー内容をErr.Descriptionでそのまま握りつぶさずに表示するのがポイントです。
よくあるエラー
- 「インデックスが有効範囲にありません」:シート名の指定間違いや、スニペット3のシート存在確認を省略したことが原因のことが多いです。
- 「型が一致しません」:スニペット4のファイル選択で
filePathをString型で受けると、キャンセル時のFalse(Boolean)が代入できずエラーになります。Variant型で受けてください。 - 画面が固まったように見える:スニペット6で
ScreenUpdatingをFalseにしたまま、エラーで処理が中断してTrueに戻し忘れているケースです。エラー処理と組み合わせて必ず復帰させます。
まとめ
最終行取得・シート存在確認・ファイル選択など、VBAでよく使う部品はパターンが決まっています。部署内で同じ書き方を使うようにすると、引き継ぎもしやすくなります。
