写真台帳をExcelで作る方法 すぐ使えるVBAコード付き

Excel VBA

写真台帳をExcelで作るとき、最初につまずきやすいのが写真の貼り付け作業です。

写真を1枚ずつ挿入し、サイズを合わせ、枠の中に収め、横や下にファイル名やコメントを入れる。数枚なら手作業でも対応できますが、現場写真、工事写真、点検写真が何十枚もあると、かなり面倒です。

しかも、手作業で貼り付けると、写真サイズが揃わなかったり、枠から少しはみ出したり、印刷やPDF出力の段階で位置がずれたりします。

この記事では、写真台帳をExcelで作るときの基本構成と、指定フォルダ内の写真をExcel上の写真枠へ順番に貼り付ける、すぐ使えるVBAコードを紹介します。

コードはそのまま試せる形にしていますが、実際に使うテンプレート、結合セル、印刷範囲、写真枠の位置に合わせて調整が必要です。

Excel写真台帳の基本構成

Excelで写真台帳を作る場合、よくある構成は次のようなものです。

  • 写真枠
  • 写真番号
  • ファイル名
  • 写真タイトル
  • コメント欄
  • 備考欄
  • ページ番号
  • 印刷範囲
  • 余白設定

1ページに写真を何枚入れるかは、用途によって変わります。3枚台帳、6枚台帳、8枚台帳などがあります。

工事写真や施工写真では、1枚ごとに写真タイトルやコメントを付けることが多く、点検写真では損傷内容や確認内容を併記することもあります。

重要なのは、写真の見た目だけでなく、写真と説明文の対応を崩さないことです。

写真だけが正しく貼られていても、コメントが1行ずれていたら、台帳としては危険です。

手作業で貼り付けると起きやすい問題

Excelに写真を手作業で貼ると、次のような問題が起きやすくなります。

  • 写真サイズが揃わない
  • 写真が枠からはみ出す
  • 写真の縦横比が崩れる
  • 写真の位置が少しずつずれる
  • 写真とファイル名の対応が分からなくなる
  • コメント欄が写真とずれる
  • 印刷すると写真が切れる
  • PDF出力するとレイアウトが崩れる

画面上ではきれいに見えていても、印刷プレビューやPDF出力では位置が変わって見えることがあります。Excelで写真台帳を作るときに画像がずれる原因については、別記事で整理しています。

また、PDF出力時のレイアウト崩れも確認が必要です。提出前には、Excel画面だけでなく、印刷プレビューとPDF出力後の状態を確認するのが安全です。

VBAで効率化できる範囲

VBAを使うと、写真台帳作成のうち、次のような作業を効率化できます。

  • 写真フォルダを選択する
  • jpg / jpeg / png を順番に取得する
  • 指定した写真枠へ貼り付ける
  • 縦横比を保ったまま枠内に収める
  • 写真を枠の中央に配置する
  • ファイル名を所定セルへ入れる
  • 既存画像を削除して貼り直す

一方で、VBAだけで完結させない方がよい部分もあります。

たとえば、写真の選定、コメントの妥当性、提出様式との整合、工事写真としての必要性、発注者指定様式への適合などは、人間が確認する必要があります。

VBAは、あくまで貼り付けや整形を補助する道具です。

すぐ使えるVBAコード:フォルダ内写真を写真枠へ順番に貼る

ここから、指定フォルダ内の写真を、Excelシート上の写真枠へ順番に貼り付けるVBAコードを紹介します。

このサンプルでは、写真台帳 シートに6枚分の写真枠を想定しています。貼付先のセル範囲はコード内の photoRanges で指定しています。

実際のテンプレートに合わせる場合は、B4:H15 などのセル範囲を書き換えて使ってください。

以下のコードは、写真台帳作成を補助するためのサンプルです。利用するExcelのバージョン、シート構成、結合セル、印刷範囲、画像サイズ、余白設定によって調整が必要になる場合があります。

実務ファイルで実行する前に、必ずファイルのバックアップを取ってください。まずはテスト用ブックとテスト用写真で動作確認してください。マクロを使うには、Excel側でマクロを有効化する必要があります。

Option Explicit

Sub 写真台帳へ写真を順番に貼り付ける()

    Dim ws As Worksheet
    Dim folderPath As String
    Dim files() As String
    Dim fileCount As Long
    Dim i As Long
    Dim frameIndex As Long
    Dim pageIndex As Long
    Dim rowOffset As Long

    Dim photoRanges As Variant
    Dim fileNameCells As Variant
    Const PAGE_ROW_HEIGHT As Long = 45

    folderPath = SelectPhotoFolder()
    If folderPath = "" Then Exit Sub

    files = GetPhotoFiles(folderPath, fileCount)

    If fileCount = 0 Then
        MsgBox "対象フォルダに jpg / jpeg / png ファイルが見つかりませんでした。", vbExclamation
        Exit Sub
    End If

    SortStringArray files, fileCount

    Set ws = GetOrCreateSheet("写真台帳")

    photoRanges = Array("B4:H15", "J4:P15", _
                        "B19:H30", "J19:P30", _
                        "B34:H45", "J34:P45")

    fileNameCells = Array("B16", "J16", _
                          "B31", "J31", _
                          "B46", "J46")

    DeletePhotoShapes ws, "PHOTO_"

    Application.ScreenUpdating = False

    For i = 1 To fileCount

        frameIndex = (i - 1) Mod (UBound(photoRanges) + 1)
        pageIndex = Int((i - 1) / (UBound(photoRanges) + 1))
        rowOffset = pageIndex * PAGE_ROW_HEIGHT

        InsertPictureFitToRange _
            ws:=ws, _
            picturePath:=folderPath & "\" & files(i), _
            targetRange:=OffsetRange(ws.Range(photoRanges(frameIndex)), rowOffset), _
            shapeName:="PHOTO_" & Format$(i, "0000")

        OffsetRange(ws.Range(fileNameCells(frameIndex)), rowOffset).Value = files(i)

    Next i

    Application.ScreenUpdating = True

    MsgBox "写真を貼り付けました。" & vbCrLf & _
           "貼付枚数: " & fileCount & " 枚" & vbCrLf & _
           "印刷範囲とPDF出力結果を確認してください。", vbInformation

End Sub

Private Function SelectPhotoFolder() As String

    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = "写真フォルダを選択してください"
        .AllowMultiSelect = False

        If .Show <> -1 Then
            SelectPhotoFolder = ""
        Else
            SelectPhotoFolder = .SelectedItems(1)
        End If
    End With

End Function

Private Function GetPhotoFiles(ByVal folderPath As String, ByRef fileCount As Long) As String()

    Dim tempFiles() As String
    Dim fileName As String
    Dim ext As String

    ReDim tempFiles(1 To 1)
    fileCount = 0

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

    Do While fileName <> ""
        ext = LCase$(Mid$(fileName, InStrRev(fileName, ".") + 1))

        If ext = "jpg" Or ext = "jpeg" Or ext = "png" Then
            fileCount = fileCount + 1
            ReDim Preserve tempFiles(1 To fileCount)
            tempFiles(fileCount) = fileName
        End If

        fileName = Dir()
    Loop

    GetPhotoFiles = tempFiles

End Function

Private Sub SortStringArray(ByRef arr() As String, ByVal itemCount As Long)

    Dim i As Long
    Dim j As Long
    Dim tmp As String

    If itemCount <= 1 Then Exit Sub

    For i = 1 To itemCount - 1
        For j = i + 1 To itemCount
            If StrComp(arr(i), arr(j), vbTextCompare) > 0 Then
                tmp = arr(i)
                arr(i) = arr(j)
                arr(j) = tmp
            End If
        Next j
    Next i

End Sub

Private Function GetOrCreateSheet(ByVal sheetName As String) As Worksheet

    Dim ws As Worksheet

    On Error Resume Next
    Set ws = ThisWorkbook.Worksheets(sheetName)
    On Error GoTo 0

    If ws Is Nothing Then
        Set ws = ThisWorkbook.Worksheets.Add
        ws.Name = sheetName
    End If

    Set GetOrCreateSheet = ws

End Function

Private Function OffsetRange(ByVal baseRange As Range, ByVal rowOffset As Long) As Range

    Set OffsetRange = baseRange.Offset(rowOffset, 0)

End Function

Private Sub InsertPictureFitToRange(ByVal ws As Worksheet, _
                                    ByVal picturePath As String, _
                                    ByVal targetRange As Range, _
                                    ByVal shapeName As String)

    Dim shp As Shape
    Dim scaleW As Double
    Dim scaleH As Double
    Dim scaleFactor As Double

    Set shp = ws.Shapes.AddPicture( _
        Filename:=picturePath, _
        LinkToFile:=msoFalse, _
        SaveWithDocument:=msoTrue, _
        Left:=targetRange.Left, _
        Top:=targetRange.Top, _
        Width:=-1, _
        Height:=-1)

    shp.LockAspectRatio = msoTrue

    scaleW = targetRange.Width / shp.Width
    scaleH = targetRange.Height / shp.Height

    If scaleW < scaleH Then
        scaleFactor = scaleW
    Else
        scaleFactor = scaleH
    End If

    shp.Width = shp.Width * scaleFactor
    shp.Height = shp.Height * scaleFactor

    shp.Left = targetRange.Left + (targetRange.Width - shp.Width) / 2
    shp.Top = targetRange.Top + (targetRange.Height - shp.Height) / 2

    shp.Placement = xlMoveAndSize
    shp.Name = shapeName

End Sub

Private Sub DeletePhotoShapes(ByVal ws As Worksheet, ByVal prefix As String)

    Dim i As Long

    For i = ws.Shapes.Count To 1 Step -1
        If Left$(ws.Shapes(i).Name, Len(prefix)) = prefix Then
            ws.Shapes(i).Delete
        End If
    Next i

End Sub

コードの使い方

このコードは、写真台帳 というシートへ写真を貼り付けます。

まだ 写真台帳 シートがない場合は、自動で作成します。ただし、実際の提出用テンプレートに合わせる場合は、あらかじめ写真枠やコメント欄を作ったシートを用意し、シート名を 写真台帳 にしておく方が扱いやすいです。

使い方の流れは次のとおりです。

  • テスト用のExcelブックを用意する
  • 写真台帳 シートを作る
  • 写真枠にしたいセル範囲を決める
  • VBAエディターで標準モジュールを追加する
  • コードを貼り付ける
  • photoRangesfileNameCells を必要に応じて変更する
  • マクロを実行する
  • 写真フォルダを選択する
  • 貼付結果を確認する

コード内では、次の部分が写真枠です。

photoRanges = Array("B4:H15", "J4:P15", _
                    "B19:H30", "J19:P30", _
                    "B34:H45", "J34:P45")

この範囲を、自分のテンプレートに合わせて変更します。

たとえば、1ページ3枚の写真台帳なら、3つの範囲だけを指定する形に変更できます。1ページ6枚なら、今回のように6つの範囲を指定します。

調整が必要なポイント

このコードは、一般的な写真台帳の考え方をもとにしたサンプルです。

実務で使う場合は、次の点を確認してください。

  • 写真枠のセル範囲
  • ファイル名を表示するセル
  • 写真タイトルやコメントを入れるセル
  • 1ページあたりの写真枚数
  • ページごとの行数
  • 印刷範囲
  • 余白
  • 行高と列幅
  • 結合セルの有無
  • PDF出力時の見え方

特に、写真枠が結合セルになっている場合、見た目と実際のセル範囲が一致していないことがあります。写真枠として指定する範囲は、印刷したときに写真を収めたい範囲と一致させてください。

また、コード内の PAGE_ROW_HEIGHT は、次ページへ進むときの行数です。テンプレートの1ページ分の高さに合わせて変更する必要があります。

VBAでも最終確認が必要な範囲

VBAで写真を貼り付けても、提出用成果品としてそのまま使えるかどうかは別問題です。

次のような確認は、人間が行う必要があります。

  • 写真が正しい順番で貼られているか
  • 写真とファイル名が対応しているか
  • コメント欄と写真がずれていないか
  • 写真が枠内に収まっているか
  • 写真が歪んでいないか
  • 印刷時に写真が切れていないか
  • PDF出力後にレイアウトが崩れていないか
  • 発注者様式や社内様式に合っているか

VBAは、単純な貼付作業を軽くするには便利です。しかし、写真の内容が正しいか、提出資料として妥当かまでは判断してくれません。

印刷とPDF出力は必ず確認する

Excel写真台帳では、画面上の見た目だけで判断しない方が安全です。

写真が枠内にきれいに収まっていても、印刷プレビューで見ると少しずれていたり、PDFにすると文字が切れていたりすることがあります。

特に、次の設定はレイアウトに影響します。

  • 印刷範囲
  • 拡大縮小率
  • 余白
  • 用紙サイズ
  • 改ページ
  • プリンタ設定
  • 行高
  • 列幅
  • 結合セル

提出前には、Excel画面、印刷プレビュー、PDF出力後の3段階で確認するのが安全です。

免責と注意事項

この記事で紹介したVBAコードは、写真台帳作成を補助するためのサンプルです。

利用するExcelのバージョン、シート構成、結合セル、印刷範囲、画像サイズ、余白設定によって、調整が必要になる場合があります。

実務ファイルで実行する前に、必ずバックアップを取ってください。まずはテスト用ブックとテスト用写真で動作確認してください。マクロを使うには、Excel側でマクロを有効化する必要があります。

提出用成果品として使う場合は、写真とコメントの対応、印刷結果、PDF出力結果、発注者・社内様式との整合を必ず人間が確認してください。

コード利用による損害、データ破損、提出物不備等について、維持DXは責任を負いません。

まとめ

写真台帳をExcelで作る場合、写真を1枚ずつ貼り付ける作業はかなり手間です。

VBAを使えば、指定フォルダ内の写真を順番に取得し、写真枠へ貼り付け、ファイル名を記入するところまで自動化できます。

ただし、テンプレートのセル範囲、結合セル、印刷範囲、余白、PDF出力結果は環境によって変わります。コードを貼れば何でも完成するわけではありません。

維持DXでは、Excel帳票、写真台帳、成果品整理、VBA自動化など、現場実務の中で発生しやすい作業負担を軽くする考え方を整理しています。

写真台帳も、まずは写真枠とファイル名の対応を崩さないところから始めると、作業の見通しがかなり良くなります。

■ダウンロード

無料ダウンロード(Excel)

維持DXでは建設コンサルタント実務を軽くするツールを無料で公開しています。
以下のフォームにメールアドレスを入力すると、ダウンロードURLを自動返信メールでお送りします。

    お名前(任意)

    メールアドレス(必須)

    会社名・所属(任意)

    ご関心のある内容(任意)

    ご相談内容(任意)

    ご注意

    ダウンロードURLは、入力いただいたメールアドレス宛に自動返信で送信されます。

    ダウンロードしたExcelでマクロが実行できない場合は、

    右クリック → プロパティ →「許可する」 をチェック後、再度開いてください。

    Windowsのセキュリティ機能により、初回実行時にマクロがブロックされる場合があります。