欄位規格(schema)設定說明

Fixed-Width Inspector 靠一份 JSON 格式的「欄位規格」來認識你的檔案:每個欄位從第幾碼開始、有幾碼、應該是什麼內容。這份說明從最簡單的例子開始,看完前兩節就能用。

想直接拿現成的?跳到 範本產生器,勾選檔案有哪些記錄,複製貼上就好。

第 1 碼5 分鐘上手

假設銀行給你的格式說明長這樣:每行 30 碼,第 1–10 碼是帳號、第 11–22 碼是戶名、第 23–30 碼是金額(含 2 位小數)。

  1. 在媒體檔旁邊建立 .fixedwidth 資料夾
    資料夾結構
    我的資料夾/
    ├─ .fixedwidth/
    │  └─ salary.json      ← 欄位規格放這裡
    └─ SALARY_202610.txt   ← 你的媒體檔
  2. 把格式說明抄進 salary.json
    .fixedwidth/salary.json
    {
      "name": "薪轉檔",
      "filePattern": "SALARY*.txt",
      "lineLength": 30,
      "records": [
        {
          "type": "detail",
          "fields": [
            { "name": "帳號", "start": 1,  "length": 10, "type": "numeric" },
            { "name": "戶名", "start": 11, "length": 12, "type": "text" },
            { "name": "金額", "start": 23, "length": 8,  "type": "amount", "decimals": 2 }
          ]
        }
      ]
    }

    檔案只有一種格式時,records 放一筆就好。start 和格式說明一樣從 1 開始算。

  3. 打開 SALARY_202610.txt

    檔名符合 filePattern,欄位就會自動上色,右下角狀態列顯示「薪轉檔」。有錯的地方出現紅色波浪底線,滑鼠停上去看原因。

更快的做法:打開媒體檔後,按 ⇧⌘P(Windows 是 Ctrl+Shift+P)執行 Fixed-Width Inspector: Create Schema from Template,勾選首筆、明細、尾筆,範例就會建在檔案旁邊並立即套用,再照格式說明修改即可。

第 2 碼規格放在哪裡、怎麼對應檔案

打開一個檔案時,依下列順序找規格,先找到的優先:

  1. 你手動指定的規格:點編輯器右上角的尺規圖示或狀態列,選「從檔案選擇 schema…」,可以指定任何位置的 .json,這個選擇會被記住。
  2. 檔案同一層的 .fixedwidth/,找不到再往上一層,直到工作區根目錄。最近的優先,和 .editorconfig 一樣。
  3. 設定 fixedWidthInspector.schemaPaths 列出的資料夾,適合放公司共用的規格。

filePattern 的寫法

寫法對應到
ACH*.txt任何資料夾裡,檔名以 ACH 開頭的 .txt。沒有 / 時只比對檔名。
**/ACH*.txt同上,寫法不同。
data/*.txt.fixedwidth 所在資料夾底下 data/ 裡的 .txt。
*.{txt,dat}.txt 或 .dat 都可以。
["A*.txt", "B*.txt"]寫成陣列,符合任一個就套用。

比對不分大小寫。支援 *、**、?、[abc]、[!abc]、{a,b}。

第 3 碼整份檔案的設定

規格最外層描述整份檔案:

參數說明預設
name必填規格名稱,顯示在狀態列。—
filePattern自動對應哪些檔名,字串或字串陣列(見上一節)。省略時只能手動指定。—
encoding檔案編碼:utf-8、big5、ms950。台灣的媒體檔多半是 big5 / ms950。utf-8
lengthUnit長度單位:byte(位元組)或 char(字元)。見位元組與字元。big5 / ms950 為 byte,utf-8 為 char
lineLength每行應有幾碼。省略時只檢查每行夠不夠放下所有欄位。—
lineEnding規定的換行符號:CRLF(Windows)或 LF。省略時不檢查。—
records必填記錄格式清單,見下一節。—
crossChecks跨行檢核,例如尾筆總筆數要等於明細筆數。見跨行檢核。—

第 4 碼記錄:首筆、明細、尾筆

很多媒體檔的第一行是「首筆」(處理日期、發動者),中間每行是「明細」,最後一行是「尾筆」(總筆數、總金額),三種的欄位都不一樣。通常靠第 1 碼分辨:1 是首筆、2 是明細、3 是尾筆。

records 的寫法
"records": [
  {
    "type": "header",
    "when": { "start": 1, "length": 1, "equals": "1" },
    "position": "first",
    "fields": [ … ]
  },
  {
    "type": "detail",
    "when": { "start": 1, "length": 1, "equals": "2" },
    "fields": [ … ]
  },
  {
    "type": "trailer",
    "when": { "start": 1, "length": 1, "equals": "3" },
    "position": "last",
    "fields": [ … ]
  }
]
參數說明
type必填記錄別名稱。慣例用 header、detail、trailer,也可以自己取名,例如 H1。
when怎麼認出這種記錄:第 start 碼起 length 碼的內容等於 equals。equals 可以是陣列,例如 ["2", "4"]。只有一種記錄時可以省略。
positionfirst:必須在第一行;last:必須在最後一行。
required每個檔案是否一定要有這種記錄。有 position 的預設 true,其他預設 false。設成 false 時缺少也不報錯,相關的跨行檢核自動略過。
label每行最前面顯示的標籤文字。省略時 header / detail / trailer 顯示「首筆 / 明細 / 尾筆」,其他顯示 type。
fields必填欄位清單,見下一節。
比對順序:每一行由上往下比對 records,用第一個符合的。沒有 when 的記錄符合所有行,要放在最後面。都不符合的行會標成紅色「未知」。

第 5 碼範本產生器:7 種組合

首筆、明細、尾筆可以任意組合(只有明細、首筆加明細、明細加尾筆……共 7 種)。勾選你的檔案有哪些記錄,下面的規格會即時更新,複製後再依實際格式說明修改位置與長度。

.fixedwidth/ach.json
  • 只有一種記錄時,不需要 when,每一行都用它。
  • 同時有明細和尾筆時,會加上「尾筆總筆數 = 明細筆數」和「尾筆總金額 = 明細金額加總」兩個跨行檢核。
  • 這和 VS Code 裡「Create Schema from Template」產生的內容相同。

第 6 碼欄位的共用參數

參數說明
name必填欄位名稱,顯示在滑鼠說明、狀態列和表格標題。
start必填起始位置,從 1 開始,單位依 lengthUnit。
length必填長度(幾碼)。
type必填欄位型態,見下一節。
requiredtrue 時不可全為空白。
description說明文字,顯示在滑鼠說明裡,例如「民國年月日」。
severity這個欄位出錯時的嚴重程度:error(紅)、warning(黃)、info(藍)。
小技巧:格式說明常寫「第 56–68 碼」,換算成 "start": 56, "length": 13(68 − 56 + 1 = 13)。寫錯時套件會提示欄位重疊或超出 lineLength。

第 7 碼8 種欄位型態

text 文字

任意文字,靠左對齊、右邊補空白,例如戶名、地址。可加 pattern(正規表示式)限制內容,比對時會先去掉右邊的空白。

範例
{ "name": "戶名", "start": 16, "length": 40, "type": "text", "required": true }
{ "name": "電話", "start": 56, "length": 10, "type": "text", "pattern": "^09\\d{8}$" }
開頭有空白(沒靠左)不符合 patternrequired 卻是空白

numeric 數字

只能是 0–9,靠右、左邊補 0,例如帳號、筆數。允許左邊補空白時加 "allowSpaces": true。表格檢視會照原樣顯示,帳號前面的 0 不會不見。

範例
{ "name": "帳號", "start": 2, "length": 14, "type": "numeric" }
{ "name": "序號", "start": 2, "length": 6, "type": "numeric", "allowSpaces": true }
含 0–9 以外的字夾雜空白整欄空白

amount 金額

只有數字,小數點是「隱含」的:"decimals": 2 時 0000000150000 代表 1,500.00。有正負號時加 "signed": true,正負號可放在最前面或最後面。

範例
{ "name": "金額", "start": 56, "length": 13, "type": "amount", "decimals": 2 }
{ "name": "調整金額", "start": 69, "length": 11, "type": "amount", "decimals": 0, "signed": true }
出現小數點或逗號正負號位置不對整欄空白

date 日期

檢查日期是否真的存在(例如 2 月 30 日會報錯)。format 可選:

format長度例子
YYYYMMDD(預設)820261020 = 2026-10-20
YYMMDD6261020 = 2026-10-20(視為 20YY 年)
ROC_YYYMMDD71151020 = 民國 115 年 10 月 20 日
範例
{ "name": "扣款日期", "start": 79, "length": 7, "type": "date", "format": "ROC_YYYMMDD" }
日期不存在長度和 format 不符民國年為 0

空白的日期欄不會報錯;一定要有日期時加 "required": true。

enum 代碼清單

值必須是清單中的一個,例如記錄別、交易代碼。比對時前後空白會忽略。

範例
{ "name": "記錄別", "start": 1, "length": 1, "type": "enum", "values": ["2"] }
{ "name": "交易代號", "start": 2, "length": 2, "type": "enum", "values": ["01", "02", "05"] }
值不在清單內

twid 身分證字號

1 個大寫英文字母加 9 碼數字,並驗證檢查碼。第 2 碼可以是 1、2(身分證)或 8、9(新式居留證)。

範例
{ "name": "身分證號", "start": 69, "length": 10, "type": "twid" }
格式不對檢查碼錯誤

twbiz 統一編號

8 碼數字,並驗證檢查碼(含第 7 碼為 7 的特殊規則)。

範例
{ "name": "發動者統編", "start": 10, "length": 8, "type": "twbiz" }
不是 8 碼數字檢查碼錯誤

filler 保留欄位

格式說明裡的「保留欄」「空白」,預設必須全為空白或全為 0。只允許某個字元時用 fillChar。

範例
{ "name": "保留欄", "start": 86, "length": 165, "type": "filler" }
{ "name": "補位", "start": 31, "length": 20, "type": "filler", "fillChar": "*" }
裡面有其他內容(警告)

第 8 碼跨行檢核

檢查不同行之間的數字對不對得起來。參照欄位的寫法是「記錄別.欄位名稱」。

crossChecks
"crossChecks": [
  { "rule": "count", "record": "detail", "equals": "trailer.總筆數" },
  { "rule": "sum", "field": "detail.金額", "equals": "trailer.總金額" }
]
rule意思參數
count某種記錄的筆數要等於某個值record:要數哪種記錄;equals:「記錄別.欄位名稱」或數字
sum某個金額欄位的加總要等於某個值field:「記錄別.欄位名稱」;equals:同上
  • equals 也可以直接寫數字,例如每個檔案固定 100 筆:"equals": 100。
  • 可加 severity 調整嚴重程度。
  • 參照的記錄設為 "required": false 且檔案裡沒有時,這個檢核自動略過。
  • 加總時格式錯誤的金額不計入,訊息會告訴你略過了幾筆。

第 9 碼位元組與字元:Big5 的中文算 2 碼

台灣多數媒體檔用 Big5(MS950)編碼,格式說明的長度以「位元組」計:英數字 1 碼、中文 2 碼。所以「王小明」雖然是 3 個字,在規格上佔 6 碼。

200…王小明␣␣

每一格是 1 碼。中文字佔 2 格,戶名欄 40 碼可以放 20 個中文字。

  • Big5 / MS950 檔案請設定 "encoding": "big5",lengthUnit 會自動用 byte。
  • 如果欄位邊界剛好落在一個中文字的中間,會出現「欄位邊界切到中文字」,通常代表前面某個欄位多了或少了 1 碼。
  • VS Code 預設用 UTF-8 開檔,Big5 檔會變成亂碼。套件偵測到時會提示,按「以 BIG5 重新開啟」即可。想一勞永逸,可以在設定加上 "files.encoding": "cp950"(只對這個工作區設定比較安全)。
  • UTF-8 的檔案若規格以字元計,設定 "encoding": "utf-8" 即可(預設 lengthUnit 為 char)。

第 10 碼套件設定

在 VS Code 設定(⌘,)搜尋「Fixed-Width Inspector」,或直接寫進 settings.json:

settings.json
{
  "fixedWidthInspector.enabled": true,
  "fixedWidthInspector.language": "auto",
  "fixedWidthInspector.schemaPaths": [".fixedwidth"],
  "fixedWidthInspector.fieldColors": [
    "rgba(59, 130, 246, 0.55)",
    "rgba(249, 115, 22, 0.55)",
    "rgba(34, 197, 94, 0.55)",
    "rgba(217, 70, 239, 0.55)"
  ],
  "fixedWidthInspector.showRecordLabels": true,
  "fixedWidthInspector.highlightCurrentField": true,
  "fixedWidthInspector.maxDiagnostics": 1000,
  "fixedWidthInspector.debounceMs": 300
}
設定說明
enabled開關整個套件。
language介面語言:auto 跟隨 VS Code、en 英文、zh-tw 繁體中文。
schemaPaths額外的規格資料夾,相對於工作區或絕對路徑。檔案旁邊的 .fixedwidth/ 一律會找。
fieldColors欄位顏色,建議 2–4 個半透明色;透明度越高越鮮明。
showRecordLabels每行前面是否顯示首筆、明細、尾筆標籤。
highlightCurrentField游標所在的欄位是否加上外框,方便在一整片顏色裡找到目前位置。
maxDiagnostics「問題」面板最多列幾筆,超過時狀態列會提示。
debounceMs修改後等多久(毫秒)重新檢查。

指令

按 ⇧⌘P 輸入「Fixed-Width」就能找到:

指令做什麼
Select Schema為目前檔案選擇規格、改回自動對應,或從檔案選擇。
Validate File重新檢查整份檔案,並告訴你有幾個錯誤。
Toggle Highlighting暫時開關欄位上色。
Create Schema from Template勾選記錄組合,在檔案旁邊建立範例規格。
Reopen with Schema Encoding用規格指定的編碼重新開啟(解決亂碼)。
Show as Table以表格檢視。
Export as CSV把某種記錄匯出成 Excel 開得了的 CSV。

第 11 碼錯誤訊息對照

「問題」面板每筆訊息後面的代碼代表錯誤種類:

代碼意思
line.length整行長度不對,或短到放不下所有欄位。
line.unknownRecord這行不符合任何記錄的 when。
line.position首筆不在第一行,或尾筆不在最後一行。
line.missingRecordrequired 的記錄完全沒出現。
line.ending換行符號和 lineEnding 不一致。
line.encoding有無法解碼的字元,檔案可能用錯編碼開啟。
field.splitChar欄位邊界切到中文字。
required必填欄位是空白。
text.*、numeric.*、amount.*、date.*、enum.*、filler.*欄位內容不符合型態規則。
twid.invalid、twbiz.invalid身分證、統編格式或檢查碼錯誤。
cross.count、cross.sum跨行檢核的筆數或加總對不上。

第 12 碼常見問題

打開檔案沒有顏色?

  • 看右下角狀態列:顯示「未套用 schema」代表沒找到對應的規格。確認 .fixedwidth 在檔案同一層或上層,且檔名符合 filePattern。
  • 規格寫錯時,「問題」面板會列出錯在哪一行,例如缺少 name、type 拼錯。
  • 也可以點狀態列,直接「從檔案選擇 schema…」。

中文變成亂碼?

檔案是 Big5 但被當成 UTF-8 開啟。執行「Reopen with Schema Encoding」,或點右下角的「UTF-8」改選「Traditional Chinese (Big5)」。

從某個欄位開始,後面全部錯位?

通常是前面某個欄位的長度寫錯,或某一行真的多(少)了一碼。看那一行有沒有 line.length 或 field.splitChar 的提示。

每個欄位的顏色看起來寬度不一樣?

正常。中文字在編輯器裡佔 2 格寬,所以同樣 10 碼,含中文的欄位看起來比較寬或窄,實際碼數是對的;滑鼠停上去可以看到位置與長度。

匯出 CSV 用 Excel 打開,帳號前面的 0 會不見嗎?

不會。數字類欄位會用 ="000123" 的形式寫出,Excel 會當成文字保留。CSV 也加了 BOM,中文不會亂碼。

規格可以分享給同事嗎?

可以,.fixedwidth/ 裡就是一般 JSON 檔,放進版本控制或共用資料夾,再用 schemaPaths 指過去即可。

Record layout (schema) guide

Fixed-Width Inspector learns your file from a JSON "record layout": where each field starts, how long it is and what it should contain. This guide starts with the simplest case; the first two sections are enough to get going.

Want something ready-made? Jump to the template builder, tick the records your file has, and copy.

pos 1Get started in 5 minutes

Say your bank's spec reads: 30 characters per line, account in positions 1–10, name in 11–22, amount in 23–30 with 2 implied decimals.

  1. Create a .fixedwidth folder next to your file
    Folder layout
    my-folder/
    ├─ .fixedwidth/
    │  └─ salary.json      ← the record layout goes here
    └─ SALARY_202610.txt   ← your data file
  2. Copy the spec into salary.json
    .fixedwidth/salary.json
    {
      "name": "Payroll file",
      "filePattern": "SALARY*.txt",
      "lineLength": 30,
      "records": [
        {
          "type": "detail",
          "fields": [
            { "name": "Account", "start": 1,  "length": 10, "type": "numeric" },
            { "name": "Name",    "start": 11, "length": 12, "type": "text" },
            { "name": "Amount",  "start": 23, "length": 8,  "type": "amount", "decimals": 2 }
          ]
        }
      ]
    }

    A file with a single layout needs just one entry in records. start counts from 1, exactly like the spec.

  3. Open SALARY_202610.txt

    The name matches filePattern, so fields are colored right away and the status bar shows "Payroll file". Problems get a red squiggle; hover to see why.

Even faster: with your file open, press ⇧⌘P (Ctrl+Shift+P on Windows) and run Fixed-Width Inspector: Create Schema from Template. Tick Header, Detail and/or Trailer and a sample layout is created next to the file and applied. Then adjust it to your spec.

pos 2Where layouts live and how files match

When you open a file, layouts are looked up in this order; the first match wins:

  1. A layout you chose by hand: click the ruler icon in the editor title or the status bar and pick "Choose a schema file…". Any .json anywhere works, and the choice is remembered.
  2. .fixedwidth/ next to the file, then each parent folder up to the workspace root. The nearest one wins, just like .editorconfig.
  3. Folders listed in fixedWidthInspector.schemaPaths, handy for layouts shared across a team.

Writing filePattern

PatternMatches
ACH*.txtAny .txt starting with ACH, in any folder. Without a / only the file name is compared.
**/ACH*.txtThe same, written differently.
data/*.txt.txt files in data/ under the folder that holds .fixedwidth.
*.{txt,dat}Either .txt or .dat.
["A*.txt", "B*.txt"]An array: any match applies the layout.

Matching ignores case. Supported: *, **, ?, [abc], [!abc], {a,b}.

pos 3File-level settings

The top level of a layout describes the whole file:

KeyMeaningDefault
namerequiredLayout name, shown in the status bar.—
filePatternFile names to match automatically: a string or an array (see above). Without it the layout can only be chosen by hand.—
encodingutf-8, big5 or ms950. Taiwanese bank files are usually big5 / ms950.utf-8
lengthUnitbyte or char. See bytes vs characters.byte for big5 / ms950, char for utf-8
lineLengthRequired length of every line. Without it, lines are only checked to be long enough for every field.—
lineEndingRequired line ending: CRLF (Windows) or LF. Not checked when omitted.—
recordsrequiredThe record layouts; see the next section.—
crossChecksChecks across lines, such as "trailer count equals the number of details". See cross checks.—

pos 4Records: header, detail, trailer

Many files start with a header line (processing date, originator), continue with one detail line per item, and end with a trailer (total count, total amount), each with different fields. The first character usually tells them apart: 1 for header, 2 for detail, 3 for trailer.

records
"records": [
  {
    "type": "header",
    "when": { "start": 1, "length": 1, "equals": "1" },
    "position": "first",
    "fields": [ … ]
  },
  {
    "type": "detail",
    "when": { "start": 1, "length": 1, "equals": "2" },
    "fields": [ … ]
  },
  {
    "type": "trailer",
    "when": { "start": 1, "length": 1, "equals": "3" },
    "position": "last",
    "fields": [ … ]
  }
]
KeyMeaning
typerequiredRecord type. By convention header, detail and trailer, but any name such as H1 works.
whenHow to recognize the record: the length characters from position start equal equals. equals can be an array such as ["2", "4"]. Optional when there is only one record.
positionfirst: must be the first line; last: must be the last line.
requiredWhether every file must contain this record. Defaults to true with a position, false otherwise. When false, a missing record is fine and cross checks that use it are skipped.
labelLabel shown before each line. Defaults to Header / Detail / Trailer for header / detail / trailer, otherwise the type.
fieldsrequiredThe fields; see below.
Matching order: each line is compared with records from top to bottom and the first match is used. A record without when matches every line, so put it last. Lines that match nothing are labeled "Unknown" in red.

pos 5Template builder: all 7 combinations

Header, detail and trailer can be combined any way you like (details only, header + details, details + trailer… 7 in total). Tick the records your file has, and the layout below updates. Copy it, then adjust positions and lengths to your spec.

.fixedwidth/ach.json
  • With a single record type, no when is needed: every line uses it.
  • With both details and a trailer, two cross checks are added: trailer count = number of details, and trailer amount = sum of detail amounts.
  • This matches what "Create Schema from Template" generates inside VS Code.

pos 6Common field keys

KeyMeaning
namerequiredField name, shown in hovers, the status bar and table headers.
startrequiredStart position, counting from 1, in lengthUnit.
lengthrequiredLength.
typerequiredField type; see the next section.
requiredWhen true, the field cannot be all spaces.
descriptionText shown in the hover, e.g. "ROC year, month and day".
severityHow serious a problem in this field is: error (red), warning (yellow) or info (blue).
Tip: a spec that says "positions 56–68" becomes "start": 56, "length": 13 (68 − 56 + 1 = 13). Mistakes show up as overlapping fields or fields past lineLength.

pos 7The 8 field types

text Text

Any text, left-aligned and padded with spaces, such as names and addresses. Add pattern (a regular expression) to restrict it; trailing spaces are removed before matching.

Example
{ "name": "Name", "start": 16, "length": 40, "type": "text", "required": true }
{ "name": "Phone", "start": 56, "length": 10, "type": "text", "pattern": "^09\\d{8}$" }
Starts with a spaceDoes not match patternBlank but required

numeric Digits

Digits 0–9 only, right-aligned with leading zeros, such as account numbers and counts. Add "allowSpaces": true to allow space padding. The table view shows the raw text, so leading zeros are kept.

Example
{ "name": "Account", "start": 2, "length": 14, "type": "numeric" }
{ "name": "Serial", "start": 2, "length": 6, "type": "numeric", "allowSpaces": true }
Non-digit charactersSpaces insideAll blank

amount Amount

Digits with an implied decimal point: with "decimals": 2, 0000000150000 means 1,500.00. Add "signed": true for a +/- sign at the start or the end.

Example
{ "name": "Amount", "start": 56, "length": 13, "type": "amount", "decimals": 2 }
{ "name": "Adjustment", "start": 69, "length": 11, "type": "amount", "decimals": 0, "signed": true }
Decimal point or commaSign in the wrong placeAll blank

date Date

Checks the date really exists (February 30 is an error). Choose a format:

formatLengthExample
YYYYMMDD (default)820261020 = 2026-10-20
YYMMDD6261020 = 2026-10-20 (read as 20YY)
ROC_YYYMMDD71151020 = ROC year 115, October 20 (2026-10-20)
Example
{ "name": "Debit date", "start": 79, "length": 7, "type": "date", "format": "ROC_YYYMMDD" }
Date does not existLength does not fit the formatROC year 0

A blank date is not an error; add "required": true if one must be present.

enum Code list

The value must be one of a list, such as a record type or transaction code. Surrounding spaces are ignored.

Example
{ "name": "Record type", "start": 1, "length": 1, "type": "enum", "values": ["2"] }
{ "name": "Transaction code", "start": 2, "length": 2, "type": "enum", "values": ["01", "02", "05"] }
Value not in the list

twid Taiwan national ID

One uppercase letter followed by 9 digits, with the check digit verified. The second character can be 1 or 2 (national ID) or 8 or 9 (new resident certificate).

Example
{ "name": "National ID", "start": 69, "length": 10, "type": "twid" }
Wrong formatWrong check digit

twbiz Taiwan business ID

8 digits with the check digit verified, including the special rule when the 7th digit is 7.

Example
{ "name": "Originator business ID", "start": 10, "length": 8, "type": "twbiz" }
Not 8 digitsWrong check digit

filler Filler

Reserved space in the spec. By default it must be all spaces or all zeros; use fillChar to allow one specific character.

Example
{ "name": "Filler", "start": 86, "length": 165, "type": "filler" }
{ "name": "Padding", "start": 31, "length": 20, "type": "filler", "fillChar": "*" }
Contains other text (warning)

pos 8Cross checks

Check that numbers on different lines agree. Fields are referenced as "recordType.fieldName".

crossChecks
"crossChecks": [
  { "rule": "count", "record": "detail", "equals": "trailer.Total count" },
  { "rule": "sum", "field": "detail.Amount", "equals": "trailer.Total amount" }
]
ruleMeaningKeys
countThe number of records of a type must equal a valuerecord: the type to count; equals: "recordType.fieldName" or a number
sumThe total of an amount field must equal a valuefield: "recordType.fieldName"; equals: as above
  • equals can be a plain number, e.g. exactly 100 lines per file: "equals": 100.
  • Add severity to change how serious a mismatch is.
  • If the referenced record has "required": false and is absent, the check is skipped.
  • Malformed amounts are left out of a sum, and the message says how many.

pos 9Bytes vs characters: Big5 Chinese takes 2

Most Taiwanese bank files use Big5 (MS950), and their specs count bytes: 1 for ASCII, 2 for each Chinese character. So the 3-character name 王小明 takes 6 positions.

200…王小明␣␣

Each box is one byte. A Chinese character takes two, so a 40-byte name field holds 20 Chinese characters.

  • For Big5 / MS950 files set "encoding": "big5"; lengthUnit becomes byte automatically.
  • If a field boundary lands in the middle of a Chinese character you get "Field boundary splits a character", which usually means an earlier field is one byte too long or too short.
  • VS Code opens files as UTF-8 by default, which garbles Big5. The extension notices and offers "Reopen as BIG5". To avoid it for good, set "files.encoding": "cp950" (preferably only for that workspace).
  • For UTF-8 files whose spec counts characters, set "encoding": "utf-8" (lengthUnit defaults to char).

pos 10Extension settings

Search for "Fixed-Width Inspector" in VS Code settings (⌘,), or put these in settings.json:

settings.json
{
  "fixedWidthInspector.enabled": true,
  "fixedWidthInspector.language": "auto",
  "fixedWidthInspector.schemaPaths": [".fixedwidth"],
  "fixedWidthInspector.fieldColors": [
    "rgba(59, 130, 246, 0.55)",
    "rgba(249, 115, 22, 0.55)",
    "rgba(34, 197, 94, 0.55)",
    "rgba(217, 70, 239, 0.55)"
  ],
  "fixedWidthInspector.showRecordLabels": true,
  "fixedWidthInspector.highlightCurrentField": true,
  "fixedWidthInspector.maxDiagnostics": 1000,
  "fixedWidthInspector.debounceMs": 300
}
SettingMeaning
enabledTurn the extension on or off.
languageUI language: auto follows VS Code, en English, zh-tw Traditional Chinese.
schemaPathsExtra layout folders, relative to the workspace or absolute. .fixedwidth/ next to the file is always searched.
fieldColorsField colors: 2–4 semi-transparent colors work best; higher alpha is more vivid.
showRecordLabelsShow the Header / Detail / Trailer label before each line.
highlightCurrentFieldOutline the field under the cursor, so you can find your place among the colors.
maxDiagnosticsMaximum problems listed in the Problems panel; the status bar says when there are more.
debounceMsDelay in milliseconds before re-checking after an edit.

Commands

Press ⇧⌘P and type "Fixed-Width":

CommandWhat it does
Select SchemaChoose a layout for the current file, go back to automatic matching, or pick a file.
Validate FileRe-check the whole file and report how many problems there are.
Toggle HighlightingTurn field colors on or off for now.
Create Schema from TemplateTick a record combination and create a sample layout next to the file.
Reopen with Schema EncodingReopen with the layout's encoding (fixes garbled text).
Show as TableOpen the table view.
Export as CSVExport one record type as a CSV that Excel opens correctly.

pos 11Problem codes

The code after each message in the Problems panel tells you the kind of problem:

CodeMeaning
line.lengthWrong line length, or too short to hold every field.
line.unknownRecordThe line matches no record's when.
line.positionHeader not on the first line, or trailer not on the last.
line.missingRecordA required record never appears.
line.endingLine endings differ from lineEnding.
line.encodingUndecodable characters; the file may be open with the wrong encoding.
field.splitCharA field boundary splits a double-byte character.
requiredA required field is blank.
text.*, numeric.*, amount.*, date.*, enum.*, filler.*The content breaks the field type's rules.
twid.invalid, twbiz.invalidWrong ID format or check digit.
cross.count, cross.sumA cross check's count or total does not match.

pos 12FAQ

No colors when I open the file?

  • Check the status bar. "No schema" means no layout matched: make sure .fixedwidth is in the file's folder or a parent, and the file name matches filePattern.
  • If the layout itself has a mistake (missing name, misspelled type…), the Problems panel says where.
  • You can also click the status bar and choose a layout file directly.

Chinese text is garbled?

The file is Big5 but was opened as UTF-8. Run "Reopen with Schema Encoding", or click "UTF-8" in the status bar and choose "Traditional Chinese (Big5)".

Everything after one field is shifted?

Usually an earlier field's length is wrong in the layout, or that line really has one byte too many or too few. Look for line.length or field.splitChar on that line.

Colored fields look different widths?

That is expected. Chinese characters are drawn two columns wide, so fields with the same byte length can look wider or narrower. Hover to see the real position and length.

Will Excel drop leading zeros from exported account numbers?

No. Numeric fields are written as ="000123", which Excel keeps as text, and the CSV starts with a BOM so Chinese displays correctly.

Can I share layouts with my team?

Yes. Layouts are plain JSON files: commit them or put them in a shared folder and point schemaPaths at it.