This commit is contained in:
updsv7
2026-04-16 18:37:48 +09:00
parent b0c6ec6baa
commit c661373369
7 changed files with 1018 additions and 58 deletions

View File

@@ -1,58 +0,0 @@
' ============================================================
' Modele Name: GlobalCache
' Modele Desc: Global Cache Module, Shared caches across all worksheets
' ============================================================
' M1 cache - used by M2_Kukan_detail
Public m1Cache As Object
' Z1 cache - used by M1_Kukan
Public z1Cache As Object
' Refresh M1 cache - called when M1 data changes
Public Sub RefreshM1Cache()
' Clear existing cache first to avoid memory leak
Set m1Cache = Nothing
On Error GoTo RefreshError
Set m1Cache = LoadLookup("M1", keyCol:=3, valueCols:=Array(3, 4, 5, 6, 7, 9, 12), startRow:=7)
On Error GoTo 0
If m1Cache Is Nothing Or m1Cache.Count = 0 Then
Err.Raise 1001, "RefreshM1Cache", "M1 reference data is empty"
End If
Exit Sub
RefreshError:
Err.Raise 1002, "RefreshM1Cache", "Failed to load M1 lookup cache: " & Err.Description
End Sub
' Clear M1 cache - called when M1 data is cleared
Public Sub ClearM1Cache()
Set m1Cache = Nothing
End Sub
' Refresh Z1 cache - called when Z1 data changes
Public Sub RefreshZ1Cache()
' Clear existing cache first to avoid memory leak
Set z1Cache = Nothing
On Error GoTo RefreshError
Set z1Cache = LoadLookup("Z1", keyCol:=3, valueCols:=Array(4), startRow:=7)
On Error GoTo 0
If z1Cache Is Nothing Or z1Cache.Count = 0 Then
Err.Raise 1001, "RefreshZ1Cache", "Z1 reference data is empty"
End If
Exit Sub
RefreshError:
Err.Raise 1002, "RefreshZ1Cache", "Failed to load Z1 lookup cache: " & Err.Description
End Sub
' Clear Z1 cache - called when Z1 data is cleared
Public Sub ClearZ1Cache()
Set z1Cache = Nothing
End Sub

274
src/module/Global_Cache.bas Normal file
View File

@@ -0,0 +1,274 @@
' ============================================================
' Modele Name: Global_Cache
' Modele Desc: Global Cache Module, Shared caches across all worksheets
' ============================================================
' M1 cache - used by M2_Kukan_detail, Tukin_C1
Public m1Cache As Object
' M1_KukanD cache - nested dict {D: {F: [G]}}
Public m1KukanDCache As Object
' Z1 cache - used by M1_Kukan
Public z1Cache As Object
' Z2 cache
Public z2Cache As Object
' Z3 cache
Public z3Cache As Object
' O1 cache - used by Tukin_C1
Public o1Cache As Object
' O2 cache
Public o2Cache As Object
' M2 cache - nested dictionary for Tukin_C1
Public m2Cache As Object
' ============================================================
' M1 Cache
' ============================================================
Public Sub RefreshM1Cache()
Set m1Cache = Nothing
On Error GoTo RefreshError
Set m1Cache = LoadLookup("M1", keyCol:=3, valueCols:=Array(3, 4, 5, 6, 7, 9, 12), startRow:=7)
On Error GoTo 0
If m1Cache Is Nothing Or m1Cache.Count = 0 Then
Err.Raise 1001, "RefreshM1Cache", "M1 reference data is empty"
End If
Exit Sub
RefreshError:
Err.Raise 1002, "RefreshM1Cache", "Failed to load M1 lookup cache: " & Err.Description
End Sub
Public Sub ClearM1Cache()
Set m1Cache = Nothing
End Sub
' Refresh M1_KukanD cache - nested dict {D: {F: [G]}}
' Structure: { 交通機関区分[D]: { 利用区間発名[F]: [利用区間着名G] } }
Public Sub RefreshM1KukanDCache()
Set m1KukanDCache = Nothing
Set m1KukanDCache = CreateObject("Scripting.Dictionary")
Dim wsM1 As Worksheet
On Error Resume Next
Set wsM1 = ThisWorkbook.Worksheets("M1")
If wsM1 Is Nothing Then Exit Sub
On Error GoTo 0
Dim lastRow As Long: lastRow = wsM1.Cells(wsM1.Rows.Count, 3).End(xlUp).Row
If lastRow < 7 Then Exit Sub
Dim r As Long
For r = 7 To lastRow
Dim dValue As String: dValue = Trim(wsM1.Cells(r, 4).Value) ' D column
Dim fValue As String: fValue = Trim(wsM1.Cells(r, 6).Value) ' F column
Dim gValue As String: gValue = Trim(wsM1.Cells(r, 7).Value) ' G column
If dValue = "" Or fValue = "" Then GoTo NextRow2
' Outer level: D column (交通機関区分)
If Not m1KukanDCache.Exists(dValue) Then
Dim innerDict As Object: Set innerDict = CreateObject("Scripting.Dictionary")
m1KukanDCache.Add dValue, innerDict
End If
' Inner level: F column (利用区間発名) -> array of G values
Set innerDict = m1KukanDCache(dValue)
If Not innerDict.Exists(fValue) Then
Dim arr As Object: Set arr = CreateObject("Scripting.Dictionary")
innerDict.Add fValue, arr
End If
Set arr = innerDict(fValue)
If gValue <> "" And Not arr.Exists(gValue) Then
arr.Add gValue, True
End If
NextRow2:
Next r
End Sub
Public Sub ClearM1KukanDCache()
Set m1KukanDCache = Nothing
End Sub
' ============================================================
' M2 Cache - Nested Dictionary
' Structure: { 区間コード[C]: { 券種[I]: { コード[J]: K } } }
' ============================================================
Public Sub RefreshM2Cache()
Set m2Cache = Nothing
Set m2Cache = CreateObject("Scripting.Dictionary")
Dim wsM2 As Worksheet
On Error Resume Next
Set wsM2 = ThisWorkbook.Worksheets("M2")
If wsM2 Is Nothing Then Exit Sub
On Error GoTo 0
Dim lastRow As Long: lastRow = wsM2.Cells(wsM2.Rows.Count, 3).End(xlUp).Row
If lastRow < 7 Then Exit Sub
Dim r As Long
For r = 7 To lastRow
Dim kukanCode As String: kukanCode = Trim(wsM2.Cells(r, 3).Value) ' C column
Dim kanshu As String: kanshu = Trim(wsM2.Cells(r, 9).Value) ' I column
Dim code As String: code = Trim(wsM2.Cells(r, 10).Value) ' J column
Dim kValue As String: kValue = Trim(wsM2.Cells(r, 11).Value) ' K column
If kukanCode = "" Or kanshu = "" Or code = "" Then GoTo NextRow
' Outer level: kukanCode
If Not m2Cache.Exists(kukanCode) Then
Dim innerDict As Object: Set innerDict = CreateObject("Scripting.Dictionary")
m2Cache.Add kukanCode, innerDict
End If
' Middle level: kanshu
Set innerDict = m2Cache(kukanCode)
If Not innerDict.Exists(kanshu) Then
Dim innermostDict As Object: Set innermostDict = CreateObject("Scripting.Dictionary")
innerDict.Add kanshu, innermostDict
End If
' Inner level: code -> kValue
Set innermostDict = innerDict(kanshu)
If Not innermostDict.Exists(code) Then
innermostDict.Add code, kValue
End If
NextRow:
Next r
End Sub
Public Sub ClearM2Cache()
Set m2Cache = Nothing
End Sub
' ============================================================
' Z1 Cache
' ============================================================
Public Sub RefreshZ1Cache()
Set z1Cache = Nothing
On Error GoTo RefreshError
Set z1Cache = LoadLookup("Z1", keyCol:=3, valueCols:=Array(4), startRow:=7)
On Error GoTo 0
If z1Cache Is Nothing Or z1Cache.Count = 0 Then
Err.Raise 1001, "RefreshZ1Cache", "Z1 reference data is empty"
End If
Exit Sub
RefreshError:
Err.Raise 1002, "RefreshZ1Cache", "Failed to load Z1 lookup cache: " & Err.Description
End Sub
Public Sub ClearZ1Cache()
Set z1Cache = Nothing
End Sub
' ============================================================
' Z2 Cache
' ============================================================
Public Sub RefreshZ2Cache()
Set z2Cache = Nothing
On Error GoTo RefreshError
Set z2Cache = LoadLookup("Z2", keyCol:=3, valueCols:=Array(4), startRow:=7)
On Error GoTo 0
If z2Cache Is Nothing Or z2Cache.Count = 0 Then
Err.Raise 1001, "RefreshZ2Cache", "Z2 reference data is empty"
End If
Exit Sub
RefreshError:
Err.Raise 1002, "RefreshZ2Cache", "Failed to load Z2 lookup cache: " & Err.Description
End Sub
Public Sub ClearZ2Cache()
Set z2Cache = Nothing
End Sub
' ============================================================
' Z3 Cache
' ============================================================
Public Sub RefreshZ3Cache()
Set z3Cache = Nothing
On Error GoTo RefreshError
Set z3Cache = LoadLookup("Z3", keyCol:=3, valueCols:=Array(4), startRow:=7)
On Error GoTo 0
If z3Cache Is Nothing Or z3Cache.Count = 0 Then
Err.Raise 1001, "RefreshZ3Cache", "Z3 reference data is empty"
End If
Exit Sub
RefreshError:
Err.Raise 1002, "RefreshZ3Cache", "Failed to load Z3 lookup cache: " & Err.Description
End Sub
Public Sub ClearZ3Cache()
Set z3Cache = Nothing
End Sub
' ============================================================
' O1 Cache
' ============================================================
Public Sub RefreshO1Cache()
Set o1Cache = Nothing
On Error GoTo RefreshError
Set o1Cache = LoadLookup("O1", keyCol:=3, valueCols:=Array(5, 6), startRow:=7)
On Error GoTo 0
If o1Cache Is Nothing Or o1Cache.Count = 0 Then
Err.Raise 1001, "RefreshO1Cache", "O1 reference data is empty"
End If
Exit Sub
RefreshError:
Err.Raise 1002, "RefreshO1Cache", "Failed to load O1 lookup cache: " & Err.Description
End Sub
Public Sub ClearO1Cache()
Set o1Cache = Nothing
End Sub
' ============================================================
' O2 Cache
' ============================================================
Public Sub RefreshO2Cache()
Set o2Cache = Nothing
On Error GoTo RefreshError
Set o2Cache = LoadLookup("O2", keyCol:=3, valueCols:=Array(4), startRow:=7)
On Error GoTo 0
If o2Cache Is Nothing Or o2Cache.Count = 0 Then
Err.Raise 1001, "RefreshO2Cache", "O2 reference data is empty"
End If
Exit Sub
RefreshError:
Err.Raise 1002, "RefreshO2Cache", "Failed to load O2 lookup cache: " & Err.Description
End Sub
Public Sub ClearO2Cache()
Set o2Cache = Nothing
End Sub

194
src/module/Test_Cache.bas Normal file
View File

@@ -0,0 +1,194 @@
' ============================================================
' Test Cache Module
' Debug: Print cache contents to Test_Cache sheet
' ============================================================
Sub Test_PrintAllCaches()
' Refresh all caches first
Call RefreshM1Cache
Call RefreshM1KukanDCache
Call RefreshM2Cache
Call RefreshZ1Cache
Call RefreshO1Cache
' Get or create Test_Cache sheet
Dim wb As Workbook
Set wb = ThisWorkbook
Dim ws As Worksheet
On Error Resume Next
Set ws = wb.Worksheets("Test_Cache")
On Error GoTo 0
If ws Is Nothing Then
Set ws = wb.Worksheets.Add
ws.Name = "Test_Cache"
End If
ws.Cells.Clear
Dim row As Long
row = 1
' Print M1 Cache
ws.Cells(row, 1).Value = "=== M1 Cache ==="
row = row + 1
Call PrintM1CacheToSheet(ws, row)
' Print M1_KukanD Cache
row = row + 1
ws.Cells(row, 1).Value = "=== M1_KukanD Cache ==="
row = row + 1
Call PrintM1KukanDCacheToSheet(ws, row)
' Print M2 Cache
row = row + 1
ws.Cells(row, 1).Value = "=== M2 Cache ==="
row = row + 1
Call PrintM2CacheToSheet(ws, row)
' Print Z1 Cache
row = row + 1
ws.Cells(row, 1).Value = "=== Z1 Cache ==="
row = row + 1
Call PrintZ1CacheToSheet(ws, row)
' Print O1 Cache
row = row + 1
ws.Cells(row, 1).Value = "=== O1 Cache ==="
row = row + 1
Call PrintO1CacheToSheet(ws, row)
ws.Columns.AutoFit
End Sub
Private Sub PrintM1CacheToSheet(ws As Worksheet, ByRef row As Long)
If m1Cache Is Nothing Then
ws.Cells(row, 1).Value = "m1Cache is Nothing"
row = row + 1
Exit Sub
End If
ws.Cells(row, 1).Value = "Count: " & m1Cache.Count
row = row + 1
Dim key As Variant
For Each key In m1Cache.Keys
Dim vals As Variant
vals = m1Cache(key)
ws.Cells(row, 1).Value = key
ws.Cells(row, 2).Value = vals(1) & ": " & vals(2)
ws.Cells(row, 3).Value = vals(3)
ws.Cells(row, 4).Value = vals(4)
ws.Cells(row, 5).Value = vals(5)
row = row + 1
Next key
End Sub
Private Sub PrintM1KukanDCacheToSheet(ws As Worksheet, ByRef row As Long)
If m1KukanDCache Is Nothing Then
ws.Cells(row, 1).Value = "m1KukanDCache is Nothing"
row = row + 1
Exit Sub
End If
ws.Cells(row, 1).Value = "Count: " & m1KukanDCache.Count
row = row + 1
Dim dKey As Variant
For Each dKey In m1KukanDCache.Keys
ws.Cells(row, 1).Value = "D: " & dKey
row = row + 1
Dim innerDict As Object
Set innerDict = m1KukanDCache(dKey)
Dim fKey As Variant
For Each fKey In innerDict.Keys
ws.Cells(row, 2).Value = "F: " & fKey
row = row + 1
Dim arr As Object
Set arr = innerDict(fKey)
Dim gKey As Variant
For Each gKey In arr.Keys
ws.Cells(row, 3).Value = "G: " & gKey
row = row + 1
Next gKey
Next fKey
Next dKey
End Sub
Private Sub PrintM2CacheToSheet(ws As Worksheet, ByRef row As Long)
If m2Cache Is Nothing Then
ws.Cells(row, 1).Value = "m2Cache is Nothing"
row = row + 1
Exit Sub
End If
ws.Cells(row, 1).Value = "Count: " & m2Cache.Count
row = row + 1
Dim kukanKey As Variant
For Each kukanKey In m2Cache.Keys
ws.Cells(row, 1).Value = "KukanCode: " & kukanKey
row = row + 1
Dim innerDict As Object
Set innerDict = m2Cache(kukanKey)
Dim kanshuKey As Variant
For Each kanshuKey In innerDict.Keys
ws.Cells(row, 2).Value = "Kanshu: " & kanshuKey
row = row + 1
Dim innermostDict As Object
Set innermostDict = innerDict(kanshuKey)
Dim codeKey As Variant
For Each codeKey In innermostDict.Keys
ws.Cells(row, 3).Value = "Code: " & codeKey
ws.Cells(row, 4).Value = innermostDict(codeKey)
row = row + 1
Next codeKey
Next kanshuKey
Next kukanKey
End Sub
Private Sub PrintZ1CacheToSheet(ws As Worksheet, ByRef row As Long)
If z1Cache Is Nothing Then
ws.Cells(row, 1).Value = "z1Cache is Nothing"
row = row + 1
Exit Sub
End If
ws.Cells(row, 1).Value = "Count: " & z1Cache.Count
row = row + 1
Dim key As Variant
For Each key In z1Cache.Keys
Dim vals As Variant
vals = z1Cache(key)
ws.Cells(row, 1).Value = key
ws.Cells(row, 2).Value = vals(0)
row = row + 1
Next key
End Sub
Private Sub PrintO1CacheToSheet(ws As Worksheet, ByRef row As Long)
If o1Cache Is Nothing Then
ws.Cells(row, 1).Value = "o1Cache is Nothing"
row = row + 1
Exit Sub
End If
ws.Cells(row, 1).Value = "Count: " & o1Cache.Count
row = row + 1
Dim key As Variant
For Each key In o1Cache.Keys
Dim vals As Variant
vals = o1Cache(key)
ws.Cells(row, 1).Value = key
ws.Cells(row, 2).Value = vals(0)
ws.Cells(row, 3).Value = vals(1)
row = row + 1
Next key
End Sub

View File

@@ -135,6 +135,11 @@ Sub Z2_validateButton()
End If
Next r
' === Refresh Z2 cache after validation passes ===
If errorCount = 0 Then
Call RefreshZ2Cache
End If
MsgBox "Validation complete. Errors: " & errorCount, vbInformation
End Sub

View File

@@ -143,6 +143,11 @@ Sub Z3_validateButton()
End If
Next r
' === Refresh Z3 cache after validation passes ===
If errorCount = 0 Then
Call RefreshZ3Cache
End If
MsgBox "Validation complete. Errors: " & errorCount, vbInformation
End Sub

View File

@@ -0,0 +1,540 @@
' ====== (Tukin_C1) =======
' Commuter allowance editing sheet
' No CSV import - direct editing only
' ====== Constants ======
Const START_COL As Long = 3 ' C column (职员番号)
Const END_COL As Long = 56 ' BC column
Const ERROR_COL As Long = 57 ' BD column
Const Tukin_HEADER_ROW As Long = 6
' Column regions (for reference)
' D-H: 届出情報 (cols 4-8)
' I-J: 住所情報 (cols 9-10)
' K-O: 出勤情報 (cols 11-15)
' P-R: 自動車等情報 (cols 16-18)
' S-Y: 区間1情報 (cols 19-25)
' Z-AF: 区間2情報 (cols 26-32)
' AG-AM: 区間3情報 (cols 33-39)
' AN-AT: 区間4情報 (cols 40-46)
' AU-AX: 決定事項情報 (cols 47-50)
' AY-BA: 備考情報 (cols 51-53)
' BB-BC: 認定情報 (cols 54-56)
' ====== Event Handlers ======
Private Sub Worksheet_Change(ByVal Target As Range)
' === Column C changes: Fill address info from O1 and Z1 cache ===
If Target.Column = 3 And Target.Row >= 7 Then
Dim cell As Range
For Each cell In Target
If Trim(cell.Value) = "" Then
Call ClearRowData(Me, cell.Row)
Else
Call FillAddressFromO1(cell.Row)
' Generate transport (T) dropdown for all 4 kukan sections
Call CreateZ1TransportDropdown(Me, cell.Row, 20) ' 区間1 - T column
Call CreateZ1TransportDropdown(Me, cell.Row, 30) ' 区間2 - AD column
Call CreateZ1TransportDropdown(Me, cell.Row, 37) ' 区間3 - AK column
Call CreateZ1TransportDropdown(Me, cell.Row, 44) ' 区間4 - AR column
End If
Next
End If
' === Column T (区間1 交通機関) changes: Generate U (利用区間発) dropdown from Z1 ===
If Target.Column = 20 And Target.Row >= 7 Then
Dim cellT As Range
For Each cellT In Target
If Trim(cellT.Value) <> "" Then
Call CreateZ1StationDropdown(Me, cellT.Row, 20, 21, 1)
Else
Call ClearKukanValidation(Me, cellT.Row, 21)
End If
Next
End If
' === Column U (区間1 利用区間発) changes: Generate V (利用区間着) dropdown from M1_KukanD ===
If Target.Column = 21 And Target.Row >= 7 Then
Dim cellU As Range
For Each cellU In Target
If Trim(cellU.Value) <> "" Then
Call CreateM1KukanDDropdown(Me, cellU.Row, 20, 21, 22)
If Me.Cells(cellU.Row, 22).Validation.Formula1 = "" Then
' No dropdown data, clear V column
Call ClearKukanValidation(Me, cellU.Row, 22)
End If
Else
Call ClearKukanValidation(Me, cellU.Row, 22)
End If
Next
End If
' === Column AD (区間2 交通機関) changes ===
If Target.Column = 30 And Target.Row >= 7 Then
Dim cellAD As Range
For Each cellAD In Target
If Trim(cellAD.Value) <> "" Then
Call CreateZ1StationDropdown(Me, cellAD.Row, 30, 31)
Else
Call ClearKukanValidation(Me, cellAD.Row, 31)
End If
Next
End If
' === Column AE (区間2 利用区間発) changes ===
If Target.Column = 31 And Target.Row >= 7 Then
Dim cellAE As Range
For Each cellAE In Target
If Trim(cellAE.Value) <> "" Then
Call CreateM1KukanDDropdown(Me, cellAE.Row, 30, 31, 32)
If Me.Cells(cellAE.Row, 32).Validation.Formula1 = "" Then
Call ClearKukanValidation(Me, cellAE.Row, 32)
End If
Else
Call ClearKukanValidation(Me, cellAE.Row, 32)
End If
Next
End If
' === Column AK (区間3 交通機関) changes ===
If Target.Column = 37 And Target.Row >= 7 Then
Dim cellAK As Range
For Each cellAK In Target
If Trim(cellAK.Value) <> "" Then
Call CreateZ1StationDropdown(Me, cellAK.Row, 37, 38)
Else
Call ClearKukanValidation(Me, cellAK.Row, 38)
End If
Next
End If
' === Column AL (区間3 利用区間発) changes ===
If Target.Column = 38 And Target.Row >= 7 Then
Dim cellAL As Range
For Each cellAL In Target
If Trim(cellAL.Value) <> "" Then
Call CreateM1KukanDDropdown(Me, cellAL.Row, 37, 38, 39)
If Me.Cells(cellAL.Row, 39).Validation.Formula1 = "" Then
Call ClearKukanValidation(Me, cellAL.Row, 39)
End If
Else
Call ClearKukanValidation(Me, cellAL.Row, 39)
End If
Next
End If
' === Column AR (区間4 交通機関) changes ===
If Target.Column = 44 And Target.Row >= 7 Then
Dim cellAR As Range
For Each cellAR In Target
If Trim(cellAR.Value) <> "" Then
Call CreateZ1StationDropdown(Me, cellAR.Row, 44, 45)
Else
Call ClearKukanValidation(Me, cellAR.Row, 45)
End If
Next
End If
' === Column AS (区間4 利用区間発) changes ===
If Target.Column = 45 And Target.Row >= 7 Then
Dim cellAS As Range
For Each cellAS In Target
If Trim(cellAS.Value) <> "" Then
Call CreateM1KukanDDropdown(Me, cellAS.Row, 44, 45, 46)
If Me.Cells(cellAS.Row, 46).Validation.Formula1 = "" Then
Call ClearKukanValidation(Me, cellAS.Row, 46)
End If
Else
Call ClearKukanValidation(Me, cellAS.Row, 46)
End If
Next
End If
' === Column S changes: Fill 区間1 from M1/M2 cache ===
If Target.Column = 19 And Target.Row >= 7 Then
Dim cellS As Range
For Each cellS In Target
If Trim(cellS.Value) <> "" Then
' First check if T column has dropdown data
Call CreateZ1TransportDropdown(Me, cellS.Row, 20)
If Me.Cells(cellS.Row, 20).Validation.Formula1 <> "" Then
Call FillKukanFromM1(Me, cellS.Row, 19, Array(20, 21, 22)) ' S->T,U,V
Call CreateM2Dropdown(Me, cellS.Row, 19, 23) ' S->W dropdown (券種)
End If
Else
Call ClearKukanValidation(Me, cellS.Row, 23)
End If
Next
End If
' === Column W changes: Fill 券種 dropdown -> generate X dropdown ===
If Target.Column = 23 And Target.Row >= 7 Then
Dim cellW As Range
For Each cellW In Target
If Trim(cellW.Value) <> "" Then
Call CreateM2CodeDropdown(Me, cellW.Row, 19, 23, 24) ' kukanCode, kanshu -> X dropdown
Else
Call ClearKukanValidation(Me, cellW.Row, 24)
End If
Next
End If
' === Column Z changes: Fill 区間2 from M1/M2 cache ===
If Target.Column = 26 And Target.Row >= 7 Then
Dim cellZ As Range
For Each cellZ In Target
If Trim(cellZ.Value) <> "" Then
Call CreateZ1TransportDropdown(Me, cellZ.Row, 30)
If Me.Cells(cellZ.Row, 30).Validation.Formula1 <> "" Then
Call FillKukanFromM1(Me, cellZ.Row, 26, Array(27, 28, 29)) ' Z->AA,AB,AC
Call CreateM2Dropdown(Me, cellZ.Row, 26, 30) ' Z->AD dropdown
End If
Else
Call ClearKukanValidation(Me, cellZ.Row, 30)
End If
Next
End If
' === Column AD changes: Fill 券種 dropdown -> generate AH dropdown ===
If Target.Column = 30 And Target.Row >= 7 Then
Dim cellAD As Range
For Each cellAD In Target
If Trim(cellAD.Value) <> "" Then
Call CreateM2CodeDropdown(Me, cellAD.Row, 26, 30, 31) ' kukanCode, kanshu -> AH dropdown
Else
Call ClearKukanValidation(Me, cellAD.Row, 31)
End If
Next
End If
' === Column AG changes: Fill 区間3 from M1/M2 cache ===
If Target.Column = 33 And Target.Row >= 7 Then
Dim cellAG As Range
For Each cellAG In Target
If Trim(cellAG.Value) <> "" Then
Call CreateZ1TransportDropdown(Me, cellAG.Row, 37)
If Me.Cells(cellAG.Row, 37).Validation.Formula1 <> "" Then
Call FillKukanFromM1(Me, cellAG.Row, 33, Array(34, 35, 36)) ' AG->AH,AI,AJ
Call CreateM2Dropdown(Me, cellAG.Row, 33, 37) ' AG->AK dropdown
End If
Else
Call ClearKukanValidation(Me, cellAG.Row, 37)
End If
Next
End If
' === Column AK changes: Fill 券種 dropdown -> generate AL dropdown ===
If Target.Column = 37 And Target.Row >= 7 Then
Dim cellAK As Range
For Each cellAK In Target
If Trim(cellAK.Value) <> "" Then
Call CreateM2CodeDropdown(Me, cellAK.Row, 33, 37, 38) ' kukanCode, kanshu -> AL dropdown
Else
Call ClearKukanValidation(Me, cellAK.Row, 38)
End If
Next
End If
' === Column AN changes: Fill 区間4 from M1/M2 cache ===
If Target.Column = 40 And Target.Row >= 7 Then
Dim cellAN As Range
For Each cellAN In Target
If Trim(cellAN.Value) <> "" Then
Call CreateZ1TransportDropdown(Me, cellAN.Row, 44)
If Me.Cells(cellAN.Row, 44).Validation.Formula1 <> "" Then
Call FillKukanFromM1(Me, cellAN.Row, 40, Array(41, 42, 43)) ' AN->AO,AP,AQ
Call CreateM2Dropdown(Me, cellAN.Row, 40, 44) ' AN->AR dropdown
End If
Else
Call ClearKukanValidation(Me, cellAN.Row, 44)
End If
Next
End If
' === Column AR changes: Fill 券種 dropdown -> generate AS dropdown ===
If Target.Column = 44 And Target.Row >= 7 Then
Dim cellAR As Range
For Each cellAR In Target
If Trim(cellAR.Value) <> "" Then
Call CreateM2CodeDropdown(Me, cellAR.Row, 40, 44, 45) ' kukanCode, kanshu -> AS dropdown
Else
Call ClearKukanValidation(Me, cellAR.Row, 45)
End If
Next
End If
End Sub
' Fill kukan info from M1 cache (key: kukan code, value: 7 elements)
Private Sub FillKukanFromM1(ByVal ws As Worksheet, ByVal rowNum As Long, ByVal codeCol As Long, ByVal fillCols As Variant)
If m1Cache Is Nothing Then Call RefreshM1Cache
Dim code As String: code = Trim(ws.Cells(rowNum, codeCol).Value)
If code = "" Then Exit Sub
If m1Cache.Exists(code) Then
Dim vals As Variant: vals = m1Cache(code)
' value(1):value(2) -> fillCols(0)
ws.Cells(rowNum, fillCols(0)).Value = Trim(vals(1)) & ": " & Trim(vals(2))
' value(3) -> fillCols(1)
ws.Cells(rowNum, fillCols(1)).Value = Trim(vals(3))
' value(4) -> fillCols(2)
ws.Cells(rowNum, fillCols(2)).Value = Trim(vals(4))
Else
ws.Cells(rowNum, codeCol).ClearContents
End If
End Sub
' Create dropdown from M2 cache for ticket type column
Private Sub CreateM2Dropdown(ByVal ws As Worksheet, ByVal rowNum As Long, ByVal kukanCodeCol As Long, ByVal ticketCol As Long)
If m2Cache Is Nothing Then Call RefreshM2Cache
Dim kukanCode As String: kukanCode = Trim(ws.Cells(rowNum, kukanCodeCol).Value)
If kukanCode = "" Then Exit Sub
' Build dropdown list: get all kanshu (券種) for the kukanCode
Dim dropdownList As String
If m2Cache.Exists(kukanCode) Then
Dim innerDict As Object: Set innerDict = m2Cache(kukanCode)
Dim kanshu As Variant
For Each kanshu In innerDict.Keys
If dropdownList = "" Then
dropdownList = kanshu
Else
dropdownList = dropdownList & "," & kanshu
End If
Next kanshu
End If
If dropdownList <> "" Then
With ws.Range(ws.Cells(rowNum, ticketCol).Address).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=dropdownList
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.InputMessage = ""
End With
End If
End Sub
' Fill address dropdown from O1 cache
Private Sub FillAddressFromO1(ByVal rowNum As Long)
If o1Cache Is Nothing Then Call RefreshO1Cache
Dim empNo As String: empNo = Trim(Me.Cells(rowNum, 3).Value)
If empNo = "" Then Exit Sub
' Build dropdown list from O1 cache
Dim dropdownList As String
Dim key As Variant
For Each key In o1Cache.Keys
If dropdownList = "" Then
dropdownList = key
Else
dropdownList = dropdownList & "," & key
End If
Next key
' Create dropdown for I column (住所)
With Me.Range("I" & rowNum).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=dropdownList
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.InputMessage = ""
End With
End Sub
' Create transport (T) dropdown from Z1 cache
Private Sub CreateZ1TransportDropdown(ByVal ws As Worksheet, ByVal rowNum As Long, ByVal col As Long)
If z1Cache Is Nothing Then Call RefreshZ1Cache
' Build dropdown list from Z1 cache keys
Dim dropdownList As String
Dim key As Variant
For Each key In z1Cache.Keys
If dropdownList = "" Then
dropdownList = key
Else
dropdownList = dropdownList & "," & key
End If
Next key
If dropdownList <> "" Then
With ws.Cells(rowNum, col).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=dropdownList
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.InputMessage = ""
End With
End If
End Sub
' Create station (利用区間発) dropdown from M1_KukanD cache
Private Sub CreateZ1StationDropdown(ByVal ws As Worksheet, ByVal rowNum As Long, ByVal transportCol As Long, ByVal stationCol As Long)
If m1KukanDCache Is Nothing Then Call RefreshM1KukanDCache
Dim transport As String: transport = Trim(ws.Cells(rowNum, transportCol).Value)
If transport = "" Then Exit Sub
' Build dropdown list from M1_KukanD cache: get all F values for the transport (D)
Dim dropdownList As String
If m1KukanDCache.Exists(transport) Then
Dim innerDict As Object: Set innerDict = m1KukanDCache(transport)
Dim fValue As Variant
For Each fValue In innerDict.Keys
If dropdownList = "" Then
dropdownList = fValue
Else
dropdownList = dropdownList & "," & fValue
End If
Next fValue
End If
If dropdownList <> "" Then
With ws.Cells(rowNum, stationCol).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=dropdownList
.IgnoreBlank = True
.InCellDropdown = True
End With
End If
End Sub
' Create destination (利用区間着) dropdown from M1_KukanD cache
' Structure: { D: { F: [G] } }
Private Sub CreateM1KukanDDropdown(ByVal ws As Worksheet, ByVal rowNum As Long, ByVal transportCol As Long, ByVal stationFromCol As Long, ByVal stationToCol As Long)
If m1KukanDCache Is Nothing Then Call RefreshM1KukanDCache
Dim transport As String: transport = Trim(ws.Cells(rowNum, transportCol).Value)
Dim stationFrom As String: stationFrom = Trim(ws.Cells(rowNum, stationFromCol).Value)
If transport = "" Or stationFrom = "" Then Exit Sub
' Build dropdown list from M1_KukanD cache
Dim dropdownList As String
If m1KukanDCache.Exists(transport) Then
Dim innerDict As Object: Set innerDict = m1KukanDCache(transport)
If innerDict.Exists(stationFrom) Then
Dim arr As Object: Set arr = innerDict(stationFrom)
Dim gValue As Variant
For Each gValue In arr.Keys
If dropdownList = "" Then
dropdownList = gValue
Else
dropdownList = dropdownList & "," & gValue
End If
Next gValue
End If
End If
If dropdownList <> "" Then
With ws.Cells(rowNum, stationToCol).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=dropdownList
.IgnoreBlank = True
.InCellDropdown = True
End With
End If
End Sub
' Clear validation for kukan columns
Private Sub ClearKukanValidation(ByVal ws As Worksheet, ByVal rowNum As Long, ByVal col As Long)
ws.Cells(rowNum, col).Validation.Delete
End Sub
' Create dropdown from M2 cache: get code (J列) list for kukanCode + kanshu
Private Sub CreateM2CodeDropdown(ByVal ws As Worksheet, ByVal rowNum As Long, ByVal kukanCodeCol As Long, ByVal kanshuCol As Long, ByVal codeCol As Long)
If m2Cache Is Nothing Then Call RefreshM2Cache
Dim kukanCode As String: kukanCode = Trim(ws.Cells(rowNum, kukanCodeCol).Value)
Dim kanshu As String: kanshu = Trim(ws.Cells(rowNum, kanshuCol).Value)
If kukanCode = "" Or kanshu = "" Then Exit Sub
' Build dropdown list: get all code for kukanCode + kanshu
Dim dropdownList As String
If m2Cache.Exists(kukanCode) Then
Dim innerDict As Object: Set innerDict = m2Cache(kukanCode)
If innerDict.Exists(kanshu) Then
Dim innermostDict As Object: Set innermostDict = innerDict(kanshu)
Dim code As Variant
For Each code In innermostDict.Keys
If dropdownList = "" Then
dropdownList = code
Else
dropdownList = dropdownList & "," & code
End If
Next code
End If
End If
If dropdownList <> "" Then
With ws.Cells(rowNum, codeCol).Validation
.Delete
.Add Type:=xlValidateList, Formula1:=dropdownList
.IgnoreBlank = True
.InCellDropdown = True
End With
End If
End Sub
' Clear row data
Private Sub ClearRowData(ByVal ws As Worksheet, ByVal rowNum As Long)
ws.Range(ws.Cells(rowNum, 4), ws.Cells(rowNum, END_COL)).ClearContents
ws.Cells(rowNum, ERROR_COL).ClearContents
End Sub
' ====== Button Macros ======
Sub C1_validateButton()
Dim lastRow As Long, r As Long, errorCount As Long
lastRow = GetLastDataRowInRange(Me, START_COL, END_COL)
If lastRow < 7 Then
MsgBox "No data found.", vbExclamation
Exit Sub
End If
errorCount = 0
For r = 7 To lastRow
Call Validate(r)
If Trim(Cells(r, ERROR_COL).Value) <> "" Then
errorCount = errorCount + 1
End If
Next r
MsgBox "Validation complete. Errors: " & errorCount, vbInformation
End Sub
' Validation logic
Private Sub Validate(ByVal rowNum As Long)
Set ws = Me
' Clear background color
ws.Range(ws.Cells(rowNum, START_COL), ws.Cells(rowNum, END_COL)).Interior.Color = vbWhite
' Required columns: C-G, K-N, AW
Dim requiredCols As Variant
requiredCols = Array("C", "D", "E", "F", "G", "K", "L", "M", "N", "AW")
Dim col As Variant
For Each col In requiredCols
If Trim(ws.Range(col & rowNum).Value & "") = "" Then
ws.Cells(rowNum, ERROR_COL).Value = col & " column is required"
ws.Range(col & rowNum).Interior.Color = RGB(255, 0, 0)
Exit Sub
End If
Next col
ws.Cells(rowNum, ERROR_COL).ClearContents
End Sub
Sub C1_SortDataRowsByC()
Call SortDataRows(3)
End Sub
Sub C1_ToggleAutoFilter()
Call ToggleAutoFilter(START_COL, END_COL)
End Sub
Sub C1_AutoFitColumnWidth()
Call AutoFitColumnWidth(START_COL, END_COL)
End Sub