【VBA】議事録テンプレートを自動生成・管理する方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

この記事でできること

  • VBAで会議情報を入力するだけで議事録テンプレートシートを自動生成できる
  • 日付・出席者・議題をテンプレートに自動転記できる
  • 議事録一覧の管理、検索、PDF出力、通番の自動採番まで実装できる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11

どんな場面で使う?

  • 毎週の定例会議で議事録テンプレートをコピーして手入力する作業を自動化したいとき
  • 過去の議事録をキーワードで素早く検索したいとき
  • 議事録に通番を自動採番して抜け漏れなく管理したいとき
  • 作成した議事録をPDFにして関係者に一括配布したいとき

完成イメージ(Before / After)

Before(手作業):

  1. 会議が決まるたびに議事録テンプレートのシートをコピー
  2. シート名を手入力で変更(「20260324_定例会議」など)
  3. 日付・出席者・議題を1つずつ手で転記
  4. 過去の議事録を探すときはシートを1枚ずつ確認
  5. PDF保存も手動で1枚ずつ

After(自動化):

  1. 「入力」シートに会議情報を入力してマクロ実行
  2. テンプレートがコピーされ、日付・出席者・議題が自動転記
  3. シート名に通番と日付が自動設定
  4. 一覧シートに議事録情報が自動追加
  5. 検索やPDF出力もボタン1つ

毎週の定例会議のたびに、テンプレートシートをコピーしてシート名を変えて、日付と出席者を転記して――という作業を繰り返していた。たった5分の作業でも、月に10回以上やるとさすがにうんざりしていた。VBAで自動化してからは、会議名を入れてボタンを押すだけ。過去の議事録もすぐ検索できるようになり、「あの会議の決定事項、どこだっけ?」と探す時間がなくなった。

議事録の作成と管理、VBAに任せれば入力1回で全部終わる。

実行前の準備

バックアップを取る

マクロ実行前に、Excelファイルのコピーを別フォルダに保存しておく。

Excelをマクロ有効ブック(.xlsm)で保存する

拡張子が .xlsx のままだとマクロが保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

シートの準備

以下の2つのシートを用意する。

「テンプレート」シート — 議事録の雛形

セル 内容
A1 議事録
A3 会議名:
B3 (マクロが自動入力)
A4 日付:
B4 (マクロが自動入力)
A5 出席者:
B5 (マクロが自動入力)
A6 議題:
B6 (マクロが自動入力)
A8 決定事項
A9 (手動入力エリア)
A12 アクションアイテム
A13 担当
B13 内容
C13 期限

「入力」シート — 会議情報の入力欄

セル 内容
A1 会議名
B1 (入力欄)
A2 日付
B2 (入力欄)
A3 出席者
B3 (入力欄。カンマ区切り)
A4 議題
B4 (入力欄)

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」
  2. 白い画面(コードウィンドウ)が表示される

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. Alt + F8CreateMinutes を選んで「実行」

ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。

コード(最小版)– テンプレートコピー+会議情報の転記

まずは最小構成で動きを確認する。「入力」シートの情報を読み取り、「テンプレート」シートをコピーして会議情報を転記する。


'============================================================
' ■ 議事録テンプレートの自動生成(最小版)
'   → 「入力」シートの情報で「テンプレート」をコピー+転記
'============================================================

Sub CreateMinutes()

    Dim wsInput As Worksheet
    Dim wsTemplate As Worksheet
    Dim wsNew As Worksheet

    Set wsInput = ThisWorkbook.Sheets("入力")
    Set wsTemplate = ThisWorkbook.Sheets("テンプレート")

    '--- 入力値を取得 ---
    Dim meetingName As String
    Dim meetingDate As String
    Dim attendees As String
    Dim agenda As String

    meetingName = Trim(wsInput.Range("B1").Value)
    meetingDate = Trim(wsInput.Range("B2").Value)
    attendees = Trim(wsInput.Range("B3").Value)
    agenda = Trim(wsInput.Range("B4").Value)

    '--- 未入力チェック ---
    If meetingName = "" Then
        MsgBox "会議名が入力されていません。", vbExclamation
        Exit Sub
    End If
    If meetingDate = "" Then
        meetingDate = Format(Date, "yyyy/mm/dd")
    End If

    '--- シート名を作成(日付_会議名) ---
    Dim sheetName As String
    sheetName = Format(CDate(meetingDate), "yyyymmdd") & "_" & meetingName

    '--- シート名が31文字を超える場合は切り詰める ---
    If Len(sheetName) > 31 Then
        sheetName = Left(sheetName, 31)
    End If

    '--- 同名シートが既にある場合は中止 ---
    Dim ws As Worksheet
    For Each ws In ThisWorkbook.Worksheets
        If ws.Name = sheetName Then
            MsgBox "同名のシートが既に存在します: " & sheetName, vbExclamation
            Exit Sub
        End If
    Next ws

    '--- テンプレートをコピー(末尾に追加) ---
    wsTemplate.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
    Set wsNew = ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
    wsNew.Name = sheetName

    '--- 会議情報を転記 ---
    wsNew.Range("B3").Value = meetingName
    wsNew.Range("B4").Value = meetingDate
    wsNew.Range("B5").Value = attendees
    wsNew.Range("B6").Value = agenda

    '--- 入力シートをクリア ---
    wsInput.Range("B1:B4").ClearContents

    MsgBox "議事録を作成しました: " & sheetName, vbInformation

End Sub

書き換えポイント

変数・箇所 説明 初期値
Sheets("入力") 会議情報を入力するシート名 "入力"
Sheets("テンプレート") 議事録の雛形シート名 "テンプレート"
Range("B3")Range("B6") テンプレート上の転記先セル B3~B6

コードの流れ

  1. 「入力」シートから会議名・日付・出席者・議題を取得
  2. 「テンプレート」シートを末尾にコピー
  3. コピーしたシートの名前を「日付_会議名」に変更
  4. 会議情報をセルに転記
  5. 入力シートをクリア

シート名の命名規則に日付を入れることで、シートタブを見ただけで時系列が分かる。シート名の取得や変更の詳しい仕組みは シート名の取得・一括変更・存在チェックする方法 で解説している。

コード(実務版)– 議事録一覧管理+検索+PDF出力+通番自動採番

実務では議事録が何十枚にもなる。通番を自動で振り、一覧シートで管理し、キーワードで検索、PDF出力まで対応する。

この実務版を導入してからは、「先月の営業会議の議事録どこ?」と聞かれてもすぐ見つけられるようになった。検索機能がないと、シートタブを右へ左へスクロールする羽目になる。

日付の判定に DateSerial を使う。日付処理の詳しい仕組みは 日付・曜日の判定で月末処理を自動化 を参照。ファイル名に日付を含めてPDF保存する方法は 日付やセル値でファイル名を付けて自動保存する方法 も合わせて確認してほしい。


'============================================================
' ■ 議事録テンプレートの自動生成(実務版)
'   → 通番自動採番 / 一覧管理 / 検索 / PDF出力
'   → シート構成: 入力, テンプレート, 一覧
'============================================================

'--- 定数 ---
Const INPUT_SHEET As String = "入力"
Const TEMPLATE_SHEET As String = "テンプレート"
Const LIST_SHEET As String = "一覧"
Const LIST_HEADER_ROW As Long = 1
Const LIST_DATA_START As Long = 2

'============================================================
' 通番を自動採番して議事録を生成する
'============================================================
Sub CreateMinutesWithNumber()

    Dim wsInput As Worksheet
    Dim wsTemplate As Worksheet
    Dim wsList As Worksheet
    Dim wsNew As Worksheet

    Set wsInput = ThisWorkbook.Sheets(INPUT_SHEET)
    Set wsTemplate = ThisWorkbook.Sheets(TEMPLATE_SHEET)

    '--- 一覧シートがなければ作成 ---
    If Not SheetExists(LIST_SHEET) Then
        ThisWorkbook.Sheets.Add After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
        ActiveSheet.Name = LIST_SHEET
        With ThisWorkbook.Sheets(LIST_SHEET)
            .Range("A1:F1").Value = Array("No.", "日付", "会議名", "出席者", "議題", "シート名")
            .Range("A1:F1").Font.Bold = True
            .Columns("A").ColumnWidth = 6
            .Columns("B").ColumnWidth = 12
            .Columns("C").ColumnWidth = 25
            .Columns("D").ColumnWidth = 30
            .Columns("E").ColumnWidth = 30
            .Columns("F").ColumnWidth = 30
        End With
    End If
    Set wsList = ThisWorkbook.Sheets(LIST_SHEET)

    '--- 入力値を取得 ---
    Dim meetingName As String
    Dim meetingDate As String
    Dim attendees As String
    Dim agenda As String

    meetingName = Trim(wsInput.Range("B1").Value)
    meetingDate = Trim(wsInput.Range("B2").Value)
    attendees = Trim(wsInput.Range("B3").Value)
    agenda = Trim(wsInput.Range("B4").Value)

    '--- 未入力チェック ---
    If meetingName = "" Then
        MsgBox "会議名が入力されていません。", vbExclamation
        Exit Sub
    End If
    If meetingDate = "" Then
        meetingDate = Format(Date, "yyyy/mm/dd")
    End If

    '--- 通番を採番(一覧シートの最大No.+1) ---
    Dim nextNo As Long
    Dim lastRow As Long
    lastRow = wsList.Cells(wsList.Rows.Count, "A").End(xlUp).Row
    If lastRow < LIST_DATA_START Then
        nextNo = 1
    Else
        nextNo = wsList.Cells(lastRow, "A").Value + 1
    End If

    '--- シート名を作成(通番_日付_会議名) ---
    Dim sheetName As String
    sheetName = Format(nextNo, "000") & "_" & _
                Format(CDate(meetingDate), "yyyymmdd") & "_" & meetingName

    '--- シート名が31文字を超える場合は切り詰める ---
    If Len(sheetName) > 31 Then
        sheetName = Left(sheetName, 31)
    End If

    '--- 同名シートが既にある場合は中止 ---
    If SheetExists(sheetName) Then
        MsgBox "同名のシートが既に存在します: " & sheetName, vbExclamation
        Exit Sub
    End If

    '--- テンプレートをコピー ---
    wsTemplate.Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
    Set wsNew = ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
    wsNew.Name = sheetName

    '--- 会議情報を転記 ---
    wsNew.Range("B3").Value = meetingName
    wsNew.Range("B4").Value = meetingDate
    wsNew.Range("B5").Value = attendees
    wsNew.Range("B6").Value = agenda

    '--- 一覧シートに追加 ---
    Dim newRow As Long
    newRow = wsList.Cells(wsList.Rows.Count, "A").End(xlUp).Row + 1
    If newRow < LIST_DATA_START Then newRow = LIST_DATA_START
    wsList.Cells(newRow, "A").Value = nextNo
    wsList.Cells(newRow, "B").Value = meetingDate
    wsList.Cells(newRow, "C").Value = meetingName
    wsList.Cells(newRow, "D").Value = attendees
    wsList.Cells(newRow, "E").Value = agenda
    wsList.Cells(newRow, "F").Value = sheetName

    '--- 入力シートをクリア ---
    wsInput.Range("B1:B4").ClearContents

    '--- 新しいシートをアクティブにする ---
    wsNew.Activate

    MsgBox "議事録 No." & nextNo & " を作成しました。" & vbCrLf & _
           "シート名: " & sheetName, vbInformation

End Sub

'============================================================
' 議事録を検索する(一覧シートからキーワードで絞り込み)
'============================================================
Sub SearchMinutes()

    If Not SheetExists(LIST_SHEET) Then
        MsgBox "一覧シートがありません。先に議事録を作成してください。", vbExclamation
        Exit Sub
    End If

    Dim wsList As Worksheet
    Set wsList = ThisWorkbook.Sheets(LIST_SHEET)

    '--- 検索キーワードを取得 ---
    Dim keyword As String
    keyword = InputBox("検索キーワードを入力してください。" & vbCrLf & _
                       "(会議名・出席者・議題から検索します)", "議事録検索")
    If keyword = "" Then Exit Sub

    '--- 一覧シートを検索 ---
    Dim lastRow As Long
    lastRow = wsList.Cells(wsList.Rows.Count, "A").End(xlUp).Row

    If lastRow < LIST_DATA_START Then
        MsgBox "議事録データがありません。", vbInformation
        Exit Sub
    End If

    '--- 一致した行を色付けし、結果を表示 ---
    Dim i As Long
    Dim hitCount As Long
    Dim resultText As String

    '--- 前回のハイライトをクリア ---
    wsList.Range("A" & LIST_DATA_START & ":F" & lastRow).Interior.ColorIndex = xlNone

    For i = LIST_DATA_START To lastRow
        Dim searchTarget As String
        searchTarget = wsList.Cells(i, "C").Value & " " & _
                       wsList.Cells(i, "D").Value & " " & _
                       wsList.Cells(i, "E").Value

        If InStr(1, searchTarget, keyword, vbTextCompare) > 0 Then
            hitCount = hitCount + 1
            wsList.Range("A" & i & ":F" & i).Interior.Color = RGB(255, 255, 200)
            resultText = resultText & "No." & wsList.Cells(i, "A").Value & _
                         " " & wsList.Cells(i, "C").Value & vbCrLf
        End If
    Next i

    '--- 結果を表示 ---
    wsList.Activate
    If hitCount = 0 Then
        MsgBox "「" & keyword & "」に一致する議事録は見つかりませんでした。", vbInformation
    Else
        MsgBox hitCount & " 件の議事録が見つかりました。" & vbCrLf & vbCrLf & _
               resultText, vbInformation
    End If

End Sub

'============================================================
' 選択中の議事録シートをPDFに出力する
'============================================================
Sub ExportMinutesToPDF()

    Dim ws As Worksheet
    Set ws = ActiveSheet

    '--- テンプレート・入力・一覧シートはPDF化しない ---
    If ws.Name = INPUT_SHEET Or ws.Name = TEMPLATE_SHEET Or ws.Name = LIST_SHEET Then
        MsgBox "議事録シートを選択してから実行してください。", vbExclamation
        Exit Sub
    End If

    '--- PDF保存先をブックと同じフォルダにする ---
    Dim savePath As String
    savePath = ThisWorkbook.Path & "\" & ws.Name & ".pdf"

    '--- ブックが未保存の場合はデスクトップに保存 ---
    If ThisWorkbook.Path = "" Then
        savePath = Environ("USERPROFILE") & "\Desktop\" & ws.Name & ".pdf"
    End If

    '--- 同名ファイルが存在する場合は上書き確認 ---
    If Dir(savePath) <> "" Then
        Dim ans As VbMsgBoxResult
        ans = MsgBox("同名のPDFが既にあります。上書きしますか?" & vbCrLf & _
                     savePath, vbYesNo + vbQuestion)
        If ans = vbNo Then Exit Sub
    End If

    '--- PDF出力 ---
    On Error GoTo ErrHandler
    ws.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=savePath, _
        Quality:=xlQualityStandard, _
        IncludeDocProperties:=True, _
        OpenAfterPublish:=True

    MsgBox "PDFを保存しました。" & vbCrLf & savePath, vbInformation
    Exit Sub

ErrHandler:
    MsgBox "PDF出力に失敗しました。" & vbCrLf & _
           "エラー: " & Err.Description, vbCritical

End Sub

'============================================================
' 一覧シートの全議事録を一括PDF出力する
'============================================================
Sub ExportAllMinutesToPDF()

    If Not SheetExists(LIST_SHEET) Then
        MsgBox "一覧シートがありません。", vbExclamation
        Exit Sub
    End If

    Dim wsList As Worksheet
    Set wsList = ThisWorkbook.Sheets(LIST_SHEET)

    Dim lastRow As Long
    lastRow = wsList.Cells(wsList.Rows.Count, "A").End(xlUp).Row

    If lastRow < LIST_DATA_START Then
        MsgBox "議事録データがありません。", vbInformation
        Exit Sub
    End If

    '--- 保存先フォルダを確認 ---
    Dim folderPath As String
    folderPath = ThisWorkbook.Path & "\議事録PDF"
    If ThisWorkbook.Path = "" Then
        folderPath = Environ("USERPROFILE") & "\Desktop\議事録PDF"
    End If
    If Dir(folderPath, vbDirectory) = "" Then
        MkDir folderPath
    End If

    '--- 一括PDF出力 ---
    Dim i As Long
    Dim exportCount As Long
    Dim sheetName As String

    Application.ScreenUpdating = False

    On Error GoTo ErrBatch
    For i = LIST_DATA_START To lastRow
        sheetName = wsList.Cells(i, "F").Value
        If SheetExists(sheetName) Then
            Dim savePath As String
            savePath = folderPath & "\" & sheetName & ".pdf"
            ThisWorkbook.Sheets(sheetName).ExportAsFixedFormat _
                Type:=xlTypePDF, _
                Filename:=savePath, _
                Quality:=xlQualityStandard
            exportCount = exportCount + 1
        End If
    Next i

    Application.ScreenUpdating = True
    MsgBox exportCount & " 件の議事録をPDF出力しました。" & vbCrLf & _
           "保存先: " & folderPath, vbInformation
    Exit Sub

ErrBatch:
    Application.ScreenUpdating = True
    MsgBox "PDF一括出力中にエラーが発生しました。" & vbCrLf & _
           "シート: " & sheetName & vbCrLf & _
           "エラー: " & Err.Description, vbCritical

End Sub

'============================================================
' シートの存在チェック(ヘルパー関数)
'============================================================
Private Function SheetExists(ByVal targetName As String) As Boolean
    Dim ws As Worksheet
    On Error Resume Next
    Set ws = ThisWorkbook.Sheets(targetName)
    On Error GoTo 0
    SheetExists = Not ws Is Nothing
End Function

書き換えポイント

変数・箇所 説明 初期値
INPUT_SHEET 入力シートの名前 "入力"
TEMPLATE_SHEET テンプレートシートの名前 "テンプレート"
LIST_SHEET 一覧管理シートの名前 "一覧"
Range("B3")Range("B6") テンプレート上の転記先セル B3~B6
folderPath PDF一括出力先のフォルダ ブックと同じフォルダ内の「議事録PDF」

コードの流れ

  1. CreateMinutesWithNumber: 一覧シートの最大通番+1で自動採番し、テンプレートをコピー。会議情報を転記し、一覧シートにも記録を追加
  2. SearchMinutes: 一覧シートの会議名・出席者・議題をキーワード検索し、該当行をハイライト
  3. ExportMinutesToPDF: アクティブな議事録シートをPDF出力
  4. ExportAllMinutesToPDF: 一覧シートに登録されている全議事録を「議事録PDF」フォルダに一括PDF出力

一覧管理シートがあると、過去の議事録を時系列で確認でき、検索にも使える。シートのコピーや移動の基本は シートを別ブックにコピー・移動する方法 も参考になる。

落とし穴

# 症状 原因 対策
1 「実行時エラー ‘1004’: シート名が無効です」と表示される シート名に使えない文字(\ / ? * [ ] : など)が含まれている 会議名にこれらの文字を入れない。入力チェックを追加するか、Replace で除去する処理を入れる
2 シート名が途中で切れる Excelのシート名は最大31文字。通番+日付+会議名が長すぎると切り詰められる 会議名を短くするか、通番と日付だけのシート名にして会議名はセル内だけで管理する
3 「テンプレート」シートに書いた数式や書式がコピーされない Sheet.Copy ではなくセルの値だけコピーしている コード内で wsTemplate.Copy を使っている限り、書式・数式・列幅すべてコピーされる。もしコピーされない場合はシート保護が原因の可能性がある
4 PDF出力が白紙になる 印刷範囲が未設定か、データが印刷領域外にある テンプレートシートにあらかじめ印刷範囲(PageSetup.PrintArea)を設定しておく。自分も最初これに気づかず、上司に白紙PDFを渡してしまった
5 通番が飛ぶ(1, 2, 4 のようになる) 議事録シートを手動で削除したが一覧シートの行は残っている 一覧シートの行を削除してから議事録シートを削除する。または通番は欠番を許容する運用にする
6 日付セルに文字列として入力されて日付として扱えない B2セルの書式が「文字列」になっている 入力シートのB2セルの書式を「日付」にするか、コード内で CDate() を使って変換する(コードでは対応済み)

VBAで議事録シートのコピーができないときの対処法

「実行時エラー ‘1004’: シート名が無効です」と表示される場合、会議名にシート名で使えない文字(\ / ? * [ ] :)が含まれていることが原因だ。入力フォームでReplace関数を使って禁止文字を自動除去するか、シート名は通番+日付だけにして会議名はセル内のみで管理するようにしよう。

VBAで議事録の通番が飛ぶときの対処法

「通番が1, 2, 4のように歯抜けになる」場合、議事録シートを手動で削除したのに一覧シートの該当行が残っていることが原因だ。シート削除と一覧行の削除を必ずセットで行う運用ルールにするか、通番は欠番を許容する方針に決めておこう。

FAQ

Q1. テンプレートのレイアウトを途中で変更したら、過去の議事録にも反映される?

反映されない。Sheet.Copy は実行時点のテンプレートをコピーするため、過去に作成済みのシートには影響しない。テンプレートの変更は次回以降の議事録に反映される。

Q2. 一覧シートから特定の議事録シートに直接ジャンプできる?

F列のシート名にハイパーリンクを設定すればジャンプできる。一覧シートに追加する処理の後に以下を追加する:


wsList.Hyperlinks.Add _
    Anchor:=wsList.Cells(newRow, "F"), _
    Address:="", _
    SubAddress:="'" & sheetName & "'!A1", _
    TextToDisplay:=sheetName

セルの値からリンクを作る方法は セルの値からハイパーリンクを一括作成する方法 で詳しく解説している。

Q3. 議事録を別のブックに分けたい場合は?

Sheet.Copy にブック指定を省略すると新しいブックが作成される。ただし、一覧管理との連携が複雑になるため、1ブックで管理し、PDF出力で共有する運用のほうが扱いやすい。

Q4. 出席者をドロップダウンリストから選べるようにしたい

入力シートのB3セルに入力規則を設定すればドロップダウンで選べる。VBAでの設定方法は 入力規則(ドロップダウンリスト)をVBAで一括設定 を参照。

Q5. 議事録の作成をボタン1つで実行するには?

「入力」シートに「議事録作成」「検索」「PDF出力」の3つのボタンを配置し、それぞれのマクロを割り当てる。ボタンの作り方は マクロをボタン1つで実行する方法 を参照。自分もこの構成で運用していて、一番使いやすかった。

まとめ

この記事では、VBAで議事録テンプレートを自動生成し、一覧管理・検索・PDF出力まで一括で行う方法を解説した。

  • 最小版: テンプレートのコピー+会議情報の自動転記
  • 実務版: 通番自動採番+一覧シート管理+キーワード検索+PDF一括出力

議事録は「作る」より「探す」のほうが時間を取られる。一覧管理と検索を組み合わせれば、過去の議事録に数秒でたどり着ける。

次にやりたくなること

コメント

タイトルとURLをコピーしました