残業を減らす!Officeテクニック

Excelの[マクロの記録]だけでは自動化が不十分! Copilotで実用的に改良する方法

「記録したマクロ」はCopilotで実用的なコードに改良できる

 [マクロの記録]を使ったことがあれば、操作内容がVBAのコードとして生成されることはご存じでしょう。記録されたコードを眺めれば、「この部分がセルの選択」「ここがファイルパスの指定」などと、処理の内容も何となく読み取れます。

[マクロの記録]で、今開いているシートをデスクトップにPDFファイルとして保存する操作を記録したコードの例

 困るのは、その先です。例えば、1枚のシートをPDFとして保存するコードは記録できます。しかし、「すべてのシートに対して同じ処理を繰り返す」「特定のシートだけ除外する」といったコードを[マクロの記録]だけで完成させるのは難しいでしょう。

 繰り返し処理は「For Each」、条件判定には「If」を使えばいい。そこまではわかっていても、変数の宣言やオブジェクトの指定まで正確に書くとなると、VBAの構文を調べ直す必要があります。

 そこで、記録したコードをCopilotに渡して改良してみましょう。ゼロからVBAコードを書かせるのではなく、実際にExcelで動作したコードを基に育てていきます。

[マクロの記録]のコードを土台にする

 今回は、ファイル内のすべてのワークシートを別々のPDFファイルとして保存するマクロを作ります。以下は、[マクロの記録]で記録されたコードです。任意のワークシートを1枚だけPDFとして保存する操作を[マクロの記録]で記録しました。なお、記録されるコードは、保存先や操作内容などによって異なります。

Sub PDF出力()
'
' PDF出力 Macro
'

'
    ChDir "C:\Users\mado\Desktop"
    ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
        "C:\Users\mado\Desktop\売上報告書_東京支店.pdf", Quality:=xlQualityStandard, _
        IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:= _
        True
End Sub

 ここで重要なのは、プロパティや引数を知ることではありません。現在選択されているシートを表す「ActiveSheet」に対して、「ExportAsFixedFormat」を実行すればPDFとして出力できます。さらに、「Filename」で保存先を指定している。この処理が実際に動くことは確認できています。

 つまり、PDF出力そのものをCopilotに考えてもらう必要はありません。欲しいのは、この処理を「すべてのワークシートに繰り返す」ためのコードです。

「どこを残して、何を追加するか」をCopilotに伝える

 記録したコードをCopilotに貼り付けて、次のように依頼します。動作しているPDF出力の処理は残して、不足している繰り返し処理や条件分岐を追加してもらいます。ポイントは「すべて書き直して」と依頼しないことです。

 なお、コード部分はコメントを削除して、折り返し位置を調整し、Copilotの出力結果と比較しやすいように調整しています。

以下は、現在のワークシートをPDFとして保存するために[マクロの記録]で作成したVBAコードです。

ExportAsFixedFormatによるPDF出力部分はできるだけそのまま利用して、次のように修正してください。

・このExcelファイルに含まれるすべての表示中のワークシートを順番に処理する

・ワークシートごとに個別のPDFファイルとして保存する

・保存先は、このExcelファイルと同じフォルダーとする

・PDFのファイル名にはワークシート名を使用する

・追加した繰り返し処理と条件分岐について説明する

Sub PDF出力()

ChDir "C:¥Users¥mado¥Desktop"

ActiveSheet.ExportAsFixedFormat _

Type:=xlTypePDF, _

Filename:= "C:¥Users¥mado¥Desktop¥売上報告書_東京支店.pdf", _

Quality:=xlQualityStandard, _

IncludeDocProperties:=True, _

IgnorePrintAreas:=False, _

OpenAfterPublish:=True

End Sub

上記のプロンプトを送信すると、修正されたコードと解説が出力される

 今回は次のように修正されました。元のコードから追加された箇所を見ていきましょう。

Sub PDF出力()

    Dim ws As Worksheet
    Dim SavePath As String

    ' このブックと同じフォルダーのパスを取得
    SavePath = ThisWorkbook.Path

    ' すべてのワークシートを順番に処理
    For Each ws In ThisWorkbook.Worksheets

        ' 表示中のシートのみ対象
        If ws.Visible = xlSheetVisible Then

            ws.ExportAsFixedFormat _
                Type:=xlTypePDF, _
                Filename:=SavePath & "\" & ws.Name & ".pdf", _
                Quality:=xlQualityStandard, _
                IncludeDocProperties:=True, _
                IgnorePrintAreas:=False, _
                OpenAfterPublish:=False

        End If

    Next ws

End Sub

 まず、変数「ws」と「SavePath」の宣言が追加されています。変数「SavePath」には、マクロが保存されているファイルと同じフォルダー(ThisWorkbook.Path)を格納し、「For Each ws In ThisWorkbook.Worksheets」で、ファイルに含まれるワークシートを1枚ずつ変数「ws」に入れて処理しています。

 繰り返し処理のFor Each文の内側にある、「If ws.Visible = xlSheetVisible Then」は、表示されているワークシートだけを処理する条件です。

 大きな変更箇所は「Filename:=SavePath & "¥" & ws.Name & ".pdf"」です。「SavePath」は「ThisWorkbook.Path」ですから、マクロが保存されているファイルと同じフォルダーがPDFの出力先となります。

 「OpenAfterPublish」は「True」から「False」に変更されています。複数のPDFファイルを連続して出力するため、出力するたびにPDFファイルを開かない設定に変更されたと考えられます。

Copilotで出力されたコードを実行すると、表示中のすべてのワークシートが別々のPDFファイルとして出力された。マクロが保存されているファイル(売上報告書.xlsm)と同じフォルダーに保存される

 今回Copilotに任せたのは、PDFとして保存する方法そのものではありません。「記録した1回分の処理」を、ワークシートの数だけ繰り返せる構造へ書き換える部分だけです。

条件を追加しながらコードを育てる

 さらに実際の業務に合わせて、Copilotのサポートを受けながらコードを育てていくことも可能です。例えば、[設定]シートは出力せず、コードの実行時にPDFファイルの保存先を選択できるダイアログボックスを表示したいとしましょう。

 [設定]シートを出力しない処理は、「ワークシート名が『設定』ではない」という条件で分岐できそうです。では、PDFファイルの保存先を選択するダイアログボックスを表示するには?

 コードを眺めて大まかな意味を理解できても、複数条件の指定や、ダイアログボックスの呼び出しといった細かな記述方法を思い出せないことは珍しくありません。現在のコードをCopilotに渡して、修正の意図を伝えてみましょう。

以下のVBAコードを修正してください。

・「設定」という名前のワークシートは処理対象から除外する

・マクロの実行時にフォルダー選択ダイアログを表示する

・選択したフォルダーにPDFファイルを保存する

・上記以外の処理やコードは変更しない

修正後のコード全体を提示し、変更した箇所を簡潔に説明してください。

Sub PDF出力()

Dim ws As Worksheet

Dim SavePath As String

' このブックと同じフォルダーのパスを取得

SavePath = ThisWorkbook.Path

' すべてのワークシートを順番に処理

For Each ws In ThisWorkbook.Worksheets

' 表示中のシートのみ対象

If ws.Visible = xlSheetVisible Then

ws.ExportAsFixedFormat _

Type:=xlTypePDF, _

Filename:=SavePath & "¥" & ws.Name & ".pdf", _

Quality:=xlQualityStandard, _

IncludeDocProperties:=True, _

IgnorePrintAreas:=False, _

OpenAfterPublish:=False

End If

Next ws

End Sub

上記のプロンプトを送信すると、修正されたコードと解説が出力される

 コードは以下のように修正されました。

Sub PDF出力()

    Dim ws As Worksheet
    Dim SavePath As String
    Dim fd As FileDialog

    ' フォルダー選択ダイアログを表示
    Set fd = Application.FileDialog(msoFileDialogFolderPicker)

    If fd.Show <> -1 Then Exit Sub

    SavePath = fd.SelectedItems(1)

    ' すべてのワークシートを順番に処理
    For Each ws In ThisWorkbook.Worksheets

        ' 表示中かつ「設定」シート以外を対象
        If ws.Visible = xlSheetVisible And ws.Name <> "設定" Then

            ws.ExportAsFixedFormat _
                Type:=xlTypePDF, _
                Filename:=SavePath & "\" & ws.Name & ".pdf", _
                Quality:=xlQualityStandard, _
                IncludeDocProperties:=True, _
                IgnorePrintAreas:=False, _
                OpenAfterPublish:=False

        End If

    Next ws

End Sub

 変数「fd」と、ファイルの保存先を選択できるダイアログボックスを表示するコードが追加されています。「If fd.Show <> -1 Then Exit Sub」は、[キャンセル]ボタンがクリックされた時に処理を終了するための条件分岐です。

 変数「SavePath」には、ダイアログボックスで選択したフォルダー(fd.SelectedItems(1))が格納されるように変更されています。

 「If ws.Visible = xlSheetVisible And ws.Name <> "設定" Then」はシートが表示中であり、かつシート名が「設定」ではない場合のみPDF出力する判定です。

 このように、動いているコードに1つずつ条件を追加していけば、どこが変わったのかを追いやすくなります。Copilotに完成形を一気に作らせるよりも、まず1回分の操作を[マクロの記録]で記録して段階的に改良するほうが、コードの内容を把握しやすく、意図しない処理が加わった時にも気付きやすくなります。

 何をしたいかは明確で、For EachやIfを使えばできそうということは理解しているがものの、VBAの正確な書き方までは覚えていない、そんな人こそ、[マクロの記録]とCopilotを組み合わせるメリットがあります。