首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 元件「拿來改」實戰:擴充 TPgCSV 實現異常紀錄、進度條與自訂欄位注入

     編輯:Delphi

優秀的第三方元件往往功能完備,卻難以 100% 符合專案特殊需求。與其重造輪子,不如深入原始碼,在關鍵節點「植入」自訂邏輯。本文以免費 CSV 匯入元件 TPgCSV 為例,示範如何透過三項微調:新增事件攔截原始列字串、植入 AfterInsert 事件注入額外欄位、新增 CSVRecordCount 屬性支援進度條,將通用元件改造成貼合專案的利器。

專案需求與元件缺口

  • 來源資料:圖書館 ISO 格式文字檔,欄位分隔符不固定、含特殊字元
  • 需求 1:匯入前預處理每一列字串(清洗格式)
  • 需求 2:匯入失敗不拋出例外,寫入錯誤日誌並繼續
  • 需求 3:進度條需知總筆數(Max),元件無 RecordCount 屬性
  • 需求 4:資料表含「書別、期號、流水號」等非來源檔欄位,匯入時自動帶入

TPgCSV 核心架構速覽

元件將匯入邏輯封裝於 CSVToDataSet 方法,核心迴圈逐列讀取、解析、Append、Post。原始碼未對外開放「列字串預處理」與「新增記錄後」的介入點。

改造一:新增 OnRegulateString 事件攔截原始列

  1. 於型別宣告區新增事件型別與屬性:
type
  TPgCSVRegulateStrEvent = procedure(Sender: TObject; var ARecordString: string) of object;

  TPgCSV = class(TComponent)
  private
    FRegulateString: TPgCSVRegulateStrEvent;
  published
    property RegulateString: TPgCSVRegulateStrEvent read FRegulateString write FRegulateString;
  end;
  1. 在 CSVToDataSet 核心迴圈 Readln 後插入呼叫:
while (not Eof(FFile)) and (not FStop) do begin
  Readln(FFile, RecordString);
  // ★ 新增:讓使用者預處理原始字串
  if Assigned(FRegulateString) then
    FRegulateString(Self, RecordString);
  // ... 後續原本解析邏輯
end;

重新編譯封裝後,Object Inspector 即出現 RegulateString 事件,雙擊即可撰寫清洗邏輯(如正規表示式替換、欄位重組)。

改造二:新增 OnAfterInsert 事件注入額外欄位

  1. 宣告事件型別(需傳遞 DataSet 參數):
type
  TPgCSVAfterInsertEvent = procedure(Sender: TObject; DataSet: TDataSet) of object;
  1. 於 FDataset.Append 緊接之後插入:
try
  FDataset.Append;
  // ★ 新增:讓使用者對新記錄填入額外欄位
  if Assigned(FAfterInsert) then
    FAfterInsert(Self, FDataset);
  // ... 後續欄位賦值與 Post

使用者即可在事件中寫入:DataSet.FieldByName('BookType').AsString := FBookType; 等邏輯,避免在資料模組分散處理。

改造三:新增 CSVRecordCount 唯讀屬性支援進度條

  1. 宣告私有欄位與屬性:
private
  FCSVRecordCount: Integer;
published
  property CSVRecordCount: Integer read FCSVRecordCount default 0;
  1. 將 CSVFile 屬性改為寫入器,於設定檔名時掃描行數:
property CSVFile: string read FCSVFile write SetCSVFile;

procedure TPgCSV.SetCSVFile(const Value: string);
var
  F1: TextFile;
  iCount: Integer;
begin
  if FCSVFile <> Value then begin
    FCSVFile := Value;
    if FileExists(Value) then begin
      AssignFile(F1, Value);
      Reset(F1);
      iCount := 0;
      while not Eof(F1) do begin
        Readln(F1);
        Inc(iCount);
      end;
      CloseFile(F1);
      FCSVRecordCount := iCount;
    end;
  end;
end;

主程式匯入前即可:

ProgressBar1.Min := 0;
ProgressBar1.Max := PgCSV1.CSVRecordCount;

實務心得

  • TPgCSV 原始碼結構單純,修改風險低;複雜元件(涉及 VCL 核心、多重繼承)修改時需極謹慎
  • 「拿來改」精髓在於:識別核心流程 → 找尋/植入擴充點 → 最小化修改 → 重新編譯封裝
  • 所有修改均在 Delphi 6.0 / Win98 驗證通過,實際專案穩定運行數月

原始碼修改不超過 30 行,卻解決四大專案痛點。下次遇到「差一點就能用」的元件,不妨嘗試打開原始碼,為它加上屬於你的介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved