Excel便利マクロ8選|コピペで使える実務VBAと安全な使い方

山積みの書類とエラーに悩む作業者が、マクロ導入後に自動化によって笑顔でコーヒーを飲みながら業務を完了させている比較イラスト

こんにちは、SkillStack Lab運営者のスタックです。

Excelで毎月同じ転記や集計を繰り返し、「この作業をマクロで自動化できないかな」と感じていませんか。

結論から言うと、重複削除、表示行だけのコピー、シート結合、PDF保存など、デスクトップ版Excel内で繰り返す定型操作はVBAマクロと相性があります。

ただし、インターネットや生成AIで見つけたコードを、そのまま本番ファイルへ貼り付けて実行するのは危険です。

シート名、列、保存先、データ形式が1つ違うだけで、必要なデータを削除したり、別のファイルを上書きしたりする可能性があります。

この記事では、元情シス・現役管理部門長の視点から、実務で使いやすいExcel便利マクロ8選と、実行前に変更する場所、安全にテストする方法を解説します。

掲載コードはサンプルです。必ず元ファイルを複製し、個人情報や実データを含まないテスト環境で確認してください。勤務先のマクロ利用ルールやセキュリティポリシーがある場合は、そちらを優先してください。

この記事で分かること
  • 実務で使いやすいExcel便利マクロ8選
  • コードを貼り付ける前に変更・確認する箇所
  • 削除・上書き・誤送信を防ぐ安全なテスト手順
  • VBA・Power Query・Office Scripts・Python・SaaSの使い分け

Excel for the webではVBAマクロを作成・実行・編集できません。この記事のコードは、VBAを利用できるデスクトップ版Excelでの実行を前提にしています。

目次

Excel便利マクロ8選の早見表

最初に、作業内容と注意点を一覧で確認しましょう。

マクロ主な用途注意点
重複削除顧客・商品リストの整理行が削除されるため複製必須
日付統一CSVや手入力データの整形変換できない文字列を確認
可視セルコピーフィルタ後のデータ転記コピー先の既存データに注意
部署別シート分割名簿・売上表の整理個人情報とシート名に注意
複数シート結合支店・月別データの集約列構成を統一する
複数ブック結合フォルダー内ファイルの集約開くファイルとマクロに注意
PDF保存請求書・見積書の出力保存先とファイル名を確認
Outlook下書き作成定型メールの作成補助classic Outlook向け

複数のCSVやExcelファイルを毎月同じ形で結合・整形するだけなら、VBAよりPower Queryの方が管理しやすい場合があります。

VBA、Power Query、Office Scripts、Pythonなどの選び方が決まっていない方は、先にExcel自動化の具体例と手段の使い分けを確認してください。

マクロを実行する前の安全チェック

コードを試す前に、次の準備を行ってください。

  1. 元ファイルを複製する
    日付を付けたバックアップを作成し、コピー側でテストします。
  2. マクロ有効ブックで保存する
    VBAコードを残す場合は、Excelマクロ有効ブックの「.xlsm」形式を使用します。
  3. シート名と列を確認する
    コード内の「顧客リスト」「部署」「A列」などを自分のファイルに合わせます。
  4. 少量のダミーデータで試す
    本番件数で実行する前に、5~10行程度で結果を確認します。
  5. 処理前後の件数を照合する
    行数、金額、合計、ファイル数が想定どおりか確認します。
  6. 会社の利用ルールを確認する
    外部から取得したマクロを禁止・制限している会社では、管理者のルールを優先します。

ActiveSheetやSelectionへの依存を減らす

ActiveSheetSelectionに依存すると、利用者が想定と違うシートやセルを選んでいた場合に、意図しない場所を変更する可能性があります。

この記事では、マクロを保存しているブックを示すThisWorkbookと、具体的なシート名をできるだけ明示しています。

また、出所や処理内容を確認できないマクロは安易に有効化しないでください。会社のパソコンでは、利用者がセキュリティ設定を独断で変更せず、情報システム担当者へ確認するのが安全です。

Microsoft公式のマクロセキュリティ情報を確認する

データ整理に使えるExcel便利マクロ

1.重複データをコピーシート上で削除する

顧客リストの氏名・電話番号・メールアドレスを使って重複行を確認する流れ

顧客リストや商品マスタを結合すると、同じデータが複数行に入ることがあります。

Excel VBAでは、RemoveDuplicatesメソッドを使って、指定した列の組み合わせが同じ行を削除できます。

次のコードは元シートを複製し、コピーしたシートだけを処理します。

Option Explicit

Sub RemoveDuplicatesOnCopy()

    Dim wsSource As Worksheet
    Dim wsCopy As Worksheet
    Dim lastRow As Long
    Dim newName As String

    Set wsSource = ThisWorkbook.Worksheets("顧客リスト")

    lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row

    If lastRow < 2 Then
        MsgBox "処理するデータがありません。", vbExclamation
        Exit Sub
    End If

    If MsgBox("顧客リストを複製して重複行を削除します。", _
              vbYesNo + vbQuestion) <> vbYes Then
        Exit Sub
    End If

    wsSource.Copy After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)
    Set wsCopy = ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count)

    newName = Left$("重複削除_" & Format(Now, "yyyymmdd_hhnnss"), 31)
    wsCopy.Name = newName

    wsCopy.Range("A1:C" & lastRow).RemoveDuplicates _
        Columns:=Array(1, 2, 3), Header:=xlYes

    MsgBox "コピーシート上で重複削除が完了しました。", vbInformation

End Sub

この例では、A列からC列までの3項目がすべて一致する行を重複として扱います。

  • 「顧客リスト」を実際のシート名に変更する
  • A~C列が重複判定に使用する列か確認する
  • 見出しがない場合はHeader:=xlNoへ変更する
  • 同姓同名の別人を消さないよう判定列を決める
  • 処理前後の行数を確認する

Microsoft公式のRange.RemoveDuplicatesを確認する

2.認識できる日付だけを統一する

形式が異なる日付データを西暦の年月日へ統一するイメージ

Format関数だけでは、認識できない文字列を正しい日付へ自動変換できません。

次のコードは、Excelが日付として認識できる値と「20260101」のような8桁の数字だけを変換し、判定できない値はそのまま残します。

Option Explicit

Sub NormalizeDates()

    Dim ws As Worksheet
    Dim lastRow As Long
    Dim c As Range
    Dim convertedDate As Date
    Dim failedCount As Long

    Set ws = ThisWorkbook.Worksheets("日付データ")
    lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

    For Each c In ws.Range("A2:A" & lastRow)

        If Len(Trim$(CStr(c.Value))) > 0 Then

            If TryConvertDate(c.Value, convertedDate) Then
                c.Value = convertedDate
                c.NumberFormat = "yyyy/mm/dd"
            Else
                failedCount = failedCount + 1
            End If

        End If

    Next c

    MsgBox "変換できなかったセル: " & failedCount & "件", vbInformation

End Sub

Private Function TryConvertDate(ByVal sourceValue As Variant, _
                                ByRef resultDate As Date) As Boolean

    Dim textValue As String
    Dim yearValue As Long
    Dim monthValue As Long
    Dim dayValue As Long

    On Error GoTo ConversionFailed

    If IsDate(sourceValue) Then
        resultDate = CDate(sourceValue)
        TryConvertDate = True
        Exit Function
    End If

    textValue = Trim$(CStr(sourceValue))

    If Len(textValue) = 8 And IsNumeric(textValue) Then

        yearValue = CLng(Left$(textValue, 4))
        monthValue = CLng(Mid$(textValue, 5, 2))
        dayValue = CLng(Right$(textValue, 2))

        resultDate = DateSerial(yearValue, monthValue, dayValue)

        If Year(resultDate) = yearValue _
           And Month(resultDate) = monthValue _
           And Day(resultDate) = dayValue Then

            TryConvertDate = True
            Exit Function

        End If

    End If

ConversionFailed:
    TryConvertDate = False

End Function

「R8.1.1」「令和8年1月1日」などの和暦文字列は、パソコンの地域設定や入力状態で判定結果が変わることがあります。変換できなかった件数を確認し、必要に応じて自社用の変換ルールを追加してください。

3.フィルタ後の表示セルだけをコピーする

フィルタで絞り込んだ行だけを別シートへコピーする場合は、SpecialCells(xlCellTypeVisible)を使用します。

Option Explicit

Sub CopyVisibleCells()

    Dim wsSource As Worksheet
    Dim wsOutput As Worksheet
    Dim sourceRange As Range
    Dim visibleRange As Range

    Set wsSource = ThisWorkbook.Worksheets("売上データ")
    Set wsOutput = ThisWorkbook.Worksheets("抽出結果")
    Set sourceRange = wsSource.Range("A1").CurrentRegion

    On Error Resume Next
    Set visibleRange = sourceRange.SpecialCells(xlCellTypeVisible)
    On Error GoTo 0

    If visibleRange Is Nothing Then
        MsgBox "コピーできる表示セルがありません。", vbExclamation
        Exit Sub
    End If

    If MsgBox("抽出結果シートの既存データを消してコピーします。", _
              vbYesNo + vbQuestion) <> vbYes Then
        Exit Sub
    End If

    wsOutput.Cells.Clear
    visibleRange.Copy Destination:=wsOutput.Range("A1")

    Application.CutCopyMode = False

    MsgBox "表示中のセルをコピーしました。", vbInformation

End Sub

コードを実行する前に、売上データシート側で必要なフィルタを設定しておきます。

  • コピー先の既存データを消してよいか確認する
  • 見出し行もコピーされることを確認する
  • 結合セルを含む表では事前にテストする
  • フィルタ条件が正しいか画面上で確認する

Microsoft公式のRange.SpecialCellsを確認する

シートやブックを整理するExcel便利マクロ

4.データを部署別のシートへ分割する

マスター表を部署名ごとのシートへ分割する処理の流れ

1つの社員名簿や売上表を、部署・支店・担当者ごとのシートに分割する例です。

次のコードでは、C列に部署名が入っていることを前提にしています。

Option Explicit

Sub SplitDataByDepartment()

    Dim wsSource As Worksheet
    Dim wsOutput As Worksheet
    Dim lastRow As Long
    Dim lastColumn As Long
    Dim departmentCell As Range
    Dim departmentName As Variant
    Dim departmentList As Object
    Dim outputSheetName As String
    Dim sourceRange As Range

    Set wsSource = ThisWorkbook.Worksheets("社員名簿")
    Set departmentList = CreateObject("Scripting.Dictionary")

    lastRow = wsSource.Cells(wsSource.Rows.Count, "A").End(xlUp).Row
    lastColumn = wsSource.Cells(1, wsSource.Columns.Count).End(xlToLeft).Column

    For Each departmentCell In wsSource.Range("C2:C" & lastRow)

        If Len(Trim$(CStr(departmentCell.Value))) > 0 Then
            departmentList(Trim$(CStr(departmentCell.Value))) = True
        End If

    Next departmentCell

    Set sourceRange = wsSource.Range( _
        wsSource.Cells(1, 1), _
        wsSource.Cells(lastRow, lastColumn))

    Application.ScreenUpdating = False
    On Error GoTo ErrorHandler

    For Each departmentName In departmentList.Keys

        outputSheetName = CreateSafeSheetName(CStr(departmentName))
        Set wsOutput = Nothing

        On Error Resume Next
        Set wsOutput = ThisWorkbook.Worksheets(outputSheetName)
        On Error GoTo ErrorHandler

        If wsOutput Is Nothing Then
            Set wsOutput = ThisWorkbook.Worksheets.Add( _
                After:=ThisWorkbook.Worksheets(ThisWorkbook.Worksheets.Count))
            wsOutput.Name = outputSheetName
        Else
            wsOutput.Cells.Clear
        End If

        sourceRange.AutoFilter Field:=3, Criteria1:=CStr(departmentName)
        sourceRange.SpecialCells(xlCellTypeVisible).Copy _
            Destination:=wsOutput.Range("A1")

    Next departmentName

SafeExit:

    If wsSource.AutoFilterMode Then
        wsSource.AutoFilterMode = False
    End If

    Application.CutCopyMode = False
    Application.ScreenUpdating = True

    Exit Sub

ErrorHandler:

    MsgBox "シート分割中にエラーが発生しました: " _
        & Err.Description, vbExclamation
    Resume SafeExit

End Sub

Private Function CreateSafeSheetName(ByVal sourceName As String) As String

    Dim invalidCharacters As Variant
    Dim targetCharacter As Variant

    invalidCharacters = Array("\", "/", ":", "*", "?", "[", "]")

    For Each targetCharacter In invalidCharacters
        sourceName = Replace(sourceName, CStr(targetCharacter), " ")
    Next targetCharacter

    sourceName = Trim$(sourceName)

    If Len(sourceName) = 0 Then
        sourceName = "未設定"
    End If

    CreateSafeSheetName = Left$(sourceName, 31)

End Function

部署名にシート名として使えない記号が含まれる場合は置換しています。ただし、置換後や31文字への切り詰め後に同じシート名になる部署が存在すると衝突する可能性があります。実データで部署名が重複しないか確認してください。

部署ごとのシートを作るだけではアクセス権限を分離できません。同じブック内に閲覧してはいけない社員情報が残る可能性があるため、社外や他部署へ配布する場合は個人情報と権限を確認してください。

5.複数シートを1つの集計シートへ結合する

支店別・月別に分かれたシートの列構成が同じであれば、データを1つの「全社集計」シートへまとめられます。

Option Explicit

Sub MergeWorksheets()

    Dim ws As Worksheet
    Dim wsOutput As Worksheet
    Dim lastRow As Long
    Dim lastColumn As Long
    Dim outputRow As Long
    Dim headerCopied As Boolean

    Set wsOutput = ThisWorkbook.Worksheets("全社集計")

    If MsgBox("全社集計シートの既存データを消して再作成します。", _
              vbYesNo + vbQuestion) <> vbYes Then
        Exit Sub
    End If

    wsOutput.Cells.Clear
    outputRow = 1
    headerCopied = False

    For Each ws In ThisWorkbook.Worksheets

        If ws.Name <> wsOutput.Name Then

            lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
            lastColumn = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column

            If lastRow >= 1 And lastColumn >= 1 Then

                If Not headerCopied Then
                    ws.Range(ws.Cells(1, 1), _
                             ws.Cells(1, lastColumn)).Copy _
                             Destination:=wsOutput.Cells(1, 1)

                    outputRow = 2
                    headerCopied = True
                End If

                If lastRow >= 2 Then
                    ws.Range(ws.Cells(2, 1), _
                             ws.Cells(lastRow, lastColumn)).Copy _
                             Destination:=wsOutput.Cells(outputRow, 1)

                    outputRow = wsOutput.Cells( _
                        wsOutput.Rows.Count, "A").End(xlUp).Row + 1
                End If

            End If

        End If

    Next ws

    Application.CutCopyMode = False

    MsgBox "シートの結合が完了しました。", vbInformation

End Sub

このコードは、すべての対象シートで列順が同じで、1行目が見出しであることを前提にしています。

シートごとに列名や順序が違う場合は、VBAで位置を無理に合わせるより、Power Queryなどで列名を基準に整形・結合する方法も比較してください。

6.フォルダー内の複数ブックを安全に結合する

フォルダー内の複数Excelファイルを集計ブックへまとめる流れ

各担当者や支店から届いた複数のExcelファイルを、1つの集計シートへ追加する例です。

ここは他のサンプルより注意が必要です。VBAからWorkbooks.Openでファイルを開く処理では、開くファイル自体の安全性も考慮する必要があります。

次のコードでは、外部ブックを開いている間だけ自動実行マクロを無効化し、外部リンクも更新しないようにしています。

Option Explicit

Sub MergeWorkbooksInFolder()

    Dim wsOutput As Worksheet
    Dim sourceWorkbook As Workbook
    Dim sourceWorksheet As Worksheet
    Dim folderPath As String
    Dim fileName As String
    Dim lastRow As Long
    Dim lastColumn As Long
    Dim outputRow As Long
    Dim folderPicker As FileDialog
    Dim previousAutomationSecurity As Long

    Set wsOutput = ThisWorkbook.Worksheets("ブック集計")
    Set folderPicker = Application.FileDialog(msoFileDialogFolderPicker)

    If folderPicker.Show <> -1 Then
        Exit Sub
    End If

    folderPath = folderPicker.SelectedItems(1) & Application.PathSeparator

    If MsgBox("ブック集計シートの既存データを消して結合します。", _
              vbYesNo + vbQuestion) <> vbYes Then
        Exit Sub
    End If

    wsOutput.Cells.Clear
    outputRow = 1

    previousAutomationSecurity = Application.AutomationSecurity

    Application.ScreenUpdating = False
    Application.AutomationSecurity = msoAutomationSecurityForceDisable

    On Error GoTo ErrorHandler

    fileName = Dir(folderPath & "*.xls*")

    Do While Len(fileName) > 0

        If Left$(fileName, 2) <> "~$" _
           And StrComp(folderPath & fileName, _
                       ThisWorkbook.FullName, _
                       vbTextCompare) <> 0 Then

            Set sourceWorkbook = Workbooks.Open( _
                Filename:=folderPath & fileName, _
                UpdateLinks:=0, _
                ReadOnly:=True)

            Set sourceWorksheet = sourceWorkbook.Worksheets(1)

            lastRow = sourceWorksheet.Cells( _
                sourceWorksheet.Rows.Count, "A").End(xlUp).Row

            lastColumn = sourceWorksheet.Cells( _
                1, sourceWorksheet.Columns.Count).End(xlToLeft).Column

            If outputRow = 1 Then

                sourceWorksheet.Range( _
                    sourceWorksheet.Cells(1, 1), _
                    sourceWorksheet.Cells(lastRow, lastColumn)).Copy _
                    Destination:=wsOutput.Cells(1, 1)

            ElseIf lastRow >= 2 Then

                sourceWorksheet.Range( _
                    sourceWorksheet.Cells(2, 1), _
                    sourceWorksheet.Cells(lastRow, lastColumn)).Copy _
                    Destination:=wsOutput.Cells(outputRow, 1)

            End If

            outputRow = wsOutput.Cells( _
                wsOutput.Rows.Count, "A").End(xlUp).Row + 1

            sourceWorkbook.Close SaveChanges:=False
            Set sourceWorkbook = Nothing

        End If

        fileName = Dir

    Loop

SafeExit:

    If Not sourceWorkbook Is Nothing Then
        sourceWorkbook.Close SaveChanges:=False
    End If

    Application.CutCopyMode = False
    Application.AutomationSecurity = previousAutomationSecurity
    Application.ScreenUpdating = True

    MsgBox "ブックの結合処理が終了しました。", vbInformation

    Exit Sub

ErrorHandler:

    MsgBox "ブック結合中にエラーが発生しました: " _
        & Err.Description, vbExclamation
    Resume SafeExit

End Sub
  • 対象ファイルの1枚目のシートを読み込む仕様になっている
  • 1行目の見出しと列順が全ファイルで同じか確認する
  • ~$で始まるExcelの一時ファイルは除外している
  • 外部リンクは更新せずに開く
  • 外部ブックの自動実行マクロを無効にして開く
  • パスワード付きや破損したファイルでは停止する可能性がある
  • 本番フォルダーではなく、必要なファイルだけコピーしたテスト用フォルダーで確認する

毎月同じ形式のファイルを集めるだけならPower Queryも比較してください。
Power Queryにはフォルダー内の同じ構造のファイルを結合する標準機能があり、対象ファイルを絞り込んでから結合することもできます。

帳票・メール作成に使えるExcel便利マクロ

Excelの帳票をPDFへ保存しOutlookメールの下書きを作る流れ

写真台帳や報告書へ画像を繰り返し配置する業務では、写真を結合セルへ自動サイズ調整して貼り付けるExcelマクロも活用できます。画像の縦横比を維持した中央配置や、複数写真の一括処理を解説しています。

7.帳票を安全なファイル名でPDF保存する

Excel VBAでは、ExportAsFixedFormatメソッドを使用して、指定したシートをPDFとして保存できます。

次のコードでは、帳票シートのA1に顧客名、B1に請求日が入っていることを前提にしています。

Option Explicit

Sub ExportInvoiceAsPDF()

    Dim ws As Worksheet
    Dim outputFolder As String
    Dim customerName As String
    Dim invoiceDate As Date
    Dim outputFile As String

    Set ws = ThisWorkbook.Worksheets("請求書")

    customerName = Trim$(CStr(ws.Range("A1").Value))

    If Len(customerName) = 0 Then
        MsgBox "A1に顧客名を入力してください。", vbExclamation
        Exit Sub
    End If

    If Not IsDate(ws.Range("B1").Value) Then
        MsgBox "B1に正しい請求日を入力してください。", vbExclamation
        Exit Sub
    End If

    invoiceDate = CDate(ws.Range("B1").Value)

    If Len(ThisWorkbook.Path) = 0 Then
        MsgBox "先にExcelファイルを保存してください。", vbExclamation
        Exit Sub
    End If

    outputFolder = ThisWorkbook.Path _
        & Application.PathSeparator & "PDF"

    If Dir(outputFolder, vbDirectory) = "" Then
        MkDir outputFolder
    End If

    outputFile = outputFolder _
        & Application.PathSeparator _
        & CreateSafeFileName(customerName) _
        & "_" & Format(invoiceDate, "yyyymm") _
        & "_請求書.pdf"

    If Len(Dir(outputFile)) > 0 Then

        If MsgBox("同名のPDFを上書きしますか?", _
                  vbYesNo + vbQuestion) <> vbYes Then
            Exit Sub
        End If

    End If

    ws.ExportAsFixedFormat _
        Type:=xlTypePDF, _
        Filename:=outputFile, _
        Quality:=xlQualityStandard, _
        IncludeDocProperties:=True, _
        IgnorePrintAreas:=False, _
        OpenAfterPublish:=True

    MsgBox "PDFを保存しました。", vbInformation

End Sub

Private Function CreateSafeFileName(ByVal sourceName As String) As String

    Dim invalidCharacters As Variant
    Dim targetCharacter As Variant

    invalidCharacters = Array("\", "/", ":", "*", "?", """", "<", ">", "|")

    For Each targetCharacter In invalidCharacters
        sourceName = Replace(sourceName, CStr(targetCharacter), "_")
    Next targetCharacter

    CreateSafeFileName = Trim$(sourceName)

End Function
  • 印刷範囲と改ページを事前に確認する
  • 同名ファイルを上書きしてよいか確認する
  • 顧客名にファイル名で使えない文字がないか確認する
  • PDFを開き、金額・宛名・ページ数を目視する
  • 請求書の送付前に社内の承認手順を通す

Microsoft公式のWorksheet.ExportAsFixedFormatを確認する

PDF保存だけでなく、印刷プレビュー、印刷範囲の自動更新、ボタンからの実行まで設定したい方は、Excelマクロで印刷ボタンを作る方法も確認してください。

8.classic Outlookでメールを自動送信せず下書き表示する

Excelの宛先・会社名・金額をOutlookメールの下書きへ反映するイメージ

メールの自動化では、.Sendによる即時送信を避け、最初は.Displayで下書きを表示してください。

次のコードは、メールリストで現在選択している行の情報から1件のメール下書きを作ります。

Option Explicit

Sub CreateOutlookDraftFromSelectedRow()

    Dim ws As Worksheet
    Dim selectedRow As Long
    Dim mailAddress As String
    Dim companyName As String
    Dim personName As String
    Dim paymentAmount As Variant
    Dim outlookApp As Object
    Dim mailItem As Object

    Set ws = ThisWorkbook.Worksheets("メールリスト")

    If ActiveSheet.Name <> ws.Name Then
        MsgBox "メールリストシートの対象行を選択してください。", vbExclamation
        Exit Sub
    End If

    selectedRow = ActiveCell.Row

    If selectedRow < 2 Then
        MsgBox "2行目以降の対象データを選択してください。", vbExclamation
        Exit Sub
    End If

    mailAddress = Trim$(CStr(ws.Cells(selectedRow, "A").Value))
    companyName = Trim$(CStr(ws.Cells(selectedRow, "B").Value))
    personName = Trim$(CStr(ws.Cells(selectedRow, "C").Value))
    paymentAmount = ws.Cells(selectedRow, "D").Value

    If Len(mailAddress) = 0 Or InStr(mailAddress, "@") = 0 Then
        MsgBox "メールアドレスを確認してください。", vbExclamation
        Exit Sub
    End If

    On Error GoTo OutlookError

    Set outlookApp = CreateObject("Outlook.Application")
    Set mailItem = outlookApp.CreateItem(0)

    With mailItem
        .To = mailAddress
        .Subject = "ご請求内容のご確認"
        .Body = companyName & vbCrLf _
            & personName & " 様" & vbCrLf & vbCrLf _
            & "いつもお世話になっております。" & vbCrLf _
            & "ご請求金額は " _
            & Format(paymentAmount, "#,##0") _
            & " 円です。" & vbCrLf & vbCrLf _
            & "内容をご確認ください。"
        .Display
    End With

    Set mailItem = Nothing
    Set outlookApp = Nothing

    Exit Sub

OutlookError:

    MsgBox "Outlookの下書きを作成できませんでした。" & vbCrLf _
        & "classic Outlookを利用しているか確認してください。" & vbCrLf _
        & Err.Description, vbExclamation

End Sub

このコードはWindows版classic Outlookを前提としています。
new OutlookではVBAや従来型のマクロがサポートされていません。new Outlookを前提に新しく業務を作る場合は、Power Automateなど別の方法も比較してください。

  • 送信先メールアドレスと会社名を目視する
  • 別の顧客名や金額が入っていないか確認する
  • 添付ファイルを自動化する場合はファイル名と中身を確認する
  • 大量送信や営業メールに使用する場合は社内ルールを確認する
  • 顧客情報を含むファイルの権限と保管場所を確認する
  • テスト時は自分のメールアドレスだけを使用する

Microsoft公式でnew OutlookのVBA代替手段を確認する

コードを自分で修正できるようになりたい方へ

サンプルコードを自分の帳票や業務に合わせて変更するには、変数、条件分岐、繰り返し処理、エラー処理、デバッグなどVBAの基礎を理解しておくと応用しやすくなります。

コードをその都度検索してつなぎ合わせるだけでなく、画面操作を見ながら体系的に学びたい方は、初心者向け・実務向け・ChatGPT活用まで目的別に比較した記事を参考にしてください。

VBAより別の方法が向いているケース

コードを書けることと、VBAがその業務に最適であることは別です。

作業第一候補理由
複数CSV・Excelを毎月結合するPower Query取得・整形手順を再利用しやすい
Excel内の帳票やセルを細かく操作するVBAデスクトップ版Excelの操作に向く
ExcelをWeb・Mac・Windowsで共有して自動化するOffice Scriptsクラウド・クロスプラットフォーム向け
メールや複数サービスを連携するPower Automateアプリ間のフローを組みやすい
大量ファイルやAPIを処理するPythonExcel外のデータも扱いやすい
勤怠・会計・問い合わせを複数人で管理するSaaS権限・履歴・同時利用を標準化しやすい

特に、同じ形式のファイルをフォルダーから繰り返し結合する用途は、Power Queryに標準のフォルダー結合機能があります。

Excel内の操作をチームで共有したい場合はOffice Scriptsも候補です。VBAがデスクトップ向けなのに対し、Office Scriptsはクラウド・クロスプラットフォームでの利用を想定した仕組みです。

勤怠、会計、請求、問い合わせ管理など、停止すると会社や顧客へ影響する業務は、マクロを増やす前に専用システムも比較してください。

Excelを残す業務とクラウドへ移行する業務は、バックオフィス向け脱Excelツールの比較で整理しています。

元情シス・管理部門長としての判断

自分だけが使う小規模な作業や、停止しても影響が限定される集計であれば、VBAは現在も有効です。

一方、複数部署で利用する、作成者以外が直せない、給与・請求・顧客対応に影響するという場合は、コードを追加する前に保守担当者と代替手段を決めます。

VBAをPythonへ置き換えただけでも、担当者が一人なら属人化は残ります。技術の種類より、テスト、権限、バックアップ、手順書、引き継ぎの設計が重要です。

すでに多くのマクロを抱えている方は、VBAを続ける業務と別の手段へ移行する業務の判断基準も確認してください。

Excel便利マクロに関するよくある質問

コードはそのままコピペすれば動きますか?

シート名、列、見出し行、保存先がサンプルと一致しなければ動きません。最低限、Worksheets("シート名")、列記号、開始行、ファイルパスを確認し、複製したファイルで実行してください。

マクロは.xlsx形式で保存できますか?

通常の.xlsx形式にはVBAコードを保存できません。コードを残す場合は、Excelマクロ有効ブックの.xlsm形式で保存します。

Excel for the webでもVBAは動きますか?

Excel for the webではVBAマクロを作成・実行・編集できません。マクロを含むブック自体は開ける場合がありますが、VBAを実行する場合は対応するデスクトップ版Excelが必要です。

複数ファイルの結合はVBAとPower Queryのどちらがよいですか?

毎月同じ形式のファイルを読み込み、結合・整形するだけならPower Queryが第一候補です。読み込み後にシート作成、セルの書式変更、PDF出力などExcel画面の細かな操作まで行うならVBAも候補になります。

外部のExcelファイルをVBAで開いても安全ですか?

信頼できないファイルを無条件に開くべきではありません。プログラムからブックを開く処理では、外部マクロ、外部リンク、一時ファイルなども考慮します。この記事の複数ブック結合例では、外部マクロを無効にし、リンクを更新せず、読み取り専用で開いています。

Outlookメールを完全自動送信してもよいですか?

最初から.Sendで送信する運用はおすすめしません。.Displayで下書きを表示し、宛先、件名、本文、添付ファイルを確認してから手動で送信する運用から始めてください。

new OutlookでもExcel VBAからメールを作れますか?

この記事のCreateObject("Outlook.Application")を使うコードはclassic Outlook向けです。new OutlookではVBA・マクロがサポートされていないため、新しく仕組みを作る場合はPower Automateなどの代替方法も比較してください。

まとめ|便利マクロは小さく安全に試す

Excelマクロをバックアップとテストを行いながら安全に導入する考え方

Excel VBAを使うと、重複削除、シート結合、PDF保存などの定型操作をまとめて実行できます。

  • 元ファイルを複製してから実行する
  • ActiveSheetへの依存を減らして対象ブックとシートを明示する
  • 少量のダミーデータで結果を確認する
  • 削除・上書き・送信を伴う処理は確認画面を入れる
  • 外部ブックを開く場合はマクロや外部リンクにも注意する
  • 複数ファイルの定期結合はPower Queryも比較する
  • 重要業務や複数人利用ではOffice Scripts・Power Automate・SaaSも検討する
  • 作成者以外が使える手順書を残す

最初から大きな業務を自動化せず、失敗しても影響が小さい作業を1つ選ぶことが重要です。

次に必要なのは、マクロを増やすことではなく、対象業務にVBAが合っているかを判断することです。

Excel内の細かな操作はVBA、定期的なデータ結合はPower Query、共有しやすいExcel自動化はOffice Scripts、外部サービス連携はPower Automate、大量ファイルやAPI処理はPython、複数人で使う重要業務はSaaSというように、作業内容から方法を選びましょう。

\ VBAを自分の業務に応用できるようになる /

VBA以外の方法も比較したい方は、Excel自動化7選も参考にしてください。

Excel・VBA・Outlookの利用可能な機能は、OS、Officeのバージョン、利用しているOutlook、組織の管理ポリシーによって異なる場合があります。本記事は2026年8月15日時点でMicrosoftの公開情報を確認して更新しています。


次は、仕事で使えるスキルをもう一段積み上げる

SkillStack Labでは、Excel・生成AI・自動化・オンライン学習を、実務で使うことを前提に解説しています。今の課題に近いテーマから次の記事へ進んでみてください。

生成AIを仕事で使いたい

ChatGPTなどを「触ったことがある」から、実際の仕事で使えるレベルへ進みたい方へ。

生成AIの勉強方法・学習順序を見る →

Excel作業を自動化したい

関数だけでは限界を感じてきたら、Power Query・VBA・Pythonなども含めて自動化を考えます。

Excel業務を自動化する方法を見る →

体系的にスキルを学びたい

Excel・VBA・Python・生成AIなどを、動画講座で効率よく学びたい方へ。

社会人向けUdemy講座の選び方を見る →

何から始めるか迷ったら、今の仕事で最も時間がかかっている作業や、身につけたいスキルに近いテーマから選んでください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次