程式資訊
- 程式 ID:
PROGRAMCLASS - 所屬子系統:L.聯絡傳訊
- 狀態:stable
程式類別代碼(ProgramClass)¶
本頁是開發者/系統參考,不是操作畫面
ProgramClass 是一份集中在程式碼裡的程式代碼清單(Common/ProgramClass.cs),不是一支可以開啟、輸入資料的表單。系統並沒有提供「程式類別維護」的操作視窗——它沒有對應的 ViewModel、XAML 或 BLL。本頁說明這份清單的用途、它如何把一支功能跟「選單/權限/查詢 SP/超連結」串起來,以及維護人員新增功能時要怎麼登錄。一般終端使用者不會直接接觸到它。
功能簡介¶
ProgramClass(程式類別)是 TsERP 用來唯一識別每一支程式(表單/報表/工具)的字串代碼。系統內幾乎每一支可開啟的程式,都對應一個 ProgramClass(例如銷售訂單是 ORMAST、生產計劃查詢是 PRODUCTIONPLAN、公告通知是 COMMPR)。這個代碼本身只是一個名字,但它是許多子系統共用的「主鍵」:
- 選單:主選單上每個項目記的就是它的
ProgramClass,用來決定點下去要開哪支程式。 - 權限:使用者權限是按
ProgramClass.Name一支一支授權(瀏覽/新增/修改/刪除/列印…)。 - 查詢 SP:查詢頁要呼叫哪一支 stored procedure,是用
ProgramClass.Name去proc_param登錄表查出來的。 - 超連結:跨單據的點選跳轉(HyperLink)以
ProgramClass.Name當目標程式識別。 - 其他:報表、行事曆事件類別、AutoPilot 排程任務等,也都用同一組代碼識別。
維護人員與開發者會用到這份清單;終端使用者只會間接受惠(點選單、被授權、按超連結時,背後都是這份代碼在運作)。
程式碼位置與結構¶
這份清單定義在 Common/ProgramClass.cs,是一個 C# 類別,內容是一長串靜態欄位宣告,每一行就是一個程式代碼:
public static ProgramClass ORMAST = new ProgramClass(); // 銷售訂單
public static ProgramClass COMMPR = new ProgramClass(); // 公告通知
public static ProgramClass PRODUCTIONPLAN = new ProgramClass(); // 生產計劃查詢
它的運作機制有三個重點:
- 代碼名稱=欄位名稱。建構子用
[CallerMemberName]自動把欄位名(如ORMAST)抓進Name屬性,所以ProgramClass.ORMAST.Name就是字串"ORMAST",不需要另外手寫一次字串。 - 集中查找表。每個代碼在建構時會自己登記進一個內部字典
_lookup,提供ProgramClass.TryParse("ORMAST", out var p)由字串反查回物件——選單、超連結、導覽參數都靠它把資料庫裡存的字串還原成程式物件。 - 以群組分區。檔案用
#region(如M.EIS、schedule)與註解把代碼分群,方便維護人員定位。少數代碼上方有<summary>XML 註解補充用途(例如INVENT1註明「產品序號表(保固卡)」、EISDASH註明「主管儀表板」)。
代碼名稱不可隨意更名或重排順序
代碼的 Name(=欄位名)會被寫進資料庫的選單、權限、proc_param、超連結紀錄等。一旦改名,舊資料就對不上、權限與查詢會失效。新增請往後加;既有代碼名稱請當成不可變更的契約。
一支程式如何「掛上」它的 ProgramClass¶
當開發者寫一支新表單的 ViewModel 時,會 override ProgramClass 屬性指向這份清單裡的代碼,例如:
public override ProgramClass ProgramClass => ProgramClass.WKPAPER;
之後框架就用這個屬性的 .Name(即 "WKPAPER")去做權限檢查、查詢 SP 解析、超連結比對等。換句話說:
- 沒有在
Common/ProgramClass.cs宣告代碼 → ViewModel 無法 override → 這支程式無法被選單、權限、查詢系統正確識別。 - 宣告了代碼但沒有任何 ViewModel 使用它 → 這個代碼目前是「保留/未啟用」狀態(檔內有多筆標
//系統保留,例如Login、Menu、ATTACHMENT等基礎機制用代碼)。
維護步驟(新增一支程式時)¶
這是給開發/維護人員的流程,不是終端使用者操作
新增一支新功能、要讓它能進選單並被權限與查詢系統認得時,通常依序:
-
在
Common/ProgramClass.cs適當的#region區段內,往後新增一行靜態欄位宣告(命名用大寫英文代碼,與該功能既有 VFP/資料庫代碼一致):public static ProgramClass MYFORM = new ProgramClass(); // 我的新表單 -
在新表單的 ViewModel override
ProgramClass屬性指向它:public override ProgramClass ProgramClass => ProgramClass.MYFORM; -
在主選單/程式清單登錄這個代碼,使用者才看得到入口(這步在系統設定/資料庫端,不在本檔)。
- 在權限設定對需要的角色開放此
ProgramClass(瀏覽/新增/修改/刪除/列印)。 - 若該程式有查詢頁,須在
proc_param登錄表把ProgramClass.Name對應到要呼叫的查詢 SP,否則查詢會找不到 SP 而靜默回空。
代碼命名慣例
主檔/單據用主表英文名(ORMAST、PURCH);列印頁在主代碼後加 PRINT(PURCHPRINT、SLIYPRINT);查詢報表常見 XXX_QRY1/REC_QRY0 之類的編號;轉單/轉傳票工具常見「來源 TO 目的」型(ODTOSA、PUTORA、WKTOMP)。新增時請沿用同模組的既有風格。
欄位說明(清單項目的組成)¶
清單裡每一筆「項目」其實就是一個靜態欄位。一個 ProgramClass 物件對外只暴露一個屬性:
| 欄位 | 說明/格式/預設 |
|---|---|
| Name | 程式代碼字串,唯讀。自動等於欄位名稱(透過 [CallerMemberName]),不需手填。例:ProgramClass.COMMPR.Name → "COMMPR"。ToString() 也回傳此值。 |
延伸搭配(不是 ProgramClass 自己的欄位,而是其他資料表用 Name 去對應的內容):
| 對應資料 | 由哪裡提供 | 說明 |
|---|---|---|
| 選單/程式清單 | NavigateProgramParameters.ProgramClass(字串) |
選單項目存的就是代碼字串;ProgramClassEnum 屬性用 TryParse 把它還原成物件 |
| 權限 | 權限設定表,以 ProgramClass.Name 為主鍵 |
一支程式一筆權限,分瀏覽/新增/修改/刪除/列印等動作 |
| 查詢 SP | proc_param 登錄表 |
SheetNoMethod.GetQueryProcedure(programClass) 以代碼查出要跑的查詢 SP |
| 多語系翻譯 | LanguageService.GetTranslateText(ProgramClass.Name, key) |
以代碼為命名空間查欄位/訊息的中英對照 |
欄位連動與附加功能¶
這份清單沒有「輸入欄位後重算」之類的畫面互動(它不是表單)。但它在程式碼層面有幾個重要的連動行為,維護時務必了解:
-
改了欄位名,等於改了整個系統的識別主鍵。代碼的
Name會散落在資料庫的選單、權限、proc_param、超連結、行事曆事件等多張表。所以新增代碼用「往後加」,不要更名、不要刪除、不要調整既有順序語意——順序本身不影響功能(靠字典查找),但把既有代碼改名會讓舊資料對不上。 -
TryParse反查決定字串能不能變回程式。當系統從資料庫讀到一個程式代碼字串(例如超連結要跳到ORMAST),會呼叫ProgramClass.TryParse("ORMAST", out var p)。若清單裡沒有這個代碼,反查失敗,超連結會回報「No valid program class found.」、導覽參數的ProgramClassEnum會是null。所以資料庫裡用到的代碼,清單裡一定要有對應宣告。 -
超連結跳轉以代碼為目標。跨單據點選跳轉(HyperLink)時,
HyperLinkExecute(programClass, …)先TryParse驗證代碼存在(反查不到就回「No valid program class found.」),再用CanHyperLink檢查使用者對該代碼有沒有權限(沒權限即回「無權限執行此程式」並中止)。權限通過後若該代碼還沒在目前系統的程式清單中(CheckIsInSystem為否),會先把它加進上方選單列(AddProgram)再切頁——也就是說,真正會擋住跳轉的是「代碼不存在」或「沒有權限」,而不是「沒掛在選單上」。 -
ViewModel override 決定權限與查詢套用到哪支。框架用 ViewModel 的
ProgramClass屬性.Name去查權限、查查詢 SP、查翻譯。若兩支不同表單不小心 override 成同一個代碼,它們會共用同一筆權限與查詢設定(這通常是 bug,新增時要確認代碼唯一)。 -
保留代碼(
//系統保留)不要拿來當業務功能用。清單開頭有一批標註//系統保留的代碼(Login、Menu、Setting、TODOLIST、LIBRARY、ATTACHMENT、MESSAGE、TITLE等),它們是登入、選單、待辦、附件等基礎機制在用的。新增業務功能請另起新代碼,不要重用這些。 -
<summary>註解是給維護人員的線索。少數容易混淆的代碼有 XML 註解澄清用途,例如CLAIM註明「索賠單(保固卡索賠,與應收扣款ARCLAIM不同功能)」、CMPLAIN註明「抱怨單」。維護時遇到名稱相近的代碼,先看註解再動手,避免掛錯。
常見問題¶
為什麼開不起「程式類別」這個功能?選單裡找不到?
因為它不是一支可開啟的表單,只是程式碼裡的代碼清單(Common/ProgramClass.cs)。系統沒有提供「程式類別維護」的操作畫面,自然不會出現在選單。要查或改代碼,請開發人員直接編輯這個 .cs 檔。
新增了一支表單,但超連結/導覽跳不過去,回報「No valid program class found.」?
代表那個程式代碼字串在 ProgramClass 清單裡反查不到。請確認已在 Common/ProgramClass.cs 宣告對應代碼,且字串拼寫(大小寫)與資料庫/選單裡登錄的完全一致。TryParse 是大小寫敏感的精確比對。
查詢頁按了「查詢」卻一直回空,沒有錯誤?
代碼有宣告、表單也開得起來,但查詢 SP 沒登錄。查詢頁是用 ProgramClass.Name 去 proc_param 找要跑的 SP;若沒登錄,系統查不到 SP 就會靜默回空。請補登 proc_param 對應(這是新增查詢功能的必要步驟,常被遺漏)。
可以把某個代碼改名/刪掉,讓清單乾淨一點嗎?
不建議。代碼的 Name 會寫進資料庫的選單、權限、proc_param、超連結等多張表。改名或刪除會讓舊資料對不上,造成權限失效、查詢找不到 SP、超連結斷掉。確定某代碼完全沒在用才考慮移除,且要連同資料庫端一起清。
兩支表單的權限好像綁在一起,改一個另一個也變?
很可能兩支 ViewModel override ProgramClass 指到了同一個代碼。因為權限與查詢都是以 ProgramClass.Name 為主鍵,共用代碼就會共用設定。請讓每支表單各自宣告並使用唯一的代碼。
相關功能¶
- L 聯絡傳訊(模組首頁)
- 公告通知 Commpr
- 便條傳訊 Commprnote
- 信件檔 Letter
- A 系統資料(使用者帳號與權限設定)
- M 主管資訊(查詢報表,依賴 proc_param 的代表性模組)
需補截圖清單
本頁為開發者/系統參考,描述的是程式碼清單而非操作畫面,原則上不需要操作截圖。若日後要補圖輔助說明,建議補:
images/programclass-step1.png—Common/ProgramClass.cs程式碼節錄(展示靜態欄位宣告與#region分區)images/programclass-step2.png— ViewModel 中override ProgramClass的寫法範例