ねらい:毎朝の「取り込み→整形→集計→レポート→バックアップ」を“同じ手順”で一括自動化する
日次処理は、手順がブレるとすぐに品質が落ちます。VBAなら「入口でデータを正す→集計・出力→配布物作成→バックアップ→ログ記録→失敗時は止めずに通知」の型にすれば、誰が回しても同じ結果が出ます。初心者でも貼って動くテンプレを、例題付きでかみ砕いて解説します。
共通基盤:設定・ログ・安全トライキャッチ
設定値とログユーティリティ
' ModDaily_Base.bas
Option Explicit
Public Type DailyConfig
SrcFolder As String ' 取り込み元フォルダ
OutFolder As String ' 出力フォルダ(レポート・CSV)
BackupFolder As String
DateKey As String ' 日次キー(yyyy-mm-dd)
RoundMode As String ' 金額の丸め "round"/"ceil"/"floor"
End Type
Public Function LoadConfig() As DailyConfig
Dim c As DailyConfig
c.SrcFolder = ThisWorkbook.Path & "\inbox"
c.OutFolder = ThisWorkbook.Path & "\outbox"
c.BackupFolder = ThisWorkbook.Path & "\backup"
c.DateKey = Format(Date, "yyyy-mm-dd")
c.RoundMode = "round"
LoadConfig = c
End Function
Public Sub AppendLog(ByVal logPath As String, ByVal message As String)
Dim f As Integer: f = FreeFile
Open logPath For Append As #f
Print #f, Format(Now, "yyyy-mm-dd hh:nn:ss"); " | "; message
Close #f
End Sub
Public Function EnsureFolder(ByVal folderPath As String) As Boolean
On Error Resume Next
If Dir(folderPath, vbDirectory) = "" Then MkDir folderPath
EnsureFolder = (Dir(folderPath, vbDirectory) <> "")
On Error GoTo 0
End Function
Public Sub SafeMsg(ByVal text As String)
On Error Resume Next
MsgBox text, vbInformation
On Error GoTo 0
End Sub
VB重要ポイントの深掘り
- 設定は1箇所(LoadConfig)に集約。パスや日付キー、丸め方法を毎日同じ値で使い回せます。
- ログは「日時 | メッセージ」で追記。監査・失敗時のトレースが容易になります。
- フォルダ生成は必ず“存在チェック→作成”に統一。突然のパス変更でも壊れません。
入口処理:CSV取り込み→型変換→正規化
取り込みとクリーニング(貼って動く)
' ModDaily_ImportClean.bas
Option Explicit
Public Function ImportCsvToArray(ByVal csvPath As String) As Variant
Dim wb As Workbook, ws As Worksheet
Set wb = Application.Workbooks.Open(csvPath)
Set ws = wb.Worksheets(1)
ImportCsvToArray = ws.Range("A1").CurrentRegion.Value
wb.Close SaveChanges:=False
End Function
Public Function ToNumberOrZero(ByVal v As Variant) As Double
If IsNumeric(v) Then ToNumberOrZero = CDbl(v) Else ToNumberOrZero = 0#
End Function
Public Function ToDateOrEmpty(ByVal v As Variant) As Variant
If IsDate(v) Then ToDateOrEmpty = CDate(v) Else ToDateOrEmpty = ""
End Function
Public Function NormKey(ByVal v As Variant) As String
NormKey = LCase$(Trim$(CStr(v)))
End Function
Public Function CleanDaily(ByVal a As Variant) As Variant
' 想定明細: A=注文日, B=顧客, C=商品, D=数量, E=金額
Dim out() As Variant: ReDim out(1 To UBound(a, 1), 1 To UBound(a, 2) + 1)
Dim lastCol As Long: lastCol = UBound(a, 2)
Dim r As Long, c As Long
' ヘッダ+派生列(YearMonth)
For c = 1 To lastCol: out(1, c) = a(1, c): Next
out(1, lastCol + 1) = "YearMonth"
For r = 2 To UBound(a, 1)
For c = 1 To lastCol: out(r, c) = a(r, c): Next
out(r, 2) = NormKey(a(r, 2)) ' 顧客キー正規化
out(r, 3) = NormKey(a(r, 3)) ' 商品キー正規化
out(r, 4) = ToNumberOrZero(a(r, 4)) ' 数量
out(r, 5) = ToNumberOrZero(a(r, 5)) ' 金額
Dim dt As Variant: dt = ToDateOrEmpty(a(r, 1))
out(r, lastCol + 1) = IIf(IsDate(dt), Format(CDate(dt), "yyyy-mm"), "")
Next
CleanDaily = out
End Function
VB重要ポイントの深掘り
- 入口で“数値・日付・キー正規化”を徹底。これだけで集計の多くの事故(文字数値・テキスト日付・グループ割れ)を防げます。
- 年月派生(yyyy-mm)を明細に加えると、月次ピボットやグラフが安定します。
- CSVは開いてCurrentRegionで一括取得→閉じる。貼り付けではなく配列で扱うのが高速・堅牢です。
集計とレポート:顧客別/商品別/日次・月次
グループ合計テンプレ
' ModDaily_Aggregate.bas
Option Explicit
Public Function GroupSum(ByVal a As Variant, ByVal keyCol As Long, ByVal valueCol As Long, ByVal headerKey As String, ByVal headerSum As String) As Variant
Dim d As Object: Set d = CreateObject("Scripting.Dictionary"): d.CompareMode = 1
Dim r As Long
For r = 2 To UBound(a, 1)
Dim k As String: k = CStr(a(r, keyCol))
Dim v As Double: v = ToNumberOrZero(a(r, valueCol))
d(k) = IIf(d.Exists(k), d(k) + v, v)
Next
Dim out() As Variant: ReDim out(1 To d.Count + 1, 1 To 2)
out(1, 1) = headerKey: out(1, 2) = headerSum
Dim i As Long: i = 2, key As Variant
For Each key In d.Keys
out(i, 1) = key
out(i, 2) = d(key)
i = i + 1
Next
GroupSum = out
End Function
Public Sub WriteBlock(ByVal ws As Worksheet, ByVal a As Variant, ByVal startAddr As String)
ws.Range(startAddr).Resize(UBound(a, 1), UBound(a, 2)).Value = a
With ws.Range(startAddr).CurrentRegion
.Columns.AutoFit
.Borders.LineStyle = xlContinuous
.Columns(.Columns.Count).NumberFormatLocal = "#,##0"
End With
End Sub
VB見える化レポート作成(貼って動く)
' ModDaily_Report.bas
Option Explicit
Public Sub BuildDailyReport(ByVal cleaned As Variant, ByVal outSheet As String)
Dim ws As Worksheet
On Error Resume Next: Set ws = Worksheets(outSheet): On Error GoTo 0
If ws Is Nothing Then Set ws = Worksheets.Add: ws.Name = outSheet Else ws.Cells.Clear
' 顧客別合計(金額)
Dim byCust As Variant: byCust = GroupSum(cleaned, 2, 5, "Customer", "AmountSum")
WriteBlock ws, byCust, "A1"
' 商品別合計(金額)
Dim byProd As Variant: byProd = GroupSum(cleaned, 3, 5, "Product", "AmountSum")
WriteBlock ws, byProd, "D1"
' 月次合計(金額)
Dim byMon As Variant: byMon = GroupSum(cleaned, UBound(cleaned, 2), 5, "Month", "AmountSum")
WriteBlock ws, byMon, "G1"
' 簡易グラフ(任意)
Dim rng As Range: Set rng = ws.Range("G1").CurrentRegion
Dim ch As ChartObject: Set ch = ws.ChartObjects.Add(Left:=rng.Left, Top:=rng.Top + rng.Height + 10, Width:=400, Height:=240)
ch.Chart.ChartType = xlColumnClustered
ch.Chart.SetSourceData rng
ch.Chart.HasTitle = True
ch.Chart.ChartTitle.Text = "Monthly Amount"
End Sub
VB重要ポイントの深掘り
- GroupSumは“キー列・値列・ヘッダ名”だけで汎用に使えます。顧客・商品・月次の切替も一瞬。
- 出力は「セル一括貼り→書式一括適用」。千区切りと罫線を標準化し、レビューが速くなります。
- グラフは最小構成でOK。見出しだけ付けて、位置も自動配置にすると崩れません。
配布とバックアップ:CSV/PDF出力・世代管理
CSV出力・PDF化・バックアップ呼び出し
' ModDaily_Distribute.bas
Option Explicit
Public Sub ExportReportCsv(ByVal ws As Worksheet, ByVal startAddr As String, ByVal csvPath As String)
Dim tempWB As Workbook: Set tempWB = Application.Workbooks.Add
ws.Range(startAddr).CurrentRegion.Copy
tempWB.Worksheets(1).Range("A1").PasteSpecial xlPasteValues
Application.DisplayAlerts = False
tempWB.SaveAs Filename:=csvPath, FileFormat:=xlCSVUTF8
Application.DisplayAlerts = True
tempWB.Close False
End Sub
Public Sub ExportSheetPdf(ByVal ws As Worksheet, ByVal pdfPath As String)
With ws.PageSetup
.Orientation = xlPortrait
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
.LeftMargin = Application.CentimetersToPoints(1)
.RightMargin = Application.CentimetersToPoints(1)
.TopMargin = Application.CentimetersToPoints(1)
.BottomMargin = Application.CentimetersToPoints(1)
End With
ws.ExportAsFixedFormat Type:=xlTypePDF, Filename:=pdfPath, Quality:=xlQualityStandard, OpenAfterPublish:=False
End Sub
VB重要ポイントの深掘り
- CSVは“値貼り付け+UTF-8”で文字化けを防止。関数のまま保存しないのが鉄則です。
- PDFは印刷設定をコードで固定。毎日同じ見た目で出力され、配布を標準化できます。
- バックアップは「日次フォルダに時刻スタンプ名」でローテーション。版数管理は週次・月次で切ると運用しやすいです。
日次パイプライン:取込→整形→集計→配布→バックアップ→ログ
例題の一括実行(貼って動く)
' ModDaily_Pipeline.bas
Option Explicit
Public Sub Run_DailyProcess()
Dim cfg As DailyConfig: cfg = LoadConfig()
If Not EnsureFolder(cfg.SrcFolder) Then SafeMsg "取り込みフォルダなし: " & cfg.SrcFolder
If Not EnsureFolder(cfg.OutFolder) Then SafeMsg "出力フォルダ作成失敗: " & cfg.OutFolder
If Not EnsureFolder(cfg.BackupFolder) Then SafeMsg "バックアップフォルダ作成失敗: " & cfg.BackupFolder
Dim logPath As String: logPath = cfg.BackupFolder & "\daily_" & Replace(cfg.DateKey, "-", "") & ".log"
On Error GoTo FAIL
' 1) 入口:CSV取り込み
Dim csvPath As String: csvPath = cfg.SrcFolder & "\detail_" & Replace(cfg.DateKey, "-", "") & ".csv"
AppendLog logPath, "IMPORT: " & csvPath
Dim raw As Variant: raw = ImportCsvToArray(csvPath)
' 2) 整形
AppendLog logPath, "CLEAN"
Dim cleaned As Variant: cleaned = CleanDaily(raw)
' 3) レポート生成
AppendLog logPath, "REPORT"
Call BuildDailyReport(cleaned, "Daily_Report")
' 4) 配布物出力(CSV/PDF)
AppendLog logPath, "EXPORT CSV/PDF"
ExportReportCsv Worksheets("Daily_Report"), "A1", cfg.OutFolder & "\report_" & Replace(cfg.DateKey, "-", "") & ".csv"
ExportSheetPdf Worksheets("Daily_Report"), cfg.OutFolder & "\report_" & Replace(cfg.DateKey, "-", "") & ".pdf"
' 5) バックアップ(ブック丸ごと)
AppendLog logPath, "BACKUP"
Call BackupWorkbook(ThisWorkbook, cfg.BackupFolder, 7)
AppendLog logPath, "OK"
SafeMsg "日次処理が完了しました。"
Exit Sub
FAIL:
AppendLog logPath, "FAILED: " & Err.Number & " - " & Err.Description
SafeMsg "日次処理でエラーが発生しました(ログ参照)"
End Sub
VB重要ポイントの深掘り
- 失敗しても“ログに残して通知”して終えるのが正解。無理に続行しない。
- ファイル名は“日付キー”で固定すると、差し替え時も迷いません。
- 出力先(CSV/PDF/バックアップ)はフォルダで分離。運用導線がスッキリします。
落とし穴と対策(深掘り)
テキスト日付・文字数値で集計が壊れる
入口で ToDateOrEmpty/ToNumberOrZero を通す。失敗は安全値(空・0)に落とす方針を固定。
取り込みファイルの欠損・命名ズレ
“detail_yyyymmdd.csv”の命名規則を固定。見つからない場合は即ログ化+通知で止める。
出力書式のふらつき
NumberFormatLocal “#,##0”+罫線+AutoFit を標準化。毎日同じ見た目で比較・監査を可能に。
セル逐次書きで遅い
配列→一括貼り付けが鉄則。10万行でも短時間で完了し、画面が固まりません。
フォルダ権限・共有切断
EnsureFolder で事前検証。共有先へ直接書かず、まずローカルに保存→成功後に共有へ同期の二段構えを検討。
まとめ:手順を“型”にし、設定・ログ・失敗時の導線まで含めて日次を強くする
- 設定は一箇所、入口で整える、集計は汎用関数、出力はCSV/PDFで固定、バックアップとログを必ず残す。
- 失敗時は止めずにログ化・通知。翌日の修正が速くなります。
- あなたの明細列(日付・顧客・商品・数量・金額の位置)、命名規則、必要なレポート(顧客別・商品別・月次・グラフ)を教えてください。現場仕様に合わせて“貼って動く”日次処理テンプレに最短で仕立てます。
