皆さん、こんにちは!下町AI探究者のガジュマロです。
いつもブログを読んでくださり、本当にありがとうございます。
さて、「AIマクロ探究シリーズ」、楽しんでいただけていますでしょうか?
前回(#1)は、Excelのちょっと面倒な「結合セルの解除と値の入力」をAIと一緒に自動化してみました。AIに頼めば、ほんの数分でコードが手に入り、手作業の繰り返しから解放される可能性があることを実感していただけたなら嬉しいです。
今回も、そんな「あるある!」なExcelの面倒ごとをAIマクロで解決していきたいと思います。今日のテーマは、「リストに基づいて、同じフォーマットのシートをたくさん自動で作成する」です!
こんな時、ありませんか? 「シートのコピーと名前変更の無限作業…」
例えば、こんな場面に遭遇したことはないでしょうか。
- 社員名簿があって、社員一人ひとりに対して、評価シートや目標管理シート(フォーマットは同じ)を作成する必要がある。
- プロジェクトのリストがあって、各プロジェクトごとに進捗管理用のシート(これもフォーマットは同じ)を用意したい。
- 取引先リストがあって、それぞれに請求書や月次報告のテンプレートシートを作成したい。
リストの数が数件ならまだしも、数十件、あるいは百件以上となると…。
一つ一つ「テンプレート」シートをコピーして、リストの名前を確認して、新しいシートの名前を打ち替えて…という作業を延々と繰り返すことになります。単調な作業なので、うっかり名前を間違えたり、コピーし忘れたりするミスも起こりがちです。ミスが起こるたびに、チェック項目が増え、作業時間が延び…。
正直、考えるだけで、ちょっと気が重くなりますよね。
「この繰り返し作業、AIにお願いしてみよう!」
そこで、今回も私たちの味方、AIの出番です!
「リストの情報を読み取って、シートを自動で作って名前も変えてくれる、そんなマクロをお願いできないかな?」
今回も、具体的なイメージをAIに伝えてみることにしました。こんな風にお願いしてみます。
【AIへのお願い(プロンプト)例】
Excel VBA マクロを作成してください。
以下の仕様を満たすようにしてください。
1. 「リストシート」という名前のシートのA列、2行目以降に、作成したいシートの名前がリストとして入力されています。
2. 「テンプレート」という名前のシートが存在します。これがコピー元のシートです。
3. リストシートのA列に入力されている名前の数だけ、「テンプレート」シートをブックの末尾にコピーしてください。
4. コピーして新しくできたシートの名前を、リストシートのA列から取得した名前に変更してください。
5. リストシートのA列が空白のセルは無視してください。
6. 汎用性のあるものにしてください。
AIにお願いする時は、このように「どのシートの」「どの列の情報を」「どう使って」「何をしてほしいか」を、自分の作業手順に倣って具体的に伝えるのがコツでしたね。
そして、AIは今回もすぐに、次のようなコードを提案してくれました。
AIが作ってくれたマクロコードはこちら!
Sub CreateSheetsFromList()
Dim listSheet As Worksheet
Dim templateSheet As Worksheet
Dim nameCell As Range
Dim listRange As Range
Dim lastRow As Long
Dim newSheet As Worksheet
' --- 設定項目 (★ここをご自身のファイルに合わせて変更してください) ---
Const ListSheetName As String = "リストシート" ' ★名前リストがあるシート名
Const TemplateSheetName As String = "テンプレート" ' ★コピー元のシート名
Const NameListColumn As String = "A" ' ★名前リストがある列番号
Const StartRow As Long = 2 ' ★名前リストの開始行番号
' ---------------------------------------------------------------
' エラー処理: On Error Resume Next は使わず、存在チェックで対応
On Error GoTo ErrorHandler ' エラーハンドリング開始
' シート存在チェック (マクロ実行前に確認)
Set listSheet = ThisWorkbook.Sheets(ListSheetName)
Set templateSheet = ThisWorkbook.Sheets(TemplateSheetName)
' 処理高速化 (画面のチラつきを抑え、処理を速くします)
Application.ScreenUpdating = False
' リストシートの指定列における最終行を取得
lastRow = listSheet.Cells(listSheet.Rows.Count, NameListColumn).End(xlUp).Row
' リスト範囲を設定 (開始行が最終行より大きい、つまりリストが空の場合は処理しない)
If lastRow >= StartRow Then
Set listRange = listSheet.Range(NameListColumn & StartRow & ":" & NameListColumn & lastRow)
' リスト範囲の各セルを順番に処理
For Each nameCell In listRange
' セルの値が空白でない場合のみシートを作成
If Trim(nameCell.Value) <> "" Then
' テンプレートシートをブックの末尾にコピー
templateSheet.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
' コピーされたシート(現在アクティブになっているシート)を取得
Set newSheet = ActiveSheet
' 新しいシートの名前をリストの値に変更する準備
Dim safeSheetName As String
safeSheetName = ReplaceCharsForSheetName(CStr(nameCell.Value)) ' シート名に使えない文字を置換
' シート名の重複チェックとリネーム
If Not SheetExists(safeSheetName, ThisWorkbook) Then
' 重複がなければ、シート名を変更(最大31文字まで)
newSheet.Name = Left(safeSheetName, 31)
Else
' ★もし同じ名前のシートが既にあった場合の処理 (例: 名前に番号を付加)
Dim i As Integer
i = 1
Do Until Not SheetExists(Left(safeSheetName, 31 - Len(CStr(i)) - 1) & "_" & i, ThisWorkbook)
i = i + 1
If i > 999 Then Exit Do ' 無限ループ防止
Loop
If i <= 999 Then
newSheet.Name = Left(safeSheetName, 31 - Len(CStr(i)) - 1) & "_" & i
Else
' 999個も重複することは稀ですが、念のためエラー処理
MsgBox "シート名「" & safeSheetName & "」の重複が多すぎるため、" & vbCrLf & _
"シートの作成をスキップします。", vbExclamation
Application.DisplayAlerts = False ' 削除時の確認メッセージを非表示
newSheet.Delete
Application.DisplayAlerts = True ' 元に戻す
End If
End If
End If
Next nameCell
Else
' リストが見つからなかった場合
MsgBox "シート「" & ListSheetName & "」の " & NameListColumn & " 列 " & StartRow & " 行以降に、" & vbCrLf & _
"シート名のリストが見つかりません。", vbInformation
End If
' 処理高速化解除
Application.ScreenUpdating = True
MsgBox "シートの作成が完了しました。", vbInformation
Exit Sub ' 正常終了時の出口
ErrorHandler: ' エラー発生時の処理
Application.ScreenUpdating = True ' 念のため画面更新を有効に戻す
If listSheet Is Nothing Then
MsgBox "エラー: シート名「" & ListSheetName & "」が見つかりません。" & vbCrLf & _
"マクロ内の「ListSheetName」の設定を確認してください。", vbCritical
ElseIf templateSheet Is Nothing Then
MsgBox "エラー: シート名「" & TemplateSheetName & "」が見つかりません。" & vbCrLf & _
"マクロ内の「TemplateSheetName」の設定を確認してください。", vbCritical
Else
' その他の予期せぬエラー
MsgBox "予期せぬエラーが発生しました。" & vbCrLf & vbCrLf & _
"エラー番号: " & Err.Number & vbCrLf & _
"エラー内容: " & Err.Description, vbCritical
End If
End Sub
' シート名に使えない文字を置換する補助関数 (簡易版)
Function ReplaceCharsForSheetName(ByVal sheetName As String) As String
Dim invalidChars As String
Dim i As Integer
invalidChars = "[]:\/?*" ' シート名に使えない文字リスト: 半角の角括弧、コロン、円マーク、スラッシュ、疑問符、アスタリスク
ReplaceCharsForSheetName = sheetName
' 全角の禁止文字も置換対象にする(例)
ReplaceCharsForSheetName = Replace(ReplaceCharsForSheetName, ":", "_")
ReplaceCharsForSheetName = Replace(ReplaceCharsForSheetName, "¥", "_")
ReplaceCharsForSheetName = Replace(ReplaceCharsForSheetName, "/", "_")
ReplaceCharsForSheetName = Replace(ReplaceCharsForSheetName, "?", "_")
ReplaceCharsForSheetName = Replace(ReplaceCharsForSheetName, "*", "_")
' 半角の禁止文字を置換
For i = 1 To Len(invalidChars)
ReplaceCharsForSheetName = Replace(ReplaceCharsForSheetName, Mid(invalidChars, i, 1), "_")
Next i
' 先頭や末尾のスペースも除去しておくと安全
ReplaceCharsForSheetName = Trim(ReplaceCharsForSheetName)
End Function
' 指定したブック内でシート名の存在をチェックする関数
Function SheetExists(sheetName As String, Optional wb As Workbook = Nothing) As Boolean
Dim sh As Worksheet
If wb Is Nothing Then Set wb = ThisWorkbook ' ブック指定がなければ自身のブック
On Error Resume Next ' エラーが発生しても無視して次に進む設定
Set sh = wb.Sheets(sheetName)
On Error GoTo 0 ' エラー処理の設定を元に戻す
' shオブジェクトが取得できていれば(Nothingでなければ)シートは存在する
SheetExists = Not sh Is Nothing
End Function
今回も、AIはしっかりと稼働するコードを作ってくれました!
非常に長いコードなので、これを解読するのはかなり骨が折れそうです。しかし、コメントも付けてくれているので、どこで何をしているのかは、少し追いやすくなっているかもしれません。
このマクロのポイント(カスタマイズ性)
今回のマクロは、AIが生成してくれたコードの中に、ユーザーが自分の環境に合わせて変更できる「設定項目」を用意してくれているのがポイントですね。
' --- 設定項目 (★ここをご自身のファイルに合わせて変更してください) ---
Const ListSheetName As String = "リストシート" ' ★名前リストがあるシート名
Const TemplateSheetName As String = "テンプレート" ' ★コピー元のシート名
Const NameListColumn As String = "A" ' ★名前リストがある列番号
Const StartRow As Long = 2 ' ★名前リストの開始行番号
' ---------------------------------------------------------------
コード冒頭のこの部分を書き換えるだけで、リストが入力されているシート名や列、コピー元のテンプレートシート名が違っていても、マクロをそのまま使えるように配慮されています。これによって、様々なファイル構造に対応できる汎用性が生じています。さすがAI、しっかりと希望に沿ったものを作ってくれたようです。
しかも、AIはシート名に使えない文字(: や ? など)が含まれていた場合の処理や、同じ名前のシートが既に存在した場合の重複回避策(例では末尾に _1, _2 …と番号を付ける)なども、考慮してコードに入れてくれています。これらも、手作業では見落としがちだったり、対応が面倒だったりするポイントです。こういう、マクロ初心者にはトライ&エラーでしか分かり得ないところを、指示なしでも押さえてくれているのが、AIの凄いところです。
このマクロの使い方と注意点(今回も、おさらい!)
さて、この便利なマクロの使い方を、さらっとおさらいです。基本的な流れは前回と同じです。ただ、今回は実行する前に、皆さんのExcelファイルに合わせて少しだけ調整が必要になります。
使う前の準備:
- 【超重要】元のファイルを必ずコピー!: これはお約束ですね!マクロは何が起こるか分からないし、何か起こっても戻せません。必ずコピーしたファイルで試してください。 しつこいですが、大事なことなので何度でも言います(笑)。
- 「リストシート」を準備: マクロが読み取るためのシート名のリストを用意します。
- シート名を「リストシート」にする。 (もしシート名を変更したくない場合は、後述するコードの修正を行ってください)
- A列に、作成したいシート名を2行目から順番に入力 します。(これも、もし違う列や行にしたい場合は、コードの修正を行って下さい)
- 「テンプレート」シートを準備: コピー元となるシートを用意します。
- シート名を「テンプレート」にする。 (これも、違う名前にしたい場合はコード修正が必要です)
マクロの実行手順:
- VBEを開く: Alt + F11 キーで VBE (Visual Basic Editor) を開きます。
- 標準モジュールを挿入: メニューの「挿入」→「標準モジュール」を選択。
- コードを貼り付け: 上記の Sub CreateSheetsFromList() から End Function まで全てをコピーし、表示された白い画面に貼り付けます。
- 【重要】コードの設定項目を確認・修正: 貼り付けたコードの最初の方にある — 設定項目 — という部分を見てください。
‘ — 設定項目 (★ここをご自身のファイルに合わせて変更してください) —
Const ListSheetName As String = “リストシート” ‘ ★名前リストがあるシート名
Const TemplateSheetName As String = “テンプレート” ‘ ★コピー元のシート名
Const NameListColumn As String = “A” ‘ ★名前リストがある列番号
Const StartRow As Long = 2 ‘ ★名前リストの開始行番号
‘ ————————————————————-
もし、皆さんが準備したシート名やリストの場所が、この初期設定(”リストシート”, “テンプレート”, “A”列, 2行目)と違う場合は、この部分のダブルクォーテーション(””)の中身や数字を、ご自身のファイルに合わせて書き換えてください。 例えば、リストが「名簿」シートのB列3行目から始まっているなら、ListSheetName = “名簿”、NameListColumn = “B”、StartRow = 3 のように修正します。 - マクロを実行: コード内のどこかをクリックしてから F5 キーを押すか、実行メニューから実行します。
- 完了確認: 「シートの作成が完了しました。」というメッセージが出たら成功です! Excelのシートタブを確認してみてください。リストに基づいた名前のシートがたくさん出来ているはずです。
- もし途中で「シート名が見つかりません」などのエラーメッセージが出た場合は、メッセージの内容をよく読んで、シート名の設定やコードの修正箇所が正しいか確認してみてくださいね。
後片付け:
前回同様、今回だけ使えれば良い場合は、結果が反映されたExcelファイルを「上書き保存」すればOKです。また、今後もこのマクロを使いたい場合は、コード全体をメモ帳などにコピーして保存しておくと便利です。
使う上での注意点 (再確認):
- 「コピーで試す」を徹底!: VBA実行後は基本的に「元に戻す(アンドゥ)」が効きません。
- AIのコードは完璧ではないかも、を念頭に: うまくいかない場合は、エラーメッセージをヒントにAIに再度質問したり、お願いの仕方を変えてみたりしましょう。
- コードの意味を少しだけ覗いてみる: 今回のコードは少し長めです。しかし、「設定項目」や「For Each nameCell In listRange ~ Next nameCell」(リストを一つずつ処理するループ)あたりが中心だと分かると、応用もしやすくなるかもしれません。また、Function ~ End Functionによって、「シート名に使えない文字を置換する」という機能が、関数として分離されている点も面白いです。(今回のコードをVBEに貼り付けると、Function ~ End Functionの箇所で明示的に線が引かれるので、見分けやすいです。)
- セキュリティーに注意: 機密情報などをAIに直接入力しないように気をつけましょう。
まとめ:定型作業こそAIマクロの得意技!
今回は、「AIマクロ探究シリーズ」の第二弾として、リストに基づいて大量のシートを自動作成するマクロに挑戦してみました。
シートのコピーと名前変更のような、ルールが決まっている単純な繰り返し作業は、まさにマクロ、そしてそれを手軽に作ってくれるAIの得意分野と言えるのではないでしょうか。手作業なら15分や30分もかかっていたかもしれない作業が、AIへの指示とマクロ実行でほんの一瞬で終わる、しかもミスなし…そんな体験を、ぜひ皆さんも味わってみてほしいなと思います。
「面倒だな」「時間かかるな」と感じる定型作業があったら、「これ、AIにマクロ作ってもらえないかな?」と考えてみる。そんな視点を持つだけで、日々の仕事が少し楽になるかもしれません。
このシリーズでは、これからも皆さんの「あるある!」な悩みを解決できるようなテーマを探していきたいと思います。
それでは、また次回の「AIマクロ探究シリーズ」でお会いしましょう!
コメント