# Commuter Allowance Editor — Design Document ## 1. Project Overview | Item | Value | |------|-------| | Application | Excel 2021 (.xlsm) | | Purpose | Edit commuter certification by referencing master data | | Module | tuk (通勤 = commutation) | | Entry Point | メインメニュー (Main Menu sheet) | --- ## 2. Sheet Inventory ### 2.1 Editor Sheets #### C1 — 通勤手当CSV編集 (Commuter Allowance Editor) - **HeaderRow**: 6 | **StartRow**: 8 | **StartCol**: C | **EndCol**: BC - **Encoding**: shift_jis | **HasHeader**: Yes - **Role**: Main editing sheet — direct cell editing only, no CSV import - **Key columns**: - C: 職員番号 (Employee ID) — triggers address + transport dropdowns - S/AA/AI/AQ: 区間N区間コード (Section N Route Code) — triggers fill from M1 + dropdown cascade - T/AB/AJ/AR: 区間N交通機関 (Section N Transport Type) - U/AC/AK/AS: 区間N発 (Section N Departure Station) - V/AD/AL/AT: 区間N着 (Section N Arrival Station) - W/AE/AM/AU: 区間N券種 (Section N Ticket Type) - X/AF/AN/AV: 区間Nコード (Section N Code) - AY: 決定事項区分コード (Determination Category) - BB: 手当月額の決定区分コード (Monthly Amount Decision Category) #### M1 — 区間メンテナンス (Route Maintenance) - **HeaderRow**: 5 | **StartRow**: 7 | **StartCol**: C | **EndCol**: N - **Encoding**: shift_jis | **HasHeader**: Yes - **Role**: Route master — defines routes (code → transport + departure + arrival + fare) - **Key columns**: - C: 利用区間コード (Route Code) - D: 交通機関区分 (Transport Category) - E: 交通機関名称 (Transport Name) - F: 利用区間発名 (Departure Station) - G: 利用区間着名 (Arrival Station) - I: 運賃 (Fare) - J: 現金の場合の1箇月運賃 (Monthly Fare Cash) - K: 連絡 (Connection) - L: 特別料金区分 (Special Fare Category) - M: 特別料金券種 (Special Fare Ticket Type) - N: 特別料金負担額 (Special Fare Burden Amount) #### M2 — 区間詳細メンテナンス (Route Detail Maintenance) - **HeaderRow**: 6 | **StartRow**: 8 | **StartCol**: C | **EndCol**: R - **Encoding**: shift_jis | **HasHeader**: Yes - **Role**: Route detail master — ticket types and pricing per route code - **Key columns**: - C: 利用区間コード (Route Code) — join key with M1 - I: 券種 (Ticket Type: 0=普通, 1=定期券, 2=回数券, 3=プリペイドカード) - J: コード (Ticket Code) - K: 名称 (Ticket Name) - L: 1箇月運賃/販売額 (Monthly Fare / Sales Price) - M: 定期額/券1(額)/利用額 (Monthly / Ticket1 Amount / Usage Amount) - N: 定期支給期間/券1(枚)/特別料金 (Monthly Issue Period / Ticket1 Qty / Special Fare) - O: 特別料金/券2(額) (Special Fare / Ticket2 Amount) - P: 券2(枚) (Ticket2 Quantity) - Q: 端数(額) (Fractional Amount) - R: 特別料金 (Special Fare) ### 2.2 Master / Config Sheets (Z-series) #### Z1 — (222)交通機関マスタ (Transport Master) - **HeaderRow**: 5 | **StartRow**: 7 | **StartCol**: C | **EndCol**: I - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Transport type catalog (dropdown source for C1 T/AB/AJ/AR) - **Columns**: C=区分 (code), D=交通機関名称 (name), E=ポップアップ名称, F=コメント, G=略式名称, H=表示しない, I=略称 #### Z2 — (223)通勤_決定事項区分一覧 (Determination Category List) - **HeaderRow**: 5 | **StartRow**: 7 | **StartCol**: C | **EndCol**: G - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Determination categories for AY column dropdown - **Columns**: C=区分 (code), D=画面用名称, E=ポップアップ用名称, F=コメント, G=表示しない #### Z3 — (224)通勤_手当月額の決定区分一覧 (Monthly Amount Decision Category List) - **HeaderRow**: 5 | **StartRow**: 7 | **StartCol**: C | **EndCol**: H - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Monthly amount decision categories for BB column dropdown - **Columns**: C=区分 (code), D=画面用名称, E=ポップアップ用名称, F=コメント, G=表示しない, H=名称2 #### Z4 — (221)利用区間発着名区分 (Route Station Name Category) - **HeaderRow**: 5 | **StartRow**: 7 | **StartCol**: C | **EndCol**: H - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Station name catalog grouped by line (rosen). Used for M1 F/G column dropdowns. - **Columns**: C=区分 (station code), D=画面用名称/駅名 (station display name), E=ポップアップ名称, F=コメント/路線名 (line name), G=正式名称, H=表示しない - **Note**: E column (ポップアップ名称) is populated but currently ignored by code. Code reads F (路線名) and D (駅名) only. ### 2.3 Ticket Master Sheets (T-series) #### T1 — (244)通勤_定期券名称区分一覧 (Commuter Pass Name Category) - **HeaderRow**: 5 | **StartRow**: 7 | **StartCol**: C | **EndCol**: G - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Periodic commuter pass types (dropdown source for W/AE/AM/AU) - **Columns**: C=区分 (code), D=画面用名称, E=ポップアップ用名称, F=コメント, G=表示しない #### T2 — (245)通勤_回数券名称区分一覧 (Fare Ticket Name Category) - **HeaderRow**: 5 | **StartRow**: 7 | **StartCol**: C | **EndCol**: M - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Frequency ticket types with pricing breakdown - **Columns**: C=区分, D=画面用名称, E=ポップアップ用名称, F=コメント, G=表示しない, H=販売額, I=券1(額), J=券1(枚), K=券2(額), L=券2(枚), M=端数額 - **Feature**: ZeroFillCols = H,I,J,K,L,M — when C column (区分) is edited and H~M are empty, they are auto-filled with "0" #### T3 — (246)通勤_プリペイドカード名称区分一覧 (Prepaid Card Name Category) - **HeaderRow**: 5 | **StartRow**: 7 | **StartCol**: C | **EndCol**: I - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Prepaid card types with pricing - **Columns**: C=区分, D=画面用名称, E=ポップアップ用名称, F=コメント, G=表示しない, H=販売額, I=利用額 ### 2.4 Other / Reference Sheets #### O1 — 住所情報 (Address Information) - **HeaderRow**: 5 | **StartRow**: 6 | **StartCol**: C | **EndCol**: F - **Encoding**: shift_jis | **HasHeader**: Yes - **Role**: Employee address lookup (keyed by employee number) - **Columns**: C=社員番号, D=更新日, E=住所1, F=住所2 #### O2 — (507)発信者一覧 (Sender List) - **HeaderRow**: 5 | **StartRow**: 6 | **StartCol**: C | **EndCol**: O - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Sender/official name list for dropdown (O2Cache) - **Columns**: C=区分, D=画面用名称, E=ポップアップ用名称, F=コメント, G=表示しない, H=発信者名称, I=発信者氏名, J=所属区分(From), K=所属区分(To), L=研究科区分, M=ソート順(From), N=ソート順(To), O=諸手当認定者区分 #### O3 — (220)通勤手当届出事由区分 (Notification Reason Category) - **HeaderRow**: 5 | **StartRow**: 6 | **StartCol**: C | **EndCol**: I - **Encoding**: utf-8 | **HasHeader**: No - **Role**: Notification reason categories for C1 G column dropdown (Todoke) - **Columns**: C=区分, D=画面用名称, E=ポップアップ名称, F=コメント, G=表示しない, H=備考, I=からまで #### Enum — Dropdown Enum Values - **Role**: Stores all enum values used in dropdown validation - **Sections** (each keyed by column position): - Col A (KeyCol=1): 特別料金区分 (tokubetuList: 普通=0, 定期券=1, 回数券=2, プリペイドカード=3) - Col C (KeyCol=3): 券種 (kenshuList) - Col F (KeyCol=6): 連絡 (renrakuList) - Col H (KeyCol=8): 往復区分 (oufukuList: 1=片道, 2=往復) - Col K (KeyCol=11): 交替制 (koutaiList: 0=非該当, 1=該当) - Col N (KeyCol=14): 非該当者認定簿出力区分 (higaitouList: 1=出力, 2=非出力) - Col Q (KeyCol=17): エラーメッセージ (errorList) #### Caches — Pre-rendered Dropdown Cache - **Role**: Stores pre-built validation lists for named-range based dropdowns - **Layout**: Each row is a pre-formatted "code:name" string used as named-range source --- ## 3. Cache Architecture ### 3.1 Cache Dictionary Keys | Constant | Sheet | Structure | Key | Value | |----------|-------|-----------|-----|-------| | `CACHE_Z1` | Z1 | Dict(code → Array(name)) | transport code | Array(transport name) | | `CACHE_Z2` | Z2 | Dict(code → Array(name)) | determination code | Array(display name) | | `CACHE_Z3` | Z3 | Dict(code → Array(name)) | decision code | Array(display name) | | `CACHE_Z4ROSEN` | Z4 | Dict(rosen → Dict(station → True)) | line name | Dict of all stations on that line | | `CACHE_T1` | T1 | Dict(code → Array(name)) | ticket type code | Array(display name) | | `CACHE_T2` | T2 | Dict(code → Array(all fields)) | ticket code | Array(C,D,E,F,G,H,I,J,K,L,M) | | `CACHE_T3` | T3 | Dict(code → Array(all fields)) | card code | Array(C,D,E,F,G,H,I) | | `CACHE_O1` | O1 | Dict(empNo → Array(addr1, addr2)) | employee number | Array(address1, address2) | | `CACHE_O2` | O2 | Dict(code → Array(name)) | sender code | Array(official name) | | `CACHE_O3` | O3 | Dict(code → Array(name)) | reason code | Array(display name) | | `CACHE_M1` | M1 | Dict(code → Array(all cols)) | route code | Array(C,D,E,F,G,H,I,J,K,L,M,N) | | `CACHE_M2` | M2 | Dict(code → Dict(ticketType → Array(detail))) | route code | Dict of ticket type → Array(I,J,K,L,M,N,O,P,Q,R) | ### 3.2 Special Enum Caches | Constant | Source | Key | Value | |----------|--------|-----|-------| | `tokubetuList` | Enum sheet Col A | int (0-3) | name string | | `kenshuList` | Enum sheet Col C | int | name string | | `renrakuList` | Enum sheet Col F | int | name string | | `oufukuList` | Enum sheet Col H | code | name string | | `koutaiList` | Enum sheet Col K | code | name string | | `higaitouList` | Enum sheet Col N | code | name string | | `errorList` | Enum sheet Col Q | error code | error message | ### 3.3 m1KukanDCache (Special Derived Cache) - **Type**: Dict(transportCode & "|" & fromStation → Dict(toStation → True)) - **Purpose**: Fast lookup of valid arrival stations given transport + departure - **Derivation**: Built from M1 sheet at runtime: groups M1 rows by D(transport) + F(fromStation), keys are G(toStation) - **Used by**: `BuildZ4StationToDropdown` → C1 M1 KukanD cascade --- ## 4. Module Architecture ### 4.1 Module Summary | Module | Responsibility | |--------|---------------| | `Common_Constants` | Error code constants (1001-1009, 2001+) | | `Common_Global_Cache` | All cache loading, refresh, and lookup. Sheet config definitions (RefreshSheetDict). Global Scripting.Dictionary objects. | | `Common_Functions` | CSV helpers (GetCSVHeader, CleanCSVField), validation helpers (CheckRequired, CheckAlphanumeric, etc.), utility functions (FormatDateInput, GetCode, MakeSelect) | | `Common_Selector` | Dropdown builder functions (BuildTransportList, BuildTodokeList, etc.) and Z4 cascade dropdowns (BuildZ4StationFromDropdown, BuildZ4StationToDropdown) | | `Common_File_Utils` | CSV file read/write (ReadCSV, WriteCSV), BOM handling | | `Common_Button` | Button action handlers: CSV_Import, Validation, CSV_Export, Sort, Filter, Fit. RunValidationSilent wrapper. | | `Common_Shape` | Icon/shape alignment utilities (AlignIconsByCenter) | ### 4.2 Sheet Class Summary | Class | Sheet | Key Methods | Notes | |-------|-------|-------------|-------| | `C1` | C1 | Worksheet_Change, FillAddressFromO1, FillTransportFromM1KukanD, FillDepartureFromM1KukanD, FillArrivalFromM1KukanD, FillKukanFromM1, FillCodeFromM2, ValidateRow | Main editor. No CSV import. | | `M1` | M1 | Worksheet_Change, Validate, BuildM1StationDropdown | Route master with Z4 cascade dropdowns | | `M2` | M2 | Worksheet_Change, Validate | Route detail master, ticket pricing | | `T1` | T1 | Validate | Periodic pass name master | | `T2` | T2 | Worksheet_Change, Validate | Frequency ticket master with ZeroFillCols feature | | `T3` | T3 | Validate | Prepaid card master | | `Z1` | Z1 | Validate | Transport type master | | `Z2` | Z2 | Validate | Determination category master | | `Z3` | Z3 | Validate | Monthly amount decision master | | `Z4` | Z4 | Validate | Station name / line master | | `O1` | O1 | Validate | Employee address master (empty stub) | | `O2` | O2 | Validate | Sender list (empty stub) | | `O3` | O3 | Validate | Notification reason master (empty stub) | --- ## 5. Data Flow ### 5.1 C1 Editing Flow (4 Kukan Sections) ``` User edits C (職員番号) → FillAddressFromO1: O1Cache lookup → populate I/J dropdowns → BuildTransportList → T/AB/AJ/AR dropdown (Z1Cache) User selects T (交通機関) → BuildZ1StationDropdown → U/AC/AK/AS dropdown (Z1Cache) User selects U (発) → BuildZ4StationFromDropdown → F column (from station) dropdown (Z4RosenCache filtered by transport) OR: BuildM1KukanDDropdown → V/AD/AL/AT dropdown (m1KukanDCache: transport+from → to stations) User selects S (区間コード) → FillKukanFromM1: M1Cache lookup → fills T/U/V/W/Y with pre-defined values → BuildM2Dropdown → W/AE/AM/AU dropdown (M2Cache by route code) → BuildM2CodeDropdown → X/AF/AN/AV dropdown (M2Cache by route+券種) User selects W (券種) → BuildM2CodeDropdown → X/AF/AN/AV dropdown (M2Cache: route+券種 → code) User edits X (コード) → FillCodeFromM2: M2Cache lookup → fills AF/AG/AH with M2 details ``` ### 5.2 CSV Import Flow ``` CSV_Import_Button clicked → User selects CSV file → ReadCSV (Common_File_Utils): shift_jis decode, BOM strip → GetCSVHeader: extract header row → LoadLookup: build/refresh cache for target sheet → DO_CSV_Import: parse rows, write to sheet cells → RunValidationSilent: call Sheet.Validate per row → HandleError on validation failure ``` ### 5.3 Validation Flow ``` RunValidationSilent(sheet) → for each data row → Sheet.Validate(ws, rowNum, lastDataRow) → On error: Err.Raise → caught by HandleError in caller → Returns error count ``` --- ## 6. Key Constants ### 6.1 CACHE_ Constants (defined in Common_Global_Cache) ``` CACHE_Z4ROSEN = "Z4Rosen" CACHE_T1 = "T1" CACHE_T2 = "T2" CACHE_T3 = "T3" CACHE_O1 = "O1" CACHE_O2 = "O2" CACHE_O3 = "O3" CACHE_M1 = "M1" CACHE_M2 = "M2" ``` ### 6.2 Validation Error Codes ``` 1001: ERR_CACHE_NOT_FOUND 1002: ERR_CACHE_EMPTY 1003: ERR_VALIDATION_FAILED 1004: ERR_CONFIG_NOT_FOUND 1005: ERR_CONFIG_INVALID 1006: ERR_CONFIG_EMPTY_PARAM 1007: ERR_SHEET_MISSING 2001: ERR_VALIDATION 5001-5009: File/CSV errors ``` ### 6.3 MakeSelect Format All dropdown values use `code:name` format: - Display: `"001:JR 東北線"` → MakeSelect("001", "JR 東北線") - GetCode("001:JR 東北線") → "001" - GetDisplay("001:JR 東北線") → "JR 東北線" (via mid/InStr) --- ## 7. Column Layout Reference ### C1 — 58 columns (C to BG) | Column | Header | Type | |--------|--------|------| | C | 職員番号 | string(8) | | D | 事実発生年月日 | date | | E | 提出年月日 | date | | F | 受理年月日 | date | | G | 届出の事由コード | enum(O3) | | H | 届出の備考 | string(40) | | I | 住所1 | string | | J | 住所2 | string | | K | 運賃改正・法改正年月日 | date | | L | 出勤予定日数 | number(2) | | M | 往復区分 | enum(oufukuList) | | N | 交替制 | enum(koutaiList) | | O | 算出式 | string(80) | | P | 自動車等使用距離 | number(3) | | Q | 自動車等支給額 | number(6) | | R | 自動車等駐車場代 | number(6) | | S~Y | 区間1 (コード/交通/発/着/券種/コード/期間) | mixed | | Z | 区間1支給開始年月 | date | | AA~AG | 区間2 | mixed | | AH | 区間2支給開始年月 | date | | AI~AM | 区間3 | mixed | | AN | 区間3支給開始年月 | date | | AO~AS | 区間4 | mixed | | AT | 区間4支給開始年月 | date | | AU | 決定事項区分コード | enum(Z2) | | AV | 非該当の理由 | string | | AW | 非該当者認定簿出力区分 | enum(higaitouList) | | AX | 非該当者認定簿出力区分 (actual) | enum | | BB | 手当月額の決定区分コード | enum(Z3) | | BC | 支給の始期 | date | | BD | 備考 | string | | BE | 所属コード | string | | BF | 認定年月日 | date | | BG | (各庁の長)官職コード | string | --- ## 8. Known Issues / Technical Debt | # | Severity | Description | Status | |---|----------|-------------|--------| | 1 | High | M2.cls: `cacheVal` declared inside If block but used in Select Case outside it | Fixed | | 2 | High | C1.cls: `kukanCol`, `kukanCode`, `kukanLetter` undeclared in Validate | Fixed | | 3 | Medium | CJK comments in Common_Shape.bas and C1.cls | Fixed | | 4 | Medium | Hardcoded path `D:\Project\upds7\vba\` in Import_modules.bas | Fixed | | 5 | Medium | `sheetConfDict("Z4")` hardcoded key | Fixed | | 6 | Medium | `sheetName:="M1"` hardcoded in Common_Shape | Fixed | | 7 | Medium | M1.cls: `"M2"` hardcoded sheet reference | Fixed | | 8 | Medium | `On Error Resume Next` in 3 cache lookup functions (Common_Global_Cache.bas) | Fixed | | 9 | Low | T2.cls: CJK in comment `区分` | Fixed | | 10 | Medium | O1/O2/O3 Validate stubs are empty | Not fixed |