質問するログイン新規登録

質問編集履歴

1

VBAコード追加

2017/11/14 03:12

投稿

lazyAnt
lazyAnt

スコア12

title CHANGED
File without changes
body CHANGED
@@ -54,4 +54,276 @@
54
54
 
55
55
  初歩的なことだったり、文章に不十分な点があったら大変申し訳ないのですが
56
56
  教えていただけますでしょうか?
57
- よろしくお願いいたします。
57
+ よろしくお願いいたします。
58
+
59
+ #追記
60
+
61
+ ```Excel VBA
62
+ Option Explicit
63
+
64
+
65
+ Private Sub Worksheet_Change(ByVal TargetRange As Range)
66
+
67
+ Application.ScreenUpdating = False
68
+ Application.EnableEvents = False
69
+
70
+ Dim Target As Range
71
+
72
+ ml_set.setSheets
73
+ arrLO = setCnvTable
74
+ If TargetRange.Column <= 2 And TargetRange.row > 3 Then
75
+
76
+ ' セルを範囲指定していた場合のループ処理
77
+ For Each Target In TargetRange
78
+
79
+ Select Case Target.Column
80
+
81
+ Case 1 ' 相手先名が選択されたら
82
+ Call wsUnProtect
83
+ Target.Offset(, 1).Resize(, 4).ClearContents '取引内容~金額(税込)までをクリア
84
+ Call setCellLocked(Target.Offset(, 4), False) '金額(税込)のロック解除
85
+
86
+ Select Case Target.Value
87
+ Case "" '相手先名が空白だった場合リセット
88
+ Target.Offset(, 1).Resize(, 12).ClearContents
89
+ With Target.Offset(, 1).validation
90
+ .Delete
91
+ .Add Type:=xlValidateList, _
92
+ Operator:=xlEqual, _
93
+ Formula1:="相手先名を設定してください"
94
+ .InputMessage = "取引内容の先に相手先名を設定してください"
95
+ .ShowError = False
96
+ .ShowInput = True
97
+ End With
98
+
99
+ Case Else '相手先名が空白じゃなければ取引内容をセット
100
+ Call setTradeValidationRule(Target)
101
+ If Cells(1, 4) <> "本社" Then Target.Offset(, 7) = Cells(1, 4)
102
+
103
+ End Select
104
+ Call wsProtect
105
+
106
+ Case 2 ' 取引内容が選択されたら
107
+
108
+ If Target.Offset(, -1) = "" Then '相手先名が空だったら取引内容をリセット
109
+ Target.ClearContents
110
+
111
+ Else
112
+ Select Case Target.Value
113
+ ' 取引内容を空にしたら、勘定科目~支払口座名(計上営業所を除く)までをリセットする
114
+ Case Is = ""
115
+ Call setCellLocked(Target.Offset(, 3), False)
116
+ Target.Offset(, 1).Resize(, 5).ClearContents
117
+ Target.Offset(, 7).Resize(, 4).ClearContents
118
+
119
+ ' 取引内容をセットしたら、勘定科目~金額・支払口座名をセットする
120
+ Case Else
121
+ Target.Offset(, 1).Resize(, 3).ClearContents
122
+ Call setSubjects(Target)
123
+ If Not IsEmpty(Target.Offset(, 3).Value) Or Target.Offset(, 3).Value > 0 Then
124
+ Call setCellLocked(Target.Offset(, 3), True)
125
+ Else
126
+ Call setCellLocked(Target.Offset(, 3), False)
127
+ End If
128
+
129
+ End Select
130
+ End If
131
+ End Select
132
+ Next
133
+
134
+ End If
135
+
136
+ Application.EnableEvents = True
137
+ Application.ScreenUpdating = True
138
+
139
+ End Sub
140
+
141
+ Public Sub setTargetValidationRule()
142
+ ' 請求先会社名の設定
143
+ '
144
+ ReDim validation(0)
145
+
146
+ Dim i1, i2, iX As Long
147
+ Dim office, company As String
148
+
149
+ office = wsInput.Cells(1, 4)
150
+ company = wsInput.Cells(1, 2)
151
+
152
+ For i1 = 2 To UBound(arrLO)
153
+ If company = arrLO(i1, 8) And office = arrLO(i1, 5) And arrLO(i1, 9) <> "共通" Then
154
+ For i2 = 0 To UBound(validation)
155
+ If validation(i2) = arrLO(i1, 1) Then
156
+ Exit For
157
+ ElseIf i2 = UBound(validation) Then
158
+ ReDim Preserve validation(iX)
159
+ validation(iX) = arrLO(i1, 1)
160
+ iX = iX + 1
161
+ End If
162
+ Next i2
163
+ End If
164
+ Next i1
165
+
166
+ If iX > 0 Then
167
+ Call setValidation(wsInput.Range("A4:A300"), validation, False)
168
+ End If
169
+ End Sub
170
+
171
+ Public Sub setTradeValidationRule(Target As Range)
172
+ ' 取引内容の設定
173
+ Dim validation()
174
+
175
+ Dim i1 As Long
176
+ Dim iX As Long
177
+
178
+ Dim office As String
179
+ office = wsInput.Cells(1, 4)
180
+
181
+ For i1 = 2 To UBound(arrLO)
182
+ If office = arrLO(i1, 5) And Target = arrLO(i1, 1) And Not IsEmpty(arrLO(i1, 2)) Then
183
+ ReDim Preserve validation(iX)
184
+ validation(iX) = arrLO(i1, 2)
185
+ iX = iX + 1
186
+ End If
187
+ Next i1
188
+
189
+ If iX > 0 Then
190
+ Call setValidation(Target.Offset(, 1), validation, False)
191
+ Else
192
+ With Target.Offset(, 1).validation
193
+ .Delete
194
+ .Add xlValidateInputOnly
195
+ .InputMessage = "「" & Target + "」は、取引内容が設定されていません" + vbNewLine + "取引内容は直接入力をしてください"
196
+ .ShowInput = True
197
+ .IMEMode = xlIMEModeHiragana
198
+ End With
199
+ End If
200
+ End Sub
201
+
202
+ Public Sub setValidation(Target As Range, validation, isErr As Boolean)
203
+ ' 入力規則リストの設定function
204
+ ' isErr の値で直接入力の可否を分岐する
205
+
206
+ Dim i1 As Long
207
+ Dim str, _
208
+ inputMsg, _
209
+ errMsg As String
210
+
211
+ Select Case isErr
212
+ Case False
213
+ inputMsg = "プルダウンに選択したい項目がない場合は、直接入力してください"
214
+ Case True
215
+ inputMsg = "プルダウンから選択してください"
216
+ errMsg = "入力できる値はプルダウンの値のみです"
217
+ End Select
218
+
219
+ For i1 = 0 To UBound(validation) '配列validationを「,」区切りの文字列へ変換
220
+ str = str + validation(i1)
221
+ If i1 < UBound(validation) Then str = str + ","
222
+ Next i1
223
+
224
+ If str = "" Then str = "取引内容が設定されていません、直接入力をしてください" 'リストの文字列が空だった場合、代替文字を代入
225
+
226
+ With Target.validation
227
+ .Delete 'validationを設定する場合ははじめに必ずDelete
228
+ .Add Type:=xlValidateList, _
229
+ AlertStyle:=xlValidAlertStop, _
230
+ Operator:=xlEqual, _
231
+ Formula1:=str
232
+ .InputMessage = inputMsg
233
+ .ErrorMessage = errMsg
234
+ .ShowInput = True
235
+ .ShowError = isErr
236
+ .IMEMode = xlIMEModeHiragana
237
+ End With
238
+
239
+ End Sub
240
+
241
+ Public Function setCnvTable()
242
+ ' 外部参照データにある計上科目変換表をThisWorkbookへ取り込むコード
243
+ ' 最新更新日時をトリガーとして、Workbook内に控えてある前回の最新更新日時からアップデートがされていたら再取り込みを行う。
244
+ ' 毎回の外部参照をすると動作遅延が生じるための動作高速化処理
245
+
246
+ Dim wsCnvTable As Worksheet
247
+ Dim path As String
248
+ Dim wb As Workbook
249
+ Dim fName As String
250
+ Dim Ary
251
+ Dim rcLastUpDate As Date
252
+ Dim getLastUpDate As Date
253
+
254
+ Set wsCnvTable = Worksheets("計上科目変換表")
255
+ rcLastUpDate = wsCnvTable.Cells(1, 12) '控えてある最新更新日時をセット
256
+
257
+ getLastUpDate = getDateLastModified(rcLastUpDate) '現在の外部参照データファイルの最新更新日時を取得
258
+
259
+ If getLastUpDate > rcLastUpDate Then '取得した現在の更新日時
260
+ path = ThisWorkbook.path & "\"
261
+ fName = "外部参照データ.xlsx"
262
+
263
+ ' 同ファイルが開いていた場合はデータだけを取得し開いたままに、閉じていた場合はデータ取得後閉じる処理分岐
264
+ If isBookOpen(fName) Then
265
+
266
+ ' 開いていた場合
267
+ Ary = Workbooks(fName).Worksheets("計上科目変換表").Cells(1, 1).CurrentRegion
268
+ Else
269
+
270
+ ' 閉じていた場合の処理
271
+ Application.DisplayAlerts = False
272
+ Workbooks.Open fileName:=path & fName, Password:=629545
273
+ Ary = ActiveWorkbook.Worksheets("計上科目変換表").Cells(1, 1).CurrentRegion
274
+ ActiveWorkbook.Close
275
+ Application.DisplayAlerts = True
276
+ End If
277
+
278
+ With wsCnvTable
279
+ .Cells(1, 1).CurrentRegion.ClearContents
280
+ .Range(.Cells(1, 1), .Cells(UBound(Ary, 1), UBound(Ary, 2))) = Ary
281
+ .Cells(1, 12) = getLastUpDate
282
+ End With
283
+
284
+ setCnvTable = Ary
285
+ Else
286
+ ' 更新がされていなかった場合は、同ブック内のシートより参照
287
+ setCnvTable = wsCnvTable.Cells(1, 1).CurrentRegion
288
+ End If
289
+
290
+ Set wsCnvTable = Nothing '解放
291
+ End Function
292
+
293
+ Private Function isBookOpen(bookName As String) As Boolean
294
+ Dim bk As Workbook
295
+
296
+ isBookOpen = False '初期設定
297
+
298
+ ' 開いているワークブックを回して該当ファイルが開いているか確認
299
+ For Each bk In Workbooks
300
+ If bk.Name = bookName Then
301
+ isBookOpen = True
302
+ Exit For
303
+ End If
304
+ Next
305
+
306
+ End Function
307
+ Private Function getDateLastModified(rcLastUpDate As Date)
308
+ ' 外部参照データファイルの最新更新日時を取得するコード
309
+
310
+ Dim FSO As Object
311
+ Set FSO = CreateObject("Scripting.FIleSystemObject")
312
+
313
+ Dim fName As String
314
+ Dim path As String
315
+ Dim d As Date
316
+ path = ThisWorkbook.path & "\"
317
+ fName = "外部参照データ.xlsx"
318
+ On Error Resume Next
319
+ d = FSO.GetFile(path & fName).DateLastModified
320
+ If Err.Number <> 0 Then
321
+ Err.Clear
322
+ d = rcLastUpDate
323
+ MsgBox fName & "が見つかりませんでした", vbInformation, "Not find file"
324
+ End If
325
+ getDateLastModified = d
326
+ Set FSO = Nothing
327
+ End Function
328
+
329
+ ```