---
# System prepended metadata

title: TMEIC 程式AP
tags: [宥倍]

---

# TMEIC 程式AP
###### tags: `公司` `TMEIC`

HR
FM
紅色量測器

黑皮鋼捲 > 除鏽 > 冷壓鋼捲

00000118232A01324H0100
00000118L3P06125402300




CSV路徑格式化 - 將資料來源的檔案路徑、名稱格式，設定至SQL資料庫TB_Parameter裡



# 架構
![](https://i.imgur.com/BrWe0jn.jpg)
![](https://i.imgur.com/ldJuT9K.jpg)
![](https://i.imgur.com/f5nnEVj.jpg)
![](https://i.imgur.com/F8CI8aA.png)


# AP
### IFC_Mill - 鋼捲
r_SPCQu - 預處理
### IFC_PDS - CSV DCA處理TB_Define_Csv、TB_Define_DCA

TB_Define_Csv - 指定CSV丟進指定資料表、欄位名稱
![](https://i.imgur.com/NwYwPr9.png)

TB_Define_DCA 欄位命名、資料存在哪裡、欄位顯示名稱、CSV_LEN對照鋼捲的位置、哪個檔案的哪個欄位
![](https://i.imgur.com/EoiAwJ5.png)

#### PDIConverter.cs 145
IFC_PDS.SocketHandler.SendTcpMessage(Payload, ref Acknowledge, ref ErrorMessage); 連接Server

<---
[ALARM] (00001) #03-08 15:26:15.78603 --->
The TCP client failed to start.
<---

#### TB_Parameter 可設定資料位置
![](https://i.imgur.com/lPvdaiA.png)


### SPC_CALC - Band超出幾% 品質評估等
DCA 連續鋼捲 會查看是否有Band
PDI 找出標準在哪裡
![](https://i.imgur.com/3vXFK0V.png)

### SPC_DFCT - 鋼鐵廠會定義缺陷代碼
如果鋼捲符合缺陷代碼，該進行怎樣的處理
從Band的資料 給缺陷代碼去做對比
並進行缺陷代碼的處理
![](https://i.imgur.com/Z0r3oJV.png)

### SPC_STAT - 鋼捲整段Band 連續資料 統計這禮拜
從到各個資料表
每個鋼捲做完 從到這裡面
![](https://i.imgur.com/JEiX2SY.png)

定義位置
![](https://i.imgur.com/LzGGDaF.png)

# SPC_CALC
## 簡述流程

這段代碼實現了一個C＃的控制台應用程序，該應用程序對捲進行質量分析。它使用Castle.DynamicProxy庫生成代理以實現AOP（面向切面編程）。

代碼創建了Castle.DynamicProxy庫中ProxyGenerator類的實例，該類在運行時生成對象的代理。然後，它創建了LogInterceptor類的實例，該類實現了Castle.DynamicProxy庫的攔截器接口，並為應用程序提供了日誌功能。

接下來，代碼創建了一個IAnalysis對象列表，其唯一元素是使用ProxyGenerator和LogInterceptor實例代理的BandAnalysis類。

然後，代碼進入了一個無限循環，在循環中，它設置日誌記錄實例的文件名和日期/時間，調用分析器的Pre()方法，檢查分析器是否有任何卷需要分析，如果有捲就執行分析，調用Post()方法，移動日誌文件，並等待10秒後再次循環。

最後，代碼設置等待日誌移動完成的時間，寫入一個指示SPC_CALC已完成的信息日誌，並退出應用程序。在應用程序退出之前，關閉日誌實例。

## 對應Class
* LogInterceptor 是用來攔截日誌信息的類。
* BandAnalysis 是繼承了 IAnalysis 接口的類，是一個用來分析數據的類。
* IAnalysis 是一個接口，被 BandAnalysis 實現，表示該類是一個分析數據的類。
* LogMover 類用來移動日誌信息。
* LogRecord 類用來記錄日誌信息。
* ProxyGenerator 類是 DynamicProxy 庫中的一個類，用來生成代理類的實例。

## 流程圖
```flow
st=>start: Start
e=>end: End
loop=>condition: Do-While Loop| aa
check=>condition: Check for "HasCoil"
pre_analysis=>operation: Pre-Analysis
execute_analysis=>operation: Execute Analysis
post_analysis=>operation: Post-Analysis
move_log=>operation: Move Log
sleep=>operation: Sleep
finally=>operation: Finally

st->loop
loop(yes)->check
check(yes)->pre_analysis->execute_analysis->post_analysis->move_log->sleep
check(no)->sleep
sleep->loop
loop(no)->finally->e
```
## 問題
* 無限循環 是如何跳出
* foreach 不就只會執行第一個物件?
* 41 42 那兩行是否不會執行

# Shared
## LogInterceptor - 攔截日誌信息
### 簡述流程
這段程式的主要用途是為某些方法進行拦截，記錄方法的輸入參數、運行時間、運行結果、運行結束後的返回值，並對異常進行記錄。
具體的，它是一個用 Castle.DynamicProxy 庫中的 StandardInterceptor 類的派生類，主要实现了四個方法：PreProceed、PerformProceed、PostProceed 以及一個靜態的 LogRecord 實例，用來記錄各種信息。

---

這是一個使用 Castle DynamicProxy 套件的攔截器，用於記錄呼叫方法的相關資訊。攔截器類別繼承自 StandardInterceptor，其中重寫了 PreProceed、PerformProceed、PostProceed 三個方法，以實現攔截的功能。

PreProceed 方法中，首先呼叫 LogRecord.SetFileNameWihoutPieceInfo() 設定檔案名稱，然後檢查方法的參數是否存在。如果存在，則逐一記錄每個參數的資訊，包括參數類型和值。

PerformProceed 方法中，呼叫 LogRecord.SetFileNameWihoutPieceInfo() 設定檔案名稱，並使用 Stopwatch 類別計算方法呼叫的時間，並在呼叫完畢後，記錄該方法已成功執行的相關資訊。如果方法呼叫期間拋出了例外，則使用 LogRecord.AlertException 方法記錄該例外，並在程式退出之前等待記錄文件移動完成。

PostProceed 方法中，首先呼叫 LogRecord.SetFileNameWihoutPieceInfo() 設定檔案名稱，然後檢查方法是否有返回值，如果有，則記錄返回值的資訊。

* PreProceed 方法：在执行其他操作之前，该方法会记录方法的参数。
* PerformProceed 方法：该方法记录方法的开始时间，并调用基类的 PerformProceed 方法。如果有异常，则会记录异常信息。
* PostProceed 方法：该方法会在执行完其他操作后，记录方法的返回值。

### 對應Class
* Castle.DynamicProxy.StandardInterceptor：這是一個 DynamicProxy 中的標準攔截器，LogInterceptor 繼承自它。

* Frame.Utility.LogRecord：這是一個用來記錄日誌的類別，LogInterceptor 利用這個類別來寫日誌。
* System.Diagnostics.Stopwatch：這是一個用來計算時間的類別，LogInterceptor 利用這個類別來記錄方法執行時間。
* System.Threading.Thread：這是一個用來實現多執行緒的類別，在 LogInterceptor 中未使用。
* System.Environment：這是一個用來獲取或設置環境變數的類別，LogInterceptor 利用這個類別來退出程式。

# QualityAnalysis

## IAnalysis - 分析數據 - 接口

### 簡述
* MovedPieces：一個 List 類型的屬性，代表移動過的棋子資訊。
* HasCoil：一個布林型的屬性，代表是否有繞線。
* Pre、Execute、Post：三個方法，分別用於在解析前、執行解析、以及解析後的執行。

## BandAnalysis - 鋼帶分析
### 簡述
1. 這是一個 C# 實現的鋼帶分析類。
1. 用於分析每個鋼帶的質量。
1. 定義了 Pre() 和 Execute() 方法，分別用於預處理和執行分析。
1. 使用 Castle.DynamicProxy 類庫生成代理對象進行記錄和錯誤捕獲。
1. Pre() 方法將所有鋼帶初始化並獲取相關信息，如計算流程、队列信息。
1. 將所有鋼帶和相應信息存入字典。
1. Execute() 方法循環遍歷每個鋼帶進行分析。
1. Post 方法是一個虛擬方法，它的主要作用是將鋼帶分析類的執行結果進行後處理。

### Class 屬性細說
* CoilList：需要進行分析的Coil物件的列表。
* Generator：Castle.DynamicProxy.ProxyGenerator的實例。
* LogInterceptor：LogInterceptor的實例。
* CpkAnalysis：CpkAnalysis的實例。
* HasCoil：布爾屬性，表示CoilList是否為空。
* MovedPieces：MovedPieceInfo物件的列表。
* CoilHelper：CoilHelper的實例。
* CoilInfoMap：將Coil物件映射到Info物件的字典。

該類具有多種執行各種任務的方法：
* SetProxy：設置generator、logInterceptor和cpkAnalysis屬性的值。
* Init：將CoilList設置為null並創建一個新的CoilInfoMap實例。
* Pre：檢索鋼捲的列表，檢索有關每個鋼捲的信息，例如其計算流、隊列信息和定義數據，並將鋼捲及其信息添加到CoilInfoMap中。
* Execute：在CoilList中的每個鋼捲上實際進行分析。
* Post：根據分析的結果更新每個鋼捲的狀態。

### 對應Class
* Castle.DynamicProxy.ProxyGenerator（generator 屬性）
* LogInterceptor（logInterceptor 屬性）
* CpkAnalysis（cpkAnalysis 屬性）
* MovedPieceInfo（MovedPieces 屬性）
* CoilHelper（coilHelper 屬性）
* Coil 類別和 Info 類別，將它們映射到 CoilInfoMap 字典中。

## CpkAnalysis - 分析CA/CP的質量

### 簡述
這個程式碼是定義了一個類別 CpkAnalysis，這個類別是一個實現了介面 IAnalysis 的物件，它是用來進行分析 "每個質量的 CA 和 CP"。

這個類別提供了一些可以存取的屬性，例如：CoilList、CoilInfoMap、HasCoil 和 MovedPieces，分別存放捲狀物、捲狀物的資訊的映射、是否有捲狀物以及移動的物品的資訊。

還有一個設定代理的方法 SetProxy()，這個方法會初始化一些物件：generator、logInterceptor 和 ratioAnalysis。

它提供了三個介面方法：

Pre() 方法：預先設定一些物件。
Execute() 方法：分析每一個捲狀物的資訊，並使用 CoilCpk 類別計算每一個質量的 CA 和 CP，如果分析失敗將記錄錯誤，最終將結果儲存在 CoilInfoMap 中。
Post() 方法：呼叫比率分析，進行分析。


### 對應Class
* Coil類別：這個類別是為了分析的對象，而對每個Coil物件進行分析。
* Info類別：這個類別存放關於每個Coil物件的資訊。
* ProxyGenerator類別：這個類別是一個由Castle.DynamicProxy庫提供的類別，可用於創建代理對象。
* LogInterceptor類別：這個類別是用於在分析過程中捕獲日誌訊息的類別。
* RatioAnalysis類別：這個類別是為了分析每個Coil物件的比率，以得到最終結果。
* CoilCpk類別：這個類別是用於分析每個Coil物件的Cpk值的類別。
* DefineData類別：這個類別存放分析的定義資訊。
* Data類別：這個類別存放分析所需的資料。
* QueueInfo類別：這個類別存放關於狀態的資訊。
* QueueState類別：這個類別代表狀態的類型。
* ResultRecord類別：這個類別存放分析的結果。


## Coil - 鋼捲
### HistoryKeyTm
存儲了一個字符串，表示 HistoryKeyTm 時間。
### PieceTime
存儲了一個 DateTime 物件，表示 Piece Time（卸料時間）。
### PieceTimeText
存儲了一個字符串，表示 Piece Time，其內容為 PieceTime 轉換為 "yyyy-MM-dd HH:mm:ss.fff" 格式的字符串。
### WorkDate
存儲了一個字符串，表示工作日期。
### PieceID
存儲了一個字符串，表示 Piece Id。
### CoilID
存儲了一個字符串，表示 Coil Id。
### OldWorkDate
存儲了一個字符串，表示舊的工作日期。
### ShiftNo 
存儲了一個整數，表示班次編號。
### Coil(DateTime pieceTime, string workDate, string pieceId, string coilId, string historyKeyTm)
類別還定義了一個帶有 5 個參數的建構函數，它會利用這 5 個參數初始化每個屬性的值，並給它們賦值。

### ToString(): 
最後，Coil 類別重寫了 ToString 方法，當呼叫 ToString 方法時會回傳一個字符串，內容是 PieceID, CoilID, PieceTime, WorkDate, HistoryKeyTm 的值，每個值之間用逗號隔開。

## Info - 資料容器
這個 Info 類別沒有任何方法，僅是一個資料容器，用來儲存計算流程，資料定義，隊列訊息以及其他數據等資訊。

### CalculationFlow
類型為 CalculationFlow 的狀態機
### Defines
類型為 DefineData
### QueueInfo
類型為 QueueInfo
### Data
類型為 Data
### ResultRecord
類型為 ResultRecord，並初始化為 ResultRecord 的新實例。

## Enum - 儲存所有狀態機
### Section
定義帶狀物的三個部分：頭部，中間和尾部。
### QueueState
定義佇列的狀態。可能會是一般錯誤，PDI 為空，樣本數據為空或規格不合格。
### BandState
定義帶狀物的狀態，可能會是一般錯誤，PDI 為空，樣本數據為空或規格不合格。
### CalculationState
定義計算的狀態，可能會等待計算，跳過，完成或中止。
### CalculationFlow
定義計算流程，可以是試驗或正式。
### QualityType
定義質量類型，包括厚度，寬度，RMDT，FMDT，CT，平坦度，冠狀和楔形。


## Define - 存儲定義的信息
### 敘述
Define 類別是程式碼的核心類別，主要記錄質量類型、帶寬表名稱、BandDefineInfo、DividerDefineInfo 和 SampleData 等資訊。Define 的實例可以通過提供 QualityType、帶寬表名稱、分析器、信號、分割器和是否分析的標誌來創建。

DefineData 類別是用侹框数据的一个包装类，包含一个 Define 对象的各种属性，如 Thick、Width、RDT、FDT、CT、Flat、Crown 和 Wedge。

QualityType 類別是一個枚舉類別，它包含質量類型的可能值，如 Thickness、Width、RDT、FDT、CT、Flat、Crown 和 Wedge。

BandDefineInfo 類別記錄帶寬表的相關信息，如帶寬表名稱、信號、是否分析、分析器等。

DividerDefineInfo 類別記錄分割器的相關信息，如分割器名稱。

通過使用上面的類別，程式碼實現了對細微性質相關資訊的存儲和記錄。

### Define Class
程式碼的核心類別，主要記錄質量類型、帶寬表名稱、BandDefineInfo、DividerDefineInfo 和 SampleData 等資訊。Define 的實例可以通過提供 QualityType、帶寬表名稱、分析器、信號、分割器和是否分析的標誌來創建。

### DefineData
用侹框数据的一个包装类，包含一个 Define 对象的各种属性，如 Thick、Width、RDT、FDT、CT、Flat、Crown 和 Wedge。

### QualityType - 枚舉類別
它包含質量類型的可能值，如 Thickness、Width、RDT、FDT、CT、Flat、Crown 和 Wedge。

BandDefineInfo 類別記錄帶寬表的相關信息，如帶寬表名稱、信號、是否分析、分析器等。

DividerDefineInfo 類別記錄分割器的相關信息，如分割器名稱。

通過使用上面的類別，程式碼實現了對細微性質相關資訊的存儲和記錄。









