-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmerge_files.bas
More file actions
283 lines (247 loc) · 9.82 KB
/
merge_files.bas
File metadata and controls
283 lines (247 loc) · 9.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
Attribute VB_Name = "merge_files"
Option Explicit
' -----------------------------------------------------------
' プログラム名: merge_files.bas
' 作成者: あなたの名前
' 作成日: 2025年4月9日
' バージョン: 1.0
' 説明: このプログラムは、〇〇を実行するためのものです。
' 使用方法: 実行方法の説明をここに記載
' -----------------------------------------------------------
' 変更履歴:
' 日付 バージョン 変更内容
' ---------- ---------- -----------------------------------
' 2025/04/09 1.0 初版作成
'
' -----------------------------------------------------------
' -----------------------------------------------------------
' ## 要件定義
' - 転記元のExcelファイルを手動選択する
' - 転記先のExcelファイルは、マクロが実行されているブックとする
' - 対象のシートは「オンサイト」「センドバック」「Nパッケージ」の3つ
' - 転記の基準は、B列の登録番号とする
' - 転記元の4行目以降を参照
' - 転記元のB列移行を参照
' - 転記元のオンサイト:AR列、センドバック:AP列、Nパッケージ:AP列までを転記
' - 転記元のデータを閉じる
' - マクロ実行のログを記録する
' -----------------------------------------------------------
'************************************************************
' タイトル欄
'************************************************************
Public Sub merge_files()
On Error GoTo ErrorHandler
' マクロを実行するかどうか確認
Dim response As VbMsgBoxResult
response = MsgBox("マクロを実行しますか?", vbYesNo + vbQuestion, "確認")
If response = vbYes Then
'************************************************************
' 事前準備
'************************************************************
' 処理開始時間を記録
Dim T As Double
T = Timer
' 自動計算&画面更新停止
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
'************************************************************
' メインの処理
'************************************************************
' 転記元のExcelファイル
Dim SrcWb As Workbook
Dim SrcWs_Onsite As Worksheet
Dim SrcWs_Sendback As Worksheet
Dim SrcWs_NPackage As Worksheet
' 任意のExcelファイルを開く(手動選択)
Set SrcWb = Application.Workbooks.Open(Application.GetOpenFilename("Excel Files (*.xls; *.xlsx), *.xls; *.xlsx", , "対象ファイルを選択してください"))
If SrcWb Is Nothing Then
MsgBox "ファイルが選択されていません。処理を中止します。", vbExclamation
Exit Sub
End If
' 対象ファイルにオンサイト、センドバック、Nパッケージが存在するか確認
Set SrcWs_Onsite = SrcWb.Worksheets("オンサイト")
Set SrcWs_Sendback = SrcWb.Worksheets("センドバック")
Set SrcWs_NPackage = SrcWb.Worksheets("Nパッケージ")
' 転記元のフィルター解除
SrcWs_Onsite.AutoFilterMode = False
SrcWs_Sendback.AutoFilterMode = False
SrcWs_NPackage.AutoFilterMode = False
' 転記先のExcelファイル(マクロが実行されているブック)
Dim dstWb As Workbook
Dim dstWs_Onsite As Worksheet
Dim dstWs_Sendback As Worksheet
Dim dstWs_NPackage As Worksheet
Set dstWb = ThisWorkbook ' マクロが実行されているブック
Set dstWs_Onsite = dstWb.Worksheets("オンサイト") ' 転記先のオンサイトシート
Set dstWs_Sendback = dstWb.Worksheets("センドバック") ' 転記先のセンドバックシート
Set dstWs_NPackage = dstWb.Worksheets("Nパッケージ") ' 転記先のNパッケージシート
' 対象ファイルからオンサイトのデータを転記
' オンサイトシートが存在しない場合は、エラーメッセージを表示
If SrcWs_Onsite Is Nothing Then
MsgBox "対象ファイルにオンサイトシートが存在しません。", vbExclamation
SrcWb.Close False
Exit Sub
Else
' オンサイトシートが存在する場合は、転記を実行
Call CheckDataExists(SrcWs_Onsite, dstWs_Onsite)
End If
' 対象ファイルからセンドバックのデータを転記
' センドバックシートが存在しない場合は、エラーメッセージを表示
If SrcWs_Sendback Is Nothing Then
MsgBox "対象ファイルにセンドバックシートが存在しません。", vbExclamation
SrcWb.Close False
Exit Sub
Else
' センドバックシートが存在する場合は、転記を実行
Call CheckDataExists(SrcWs_Sendback, dstWs_Sendback)
End If
' 対象ファイルからNパッケージのデータを転記
' Nパッケージシートが存在しない場合は、エラーメッセージを表示
If SrcWs_NPackage Is Nothing Then
MsgBox "対象ファイルにNパッケージシートが存在しません。", vbExclamation
SrcWb.Close False
Exit Sub
Else
' Nパッケージシートが存在する場合は、転記を実行
Call CheckDataExists(SrcWs_NPackage, dstWs_NPackage)
End If
' 転記元のデータを閉じる(セーブしない)
Workbooks(SrcWb.Name).Close False
'************************************************************
' 残作業
'************************************************************
' 自動計算&画面更新再開
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
' ログ: マクロ実行の成功を記録
Call LogMacroExecution("merge_files", "成功")
' 処理完了メッセージ
MsgBox "マクロを実行しました。" & vbCrLf & "処理時間: " & Format(Timer - T, "0.00") & " 秒"
Else
' ログ: マクロ実行のキャンセルを記録
Call LogMacroExecution("merge_files", "キャンセル")
' キャンセルメッセージ
MsgBox "マクロの実行をキャンセルしました。"
End If
Exit Sub
'************************************************************
' エラーハンドリング
'************************************************************
ErrorHandler:
' 転記元のデータを閉じる(セーブしない)
Workbooks(SrcWb.Name).Close False
' ログ:マクロ失敗時、エラーメッセージをログに記録
Call LogMacroExecution("merge_files", "失敗 - " & Err.Description)
' エラーメッセージを表示
MsgBox "エラーが発生しました。管理者に連絡ください。" & vbCrLf & "エラー内容: " & Err.Description, vbCritical
' 自動計算&画面更新再開
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
' ************************************************************
' 転記先に転記元のデータがないか検証するサブルーチン
Sub CheckDataExists(srcWs As Worksheet, dstWs As Worksheet)
' 変数宣言を集約
Dim i As Long
Dim key As Variant
Dim srcRegNo As String
Dim dstRegNo As String
Dim lastRow As Long
Dim dstLastRow As Long
Dim srcDict As Object
Dim DstDict As Object
Set srcDict = CreateObject("Scripting.Dictionary")
Set DstDict = CreateObject("Scripting.Dictionary")
' フィルターを解除
srcWs.AutoFilterMode = False
dstWs.AutoFilterMode = False
' 転記元の登録番号を集計
lastRow = srcWs.Cells(srcWs.Rows.Count, 2).End(xlUp).Row
For i = 4 To lastRow
srcRegNo = srcWs.Cells(i, 2).Value
If srcRegNo <> "" Then
If Not srcDict.Exists(srcRegNo) Then
srcDict.Add srcRegNo, 1
Else
srcDict(srcRegNo) = srcDict(srcRegNo) + 1
End If
End If
Next i
' 転記先の登録番号を集計
dstLastRow = dstWs.Cells(dstWs.Rows.Count, 2).End(xlUp).Row
For i = 4 To dstLastRow
dstRegNo = dstWs.Cells(i, 2).Value
If dstRegNo <> "" Then
If Not DstDict.Exists(dstRegNo) Then
DstDict.Add dstRegNo, 1
Else
DstDict(dstRegNo) = DstDict(dstRegNo) + 1
End If
End If
Next i
' 登録番号ごとに個数比較
Dim needUpdate As Boolean: needUpdate = False
Dim warnMsg As String: warnMsg = ""
For Each key In srcDict.Keys
If Not DstDict.Exists(key) Then
needUpdate = True
warnMsg = "転記先に登録番号 [" & key & "] がありません。"
Exit For
ElseIf srcDict(key) <> DstDict(key) Then
needUpdate = True
warnMsg = "登録番号 [" & key & "] の個数が一致しません。" & vbCrLf & _
"転記元: " & srcDict(key) & "件, 転記先: " & DstDict(key) & "件"
Exit For
End If
Next key
For Each key In DstDict.Keys
If Not srcDict.Exists(key) Then
needUpdate = True
warnMsg = "転記先に余分な登録番号 [" & key & "] があります。"
Exit For
End If
Next key
If needUpdate Then
MsgBox "転記元と転記先でデータの過不足があります。" & vbCrLf & _
warnMsg & vbCrLf & _
"手動で転記先のデータを修正してください。", vbExclamation
Exit Sub
End If
' 個数がすべて一致:何もしない
Exit Sub
' 転記元の該当行のみ転記
Call CopyData(srcWs, dstWs, 4, lastRow - 3)
End Sub
' ************************************************************
' データを転記するサブルーチン
Private Sub CopyData(srcWs As Worksheet, _
dstWs As Worksheet, _
targetRow As Long, _
copyRowCount As Long _
)
Dim lastRow As Long
Dim i As Long
Dim col As Long
' 転記先のシートの最終行を取得(B列基準)
lastRow = dstWs.Cells(dstWs.Rows.Count, 2).End(xlUp).Row + 1
' 要件定義に基づき、B列以降を転記
Dim colStart As Long, colEnd As Long
' シート名で転記範囲を切り替え
Select Case dstWs.Name
Case "オンサイト"
colStart = 2 ' B列
colEnd = 44 ' AR列
Case "センドバック"
colStart = 2 ' B列
colEnd = 42 ' AP列
Case "Nパッケージ"
colStart = 2 ' B列
colEnd = 42 ' AP列
End Select
For i = targetRow To targetRow + copyRowCount - 1
For col = colStart To colEnd
dstWs.Cells(lastRow, col).Value = srcWs.Cells(i, col).Value
Next col
lastRow = lastRow + 1
Next i
End Sub