優秀的第三方元件往往功能完備,卻難以 100% 符合專案特殊需求。與其重造輪子,不如深入原始碼,在關鍵節點「植入」自訂邏輯。本文以免費 CSV 匯入元件 TPgCSV 為例,示範如何透過三項微調:新增事件攔截原始列字串、植入 AfterInsert 事件注入額外欄位、新增 CSVRecordCount 屬性支援進度條,將通用元件改造成貼合專案的利器。
Max),元件無 RecordCount 屬性元件將匯入邏輯封裝於 CSVToDataSet 方法,核心迴圈逐列讀取、解析、Append、Post。原始碼未對外開放「列字串預處理」與「新增記錄後」的介入點。
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;
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 事件,雙擊即可撰寫清洗邏輯(如正規表示式替換、欄位重組)。
DataSet 參數):type
TPgCSVAfterInsertEvent = procedure(Sender: TObject; DataSet: TDataSet) of object;
FDataset.Append 緊接之後插入:try
FDataset.Append;
// ★ 新增:讓使用者對新記錄填入額外欄位
if Assigned(FAfterInsert) then
FAfterInsert(Self, FDataset);
// ... 後續欄位賦值與 Post
使用者即可在事件中寫入:DataSet.FieldByName('BookType').AsString := FBookType; 等邏輯,避免在資料模組分散處理。
private
FCSVRecordCount: Integer;
published
property CSVRecordCount: Integer read FCSVRecordCount default 0;
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;
原始碼修改不超過 30 行,卻解決四大專案痛點。下次遇到「差一點就能用」的元件,不妨嘗試打開原始碼,為它加上屬於你的介面。