忍者ブログ
バイオインフォマティックス技術者試験、情報処理試験など、IT系の試験を基礎から勉強します。また、Javaなどプログラミングを勉強します。

【VBA】ブック内の全シート名を一括取得!Sheets.CountとForループでシート一覧を表示する方法

Excelファイル内にどんなシートが存在するのかを把握したり、特定のシートを探して処理を行いたいとき、ブックに含まれる全シート名を順番に取得する手法はVBA開発の基本テクニックです。今回は `Sheets.Count` と `For` ループを使ったシンプルな実装方法を解説します。

1. 基本概念:Sheets.Count と Sheets(i)

Excel VBAでは、ブックに含まれるシートの総数を Sheets.Count で取得できます。これを `For` ループの終了条件に指定することで、1番目のシートから最後のシートまで順番に処理を適用できます。

[ 構成要素 ]
Sheets.Count:ブック内の全シート数(ワークシート+グラフシート等)を返す
Sheets(i).Name:i 番目のシート名(文字列)を取得する

2. 実践サンプル:全シート名をイミディエイトウィンドウに出力する

ポイント:インデックス番号(1からSheets.Countまで)を順番に回す

以下のサンプルコードを実行すると、アクティブなブックに含まれる全てのシート名がイミディエイトウィンドウに順番に出力されます。

Sub Macro1()
  Dim i As Long
  
  ' 1番目のシートから最後のシートまでループ
  For i = 1 To Sheets.Count
    Debug.Print Sheets(i).Name
  Next i
End Sub

3. 実行結果

イミディエイトウィンドウに、ブック内のシート一覧が上から順に表示されます。

Sheet1
Sheet2
Sheet3

4. 【超重要】よくある注意点と「ハマりやすい罠」

注意点1:変数 i のデータ型は Variant ではなく Long にする

ループのカウント変数(`i`)に `Variant` 型を使うと、余計なメモリを消費し処理速度が低下します。数値のカウントには整数型(Long)を使うのがVBAの鉄則です。
Dim i As Variant  ' 非推奨(低速・無駄なメモリ消費)
Dim i As Long    ' 推奨(高速で標準的)

注意点2:Sheets と Worksheets の違いに注意する

`Sheets` はグラフシート等も含めたすべてのシートを対象とします。普通の「セルがある表シート」だけを正確に対象にしたい場合は、`Worksheets` を使用するのが安全です。
For i = 1 To Worksheets.Count  ' ワークシートのみを厳密にカウント

5. エンジニアの視点:For Each ループを使ったよりスタイリッシュな書き方

1. For Each ws In Worksheets: インデックス番号(`i`)を使わずに `For Each` 文を使うと、コードがより直感的で読みやすくなります。プロのエンジニアが現場でよく書く「いけいけ」な記法です。

Sub ShowAllSheetNames()
  Dim ws As Worksheet
  For Each ws In Worksheets
    Debug.Print ws.Name
  Next ws
End Sub


2. 全シート一括処理の基盤: 「全シートの特定セルをまとめてクリアする」「全シートをPDF化して出力する」といった高度な自動化も、このシートループ処理が基本骨格になります。


6. まとめ

シート一覧の取得は、複数シートをまとめて操作するマクロの第一歩です。変数の型(`Long`)や `Worksheets` コレクションの選び方に気をつけて、拡張性の高いスマートなコードを作成していきましょう!


PR

【VBA】DisplayAlertsで警告メッセージを消す!シート削除時のポップアップを非表示にする方法

VBAでシートの削除やファイルの上書き保存などを実行する際、「本当に削除しますか?」といった確認メッセージ(ポップアップ)が表示されて処理がストップしてしまうことがあります。Application.DisplayAlerts を使えば、こうした警告メッセージを一時的に消して、マクロを完全に自動実行させることができます。

1. 基本概念:Application.DisplayAlerts とは?

Excelが発生させる各種確認アラートの表示・非表示を制御するプロパティです。これを False に設定すると、警告ダイアログを出さずにExcelの既定値(規定の挙動:例えば削除なら「削除を実行する」)でそのまま処理が進みます。

[ 設定値 ]
False:警告メッセージを表示しない(規定の動作を自動選択)
True:警告メッセージを表示する(既定の状態)

2. 実践サンプル:確認なしでシートを削除する

最重要ルール:処理が終わったら必ず True に戻す!

シート削除の直前で `False` にし、削除が終わったら即座に `True` に戻すのが基本の書き方です。

Sub DeleteSheetWithoutAlert()
  ' 1. 警告メッセージの表示をオフにする
  Application.DisplayAlerts = False
  
  ' 2. シートを削除(ポップアップが出ずに削除される)
  Worksheets("TempSheet").Delete
  
  ' 3. 処理が終わったら必ずオンに戻す
  Application.DisplayAlerts = True
End Sub

3. 実行結果

通常であれば「データが存在する場合、永久に削除されます」という警告ウィンドウが出ますが、一切の割り込みなしで「TempSheet」が即座に削除されます。

4. 【超危険】よくある失敗例と「戻し忘れ」の罠&解決策

失敗パターン:エラーで途中で止まり、True に戻らない

`DisplayAlerts = False` のまま途中でエラーが発生して処理が中断すると、その後のExcel全体の操作でも警告が出なくなります。手動で大切なファイルを保存せずに閉じようとした際も確認が出ずに消えてしまうという二次災害につながります。
' 危険!途中でエラーが起きると True に戻らない
Application.DisplayAlerts = False
Worksheets("存在しないシート").Delete ' ←ここでエラー発生!
Application.DisplayAlerts = True ' ←ここまで到達しない!

【解決策】On Error と Exit Sub を使った鉄壁のエラー処理

万が一エラーが発生しても必ず True に戻る脱出ルート(ExitHandler)を用意するのがプロの設計です。
Sub SafeDeleteSheet()
  On Error GoTo ErrorHandler ' エラーが発生したらErrorHandlerへジャンプ
  
  Application.DisplayAlerts = False
  Worksheets("TempSheet").Delete

ExitHandler:
  ' 正常・異常に関わらず必ずここを通って True に戻す
  Application.DisplayAlerts = True
  Exit Sub

ErrorHandler:
  MsgBox "エラーが発生しました: " & Err.Description, vbCritical
  Resume ExitHandler ' 後処理へ移動
End Sub

5. シート削除以外に警告を抑止できる実務例

DisplayAlerts はシート削除以外にも、業務自動化でよく引っかかる様々なポップアップをスキップできます。

1. 同名ファイルへの上書き保存(「上書きしますか?」をスキップ)
ActiveWorkbook.SaveAs Filename:="C:\Test\Data.xlsx"

2. 変更内容を保存せずにブックを閉じる(「変更を保存しますか?」をスキップ)
ActiveWorkbook.Close SaveChanges:=False

3. 外部リンク(参照)の更新警告(「リンクを更新しますか?」を自動で規定処理)
Workbooks.Open Filename:="C:\Test\LinkData.xlsx"

4. CSV保存時の互換性警告(「一部の機能が失われる可能性があります」をスキップ)
ActiveWorkbook.SaveAs Filename:="C:\Test\Data.csv", FileFormat:=xlCSV

6. エンジニアの視点:局所的な制御と「いけいけ」なエラーハンドリング

1. 範囲は最小限に: プログラムの最初で `False` にして最後で `True` に戻すのではなく、警告が出る対象の処理の前後だけをピンポイントで囲むのがバグを減らすコツです。
2. 規定動作の把握: ポップアップを消したとき、Excelが「はい(OK)」を選ぶのか「いいえ(キャンセル)」を選ぶのか(例:シート削除なら「はい」、保存確認なら「いいえ」)を事前に把握しておくことが「理系」的な堅牢設計に繋がります。


7. まとめ

完全自動化ツールを作る上で `DisplayAlerts = False` は必須ですが、エラー時の「戻し忘れ」対策(`On Error GoTo`)とセットで使って初めてプロのコードになります。リスクを回避しつつ、無人でもノンストップで動く爆速VBAツールを作り上げましょう!




【VBA】文字列結合(&)の使い方と落とし穴!「+」との違いとスペース挿入の注意点

VBAで文字と文字、あるいは文字と変数を繋ぎ合わせるときに使うのが &(アンパサンド) 演算子です。非常にシンプルですが、書き方によってはエラーになったり、予期せぬ計算結果になったりする「罠」が存在します。正しい使い方とよくあるミスを押さえておきましょう。

1. 基本文法:& 演算子

2つの値や変数を結合して、1つの文字列にします。数値と文字列を結合した場合も、全体が自動的に文字列として扱われます。

[ 構文 ]
結合結果 = 値1 & 値2

2. 実践サンプル:文字と数値の結合

ポイント:前後には必ず半角スペースを入れる

変数や文字列リテラルを `&` でスムーズにつなぐ基本のコードです。

Sub Macro1()
  Dim num As Long
  Dim str As String
  
  num = 100
  str = "個"
  
  ' 数値と文字を結合
  Debug.Print num & str
End Sub

3. 実行結果

数値と文字列が結合されて出力されます。

100個

4. 【閲覧注意】よくある2大「失敗例」とハマりポイント

失敗パターン1:「+」を使って足し算になってしまう(または型エラー)

VBAでは `+` でも文字列結合ができますが、数値と数値風の文字列を混ぜると足し算として計算される危険があります。さらに、純粋な文字が入ると「型が一致しません」エラーで止まります。
Debug.Print "10" + 20    ' 結果: 30 (結合されず足し算される!)
Debug.Print "10" & 20    ' 結果: 1020(& なら安全に結合される)

失敗パターン2:& の前後にスペースが無くて文法エラーになる

VBAの仕様上、変数の直後にスペースなしで `&` を書くと、16進数や型宣言記号(Long型の `&`)と誤認されてコンパイルエラー(赤字)になります。
Debug.Print num&str      ' 構文エラー!
Debug.Print num & str    ' 正解:& の前後に半角スペースを入れる

5. エンジニアの視点:「結合演算子は & 一択」が鉄則

1. 明示的なコード作成: 他言語(JavaScriptやJavaなど)の影響で `+` を使いたくなりますが、VBAにおいて文字列結合は必ず `&` を使うのが「いけいけ」な開発者の鉄則ルールです。意図しない型変換バグを完全に排除できます。
2. 大量結合のパフォーマンス: ループ内で何千回・何万回も `&` で文字列を連結すると処理が極端に重くなります。大規模なテキスト処理では、配列に一度格納してから `Join` 関数で一括結合する方が「理系」的で圧倒的に高速です。


6. まとめ

文字列結合は「`+` ではなく `&` を使う」「`&` の前後には半角スペースを開ける」という2点さえ押さえれば完璧です。基本だからこそ落とし穴に気をつけて、バグのないクリーンなVBAコードを書いていきましょう!


【VBA】ThisWorkbook.Pathで簡単取得!開いているマクロブックのフォルダパスを活用する方法

VBAでファイル操作を行う際、フォルダの場所(パス)をコード内に直接書く(ハードコーディングする)と、ファイルを別の場所に移動したときにエラーになってしまいます。ThisWorkbook.Path を使えば、マクロが保存されているフォルダのパスを動的に取得できるため、環境が変わっても柔軟に動作するプログラムが作れます。

1. 基本概念:ThisWorkbook.Path とは?

ThisWorkbook.Path は、現在マクロが実行されているExcelファイル(自ブック)が保存されているフォルダの絶対パスを文字列で返します。

[ 特徴 ]
・マクロ付きブック(ThisWorkbook)が存在するフォルダのパスを取得する。
・末尾に「\(円マーク/バックスラッシュ)」は含まれない。
・ブックが一度も保存されていない未保存状態の場合は、空文字("")を返す。

2. 実践サンプル:自ブックのパスを取得して出力する

ポイント:末尾の「\」を連結してファイルパスを作る

自ブックと同じフォルダ内にある別のファイルやフォルダを指し示す場合、`ThisWorkbook.Path & "\"` とつなぐのが実務での基本テクニックです。

Sub ShowWorkbookPath()
  Dim currentPath As String
  
  ' 自ブックのフォルダパスを取得
  currentPath = ThisWorkbook.Path
  
  ' 1. パスそのものを出力
  Debug.Print currentPath
  
  ' 2. 同じフォルダ内のファイルを指すフルパスの例
  Debug.Print currentPath & "\データ.xlsx"
End Sub

3. 実行結果

イミディエイトウィンドウには、マクロが保存されているフォルダの位置に応じて以下のように表示されます。

C:\Users\Username\Documents
C:\Users\Username\Documents\データ.xlsx

4. エンジニアの視点:相対パス感覚で書けるメリットと注意点

1. ポータビリティの向上: `ThisWorkbook.Path` を基準に処理を組むと、フォルダごとデスクトップや共有サーバー、他人のPCへ移動させてもそのまま動きます。これぞまさに「自走するツール」の極意です。
2. ActiveWorkbook.Path との違い: `ActiveWorkbook` は「今画面でアクティブになっているブック」を指すため、処理中に別のブックを開くと取得先が変わってしまう危険があります。マクロ自身がある場所を基準にするなら、必ず `ThisWorkbook` を使いましょう。
3. 保存状態の事前チェック: 新規作成したばかりの未保存ブックで実行すると空文字が返り、後続のファイル参照でエラーになります。実務では `If ThisWorkbook.Path = "" Then` で保存済みか確認するガード句を入れておくと「いけいけ」で堅牢なコードになります。


5. まとめ

ファイルパスの動的取得は、脱ハードコーディングの基本中の基本です。`ThisWorkbook.Path` を使いこなして、環境の変化やファイルの移動にもびくともしないスマートなVBAツールを作成していきましょう!


【VBA】処理時間を計測(Timer)する方法!コードの高速化と改善に役立つパフォーマンス計測

VBAで作成したツールが「なんだか遅い…」と感じたとき、どの処理にどれくらいの時間がかかっているのかを正しく把握することが改善の第一歩です。VBAでは Timer関数 を使うことで、簡単にプログラムの実行時間を計測(プロファイリング)できます。

1. 考え方:Timer関数で「前後の差分」を計算する

Timer関数は、午前0時からの経過時間を「秒単位(小数付き)」で返す関数です。処理の「開始時」と「終了時」のタイマーの値を記録し、その差算(終了時間 - 開始時間)を求めることで、処理にかかった時間を算出します。

[ 計算式 ]
実行時間(秒) = 処理終了時の Timer - 処理開始時の Timer

2. 実践サンプル:1,000万回のループ時間を計測する

ポイント:開始時の Timer を変数に記録しておく

以下の例では、1,000万回のForループにかかる時間を計測して、イミディエイトウィンドウに出力します。

Sub MySub()
  Dim l As Long
  Dim startTime As Single  ' タイマー値保持用の変数
  
  ' 計測開始
  startTime = Timer

  ' 計測したい処理(10,000,000回のループ)
  For l = 1 To 10000000
    l = l + 1
  Next l
  
  ' 差分を出力(実行時間)
  Debug.Print Timer - startTime & " 秒"
End Sub

3. 実行結果

PCのスペックによりますが、ループにかかった時間が秒(小数付き)で出力されます。

0.015625 秒

4. エンジニアの視点:より正確な計測とボトルネック特定

1. 深夜跨ぎの注意点(日付の壁): Timer関数は午前0時で `0` にリセットされるため、深夜23:59〜0:01のように日付を跨いで計測すると計算結果がマイナスになります。厳密に計測したい場合は、マイナスになったら `+ 86400`(1日の秒数)を補完するロジックを入れると堅牢です。
2. ミリ秒・マイクロ秒単位の計測: `Timer` 関数の精度(約1/64秒)を超える超高速な処理を計測したい場合は、Windows APIの `GetTickCount` や `QueryPerformanceCounter` を使うのがプロエンジニアの「いけいけ」な手法です。
3. 高速化の第一歩: `Application.ScreenUpdating = False`(画面更新停止)や `Application.Calculation = xlCalculationManual`(自動計算停止)を入れる前と後で `Timer` を使って比較してみてください。目に見えて秒数が縮まる快感を味わえます!


5. まとめ

「遅いコード」を改善するには、まず「どれくらい遅いのか」を客観的に測ることが重要です。`Timer` を使った処理時間の見える化を癖にして、ユーザーを待たせない爆速マクロを作り上げていきましょう!