質問編集履歴

1

VBAコード追加

2017/11/14 03:12

投稿

lazyAnt
lazyAnt

スコア12

test CHANGED
File without changes
test CHANGED
@@ -111,3 +111,547 @@
111
111
  教えていただけますでしょうか?
112
112
 
113
113
  よろしくお願いいたします。
114
+
115
+
116
+
117
+ #追記
118
+
119
+
120
+
121
+ ```Excel VBA
122
+
123
+ Option Explicit
124
+
125
+
126
+
127
+
128
+
129
+ Private Sub Worksheet_Change(ByVal TargetRange As Range)
130
+
131
+
132
+
133
+ Application.ScreenUpdating = False
134
+
135
+ Application.EnableEvents = False
136
+
137
+
138
+
139
+ Dim Target As Range
140
+
141
+
142
+
143
+ ml_set.setSheets
144
+
145
+ arrLO = setCnvTable
146
+
147
+ If TargetRange.Column <= 2 And TargetRange.row > 3 Then
148
+
149
+
150
+
151
+ ' セルを範囲指定していた場合のループ処理
152
+
153
+ For Each Target In TargetRange
154
+
155
+
156
+
157
+ Select Case Target.Column
158
+
159
+
160
+
161
+ Case 1 ' 相手先名が選択されたら
162
+
163
+ Call wsUnProtect
164
+
165
+ Target.Offset(, 1).Resize(, 4).ClearContents '取引内容~金額(税込)までをクリア
166
+
167
+ Call setCellLocked(Target.Offset(, 4), False) '金額(税込)のロック解除
168
+
169
+
170
+
171
+ Select Case Target.Value
172
+
173
+ Case "" '相手先名が空白だった場合リセット
174
+
175
+ Target.Offset(, 1).Resize(, 12).ClearContents
176
+
177
+ With Target.Offset(, 1).validation
178
+
179
+ .Delete
180
+
181
+ .Add Type:=xlValidateList, _
182
+
183
+ Operator:=xlEqual, _
184
+
185
+ Formula1:="相手先名を設定してください"
186
+
187
+ .InputMessage = "取引内容の先に相手先名を設定してください"
188
+
189
+ .ShowError = False
190
+
191
+ .ShowInput = True
192
+
193
+ End With
194
+
195
+
196
+
197
+ Case Else '相手先名が空白じゃなければ取引内容をセット
198
+
199
+ Call setTradeValidationRule(Target)
200
+
201
+ If Cells(1, 4) <> "本社" Then Target.Offset(, 7) = Cells(1, 4)
202
+
203
+
204
+
205
+ End Select
206
+
207
+ Call wsProtect
208
+
209
+
210
+
211
+ Case 2 ' 取引内容が選択されたら
212
+
213
+
214
+
215
+ If Target.Offset(, -1) = "" Then '相手先名が空だったら取引内容をリセット
216
+
217
+ Target.ClearContents
218
+
219
+
220
+
221
+ Else
222
+
223
+ Select Case Target.Value
224
+
225
+ ' 取引内容を空にしたら、勘定科目~支払口座名(計上営業所を除く)までをリセットする
226
+
227
+ Case Is = ""
228
+
229
+ Call setCellLocked(Target.Offset(, 3), False)
230
+
231
+ Target.Offset(, 1).Resize(, 5).ClearContents
232
+
233
+ Target.Offset(, 7).Resize(, 4).ClearContents
234
+
235
+
236
+
237
+ ' 取引内容をセットしたら、勘定科目~金額・支払口座名をセットする
238
+
239
+ Case Else
240
+
241
+ Target.Offset(, 1).Resize(, 3).ClearContents
242
+
243
+ Call setSubjects(Target)
244
+
245
+ If Not IsEmpty(Target.Offset(, 3).Value) Or Target.Offset(, 3).Value > 0 Then
246
+
247
+ Call setCellLocked(Target.Offset(, 3), True)
248
+
249
+ Else
250
+
251
+ Call setCellLocked(Target.Offset(, 3), False)
252
+
253
+ End If
254
+
255
+
256
+
257
+ End Select
258
+
259
+ End If
260
+
261
+ End Select
262
+
263
+ Next
264
+
265
+
266
+
267
+ End If
268
+
269
+
270
+
271
+ Application.EnableEvents = True
272
+
273
+ Application.ScreenUpdating = True
274
+
275
+
276
+
277
+ End Sub
278
+
279
+
280
+
281
+ Public Sub setTargetValidationRule()
282
+
283
+ ' 請求先会社名の設定
284
+
285
+ '
286
+
287
+ ReDim validation(0)
288
+
289
+
290
+
291
+ Dim i1, i2, iX As Long
292
+
293
+ Dim office, company As String
294
+
295
+
296
+
297
+ office = wsInput.Cells(1, 4)
298
+
299
+ company = wsInput.Cells(1, 2)
300
+
301
+
302
+
303
+ For i1 = 2 To UBound(arrLO)
304
+
305
+ If company = arrLO(i1, 8) And office = arrLO(i1, 5) And arrLO(i1, 9) <> "共通" Then
306
+
307
+ For i2 = 0 To UBound(validation)
308
+
309
+ If validation(i2) = arrLO(i1, 1) Then
310
+
311
+ Exit For
312
+
313
+ ElseIf i2 = UBound(validation) Then
314
+
315
+ ReDim Preserve validation(iX)
316
+
317
+ validation(iX) = arrLO(i1, 1)
318
+
319
+ iX = iX + 1
320
+
321
+ End If
322
+
323
+ Next i2
324
+
325
+ End If
326
+
327
+ Next i1
328
+
329
+
330
+
331
+ If iX > 0 Then
332
+
333
+ Call setValidation(wsInput.Range("A4:A300"), validation, False)
334
+
335
+ End If
336
+
337
+ End Sub
338
+
339
+
340
+
341
+ Public Sub setTradeValidationRule(Target As Range)
342
+
343
+ ' 取引内容の設定
344
+
345
+ Dim validation()
346
+
347
+
348
+
349
+ Dim i1 As Long
350
+
351
+ Dim iX As Long
352
+
353
+
354
+
355
+ Dim office As String
356
+
357
+ office = wsInput.Cells(1, 4)
358
+
359
+
360
+
361
+ For i1 = 2 To UBound(arrLO)
362
+
363
+ If office = arrLO(i1, 5) And Target = arrLO(i1, 1) And Not IsEmpty(arrLO(i1, 2)) Then
364
+
365
+ ReDim Preserve validation(iX)
366
+
367
+ validation(iX) = arrLO(i1, 2)
368
+
369
+ iX = iX + 1
370
+
371
+ End If
372
+
373
+ Next i1
374
+
375
+
376
+
377
+ If iX > 0 Then
378
+
379
+ Call setValidation(Target.Offset(, 1), validation, False)
380
+
381
+ Else
382
+
383
+ With Target.Offset(, 1).validation
384
+
385
+ .Delete
386
+
387
+ .Add xlValidateInputOnly
388
+
389
+ .InputMessage = "「" & Target + "」は、取引内容が設定されていません" + vbNewLine + "取引内容は直接入力をしてください"
390
+
391
+ .ShowInput = True
392
+
393
+ .IMEMode = xlIMEModeHiragana
394
+
395
+ End With
396
+
397
+ End If
398
+
399
+ End Sub
400
+
401
+
402
+
403
+ Public Sub setValidation(Target As Range, validation, isErr As Boolean)
404
+
405
+ ' 入力規則リストの設定function
406
+
407
+ ' isErr の値で直接入力の可否を分岐する
408
+
409
+
410
+
411
+ Dim i1 As Long
412
+
413
+ Dim str, _
414
+
415
+ inputMsg, _
416
+
417
+ errMsg As String
418
+
419
+
420
+
421
+ Select Case isErr
422
+
423
+ Case False
424
+
425
+ inputMsg = "プルダウンに選択したい項目がない場合は、直接入力してください"
426
+
427
+ Case True
428
+
429
+ inputMsg = "プルダウンから選択してください"
430
+
431
+ errMsg = "入力できる値はプルダウンの値のみです"
432
+
433
+ End Select
434
+
435
+
436
+
437
+ For i1 = 0 To UBound(validation) '配列validationを「,」区切りの文字列へ変換
438
+
439
+ str = str + validation(i1)
440
+
441
+ If i1 < UBound(validation) Then str = str + ","
442
+
443
+ Next i1
444
+
445
+
446
+
447
+ If str = "" Then str = "取引内容が設定されていません、直接入力をしてください" 'リストの文字列が空だった場合、代替文字を代入
448
+
449
+
450
+
451
+ With Target.validation
452
+
453
+ .Delete 'validationを設定する場合ははじめに必ずDelete
454
+
455
+ .Add Type:=xlValidateList, _
456
+
457
+ AlertStyle:=xlValidAlertStop, _
458
+
459
+ Operator:=xlEqual, _
460
+
461
+ Formula1:=str
462
+
463
+ .InputMessage = inputMsg
464
+
465
+ .ErrorMessage = errMsg
466
+
467
+ .ShowInput = True
468
+
469
+ .ShowError = isErr
470
+
471
+ .IMEMode = xlIMEModeHiragana
472
+
473
+ End With
474
+
475
+
476
+
477
+ End Sub
478
+
479
+
480
+
481
+ Public Function setCnvTable()
482
+
483
+ ' 外部参照データにある計上科目変換表をThisWorkbookへ取り込むコード
484
+
485
+ ' 最新更新日時をトリガーとして、Workbook内に控えてある前回の最新更新日時からアップデートがされていたら再取り込みを行う。
486
+
487
+ ' 毎回の外部参照をすると動作遅延が生じるための動作高速化処理
488
+
489
+
490
+
491
+ Dim wsCnvTable As Worksheet
492
+
493
+ Dim path As String
494
+
495
+ Dim wb As Workbook
496
+
497
+ Dim fName As String
498
+
499
+ Dim Ary
500
+
501
+ Dim rcLastUpDate As Date
502
+
503
+ Dim getLastUpDate As Date
504
+
505
+
506
+
507
+ Set wsCnvTable = Worksheets("計上科目変換表")
508
+
509
+ rcLastUpDate = wsCnvTable.Cells(1, 12) '控えてある最新更新日時をセット
510
+
511
+
512
+
513
+ getLastUpDate = getDateLastModified(rcLastUpDate) '現在の外部参照データファイルの最新更新日時を取得
514
+
515
+
516
+
517
+ If getLastUpDate > rcLastUpDate Then '取得した現在の更新日時
518
+
519
+ path = ThisWorkbook.path & "\"
520
+
521
+ fName = "外部参照データ.xlsx"
522
+
523
+
524
+
525
+ ' 同ファイルが開いていた場合はデータだけを取得し開いたままに、閉じていた場合はデータ取得後閉じる処理分岐
526
+
527
+ If isBookOpen(fName) Then
528
+
529
+
530
+
531
+ ' 開いていた場合
532
+
533
+ Ary = Workbooks(fName).Worksheets("計上科目変換表").Cells(1, 1).CurrentRegion
534
+
535
+ Else
536
+
537
+
538
+
539
+ ' 閉じていた場合の処理
540
+
541
+ Application.DisplayAlerts = False
542
+
543
+ Workbooks.Open fileName:=path & fName, Password:=629545
544
+
545
+ Ary = ActiveWorkbook.Worksheets("計上科目変換表").Cells(1, 1).CurrentRegion
546
+
547
+ ActiveWorkbook.Close
548
+
549
+ Application.DisplayAlerts = True
550
+
551
+ End If
552
+
553
+
554
+
555
+ With wsCnvTable
556
+
557
+ .Cells(1, 1).CurrentRegion.ClearContents
558
+
559
+ .Range(.Cells(1, 1), .Cells(UBound(Ary, 1), UBound(Ary, 2))) = Ary
560
+
561
+ .Cells(1, 12) = getLastUpDate
562
+
563
+ End With
564
+
565
+
566
+
567
+ setCnvTable = Ary
568
+
569
+ Else
570
+
571
+ ' 更新がされていなかった場合は、同ブック内のシートより参照
572
+
573
+ setCnvTable = wsCnvTable.Cells(1, 1).CurrentRegion
574
+
575
+ End If
576
+
577
+
578
+
579
+ Set wsCnvTable = Nothing '解放
580
+
581
+ End Function
582
+
583
+
584
+
585
+ Private Function isBookOpen(bookName As String) As Boolean
586
+
587
+ Dim bk As Workbook
588
+
589
+
590
+
591
+ isBookOpen = False '初期設定
592
+
593
+
594
+
595
+ ' 開いているワークブックを回して該当ファイルが開いているか確認
596
+
597
+ For Each bk In Workbooks
598
+
599
+ If bk.Name = bookName Then
600
+
601
+ isBookOpen = True
602
+
603
+ Exit For
604
+
605
+ End If
606
+
607
+ Next
608
+
609
+
610
+
611
+ End Function
612
+
613
+ Private Function getDateLastModified(rcLastUpDate As Date)
614
+
615
+ ' 外部参照データファイルの最新更新日時を取得するコード
616
+
617
+
618
+
619
+ Dim FSO As Object
620
+
621
+ Set FSO = CreateObject("Scripting.FIleSystemObject")
622
+
623
+
624
+
625
+ Dim fName As String
626
+
627
+ Dim path As String
628
+
629
+ Dim d As Date
630
+
631
+ path = ThisWorkbook.path & "\"
632
+
633
+ fName = "外部参照データ.xlsx"
634
+
635
+ On Error Resume Next
636
+
637
+ d = FSO.GetFile(path & fName).DateLastModified
638
+
639
+ If Err.Number <> 0 Then
640
+
641
+ Err.Clear
642
+
643
+ d = rcLastUpDate
644
+
645
+ MsgBox fName & "が見つかりませんでした", vbInformation, "Not find file"
646
+
647
+ End If
648
+
649
+ getDateLastModified = d
650
+
651
+ Set FSO = Nothing
652
+
653
+ End Function
654
+
655
+
656
+
657
+ ```