那我是不是可以直接拿來使用呢?這裡就出現問題了.
----問題一及解決方案
在該控件自帶的Demo中,所使用的文本數據文件,格式如下
test.csv
"11","12","13","14"
"21","22","23","24"
"31","32","33","34"
...
而ISO文件中的數據格式(部分)為
sm01632.ISO
... a7507310175-b特精裝-d¥1893"?1 -a毛澤東珍品典藏(上、下冊)-f中共中央文獻研究室編著?c中獻-d011200"...
...-a7119029193-b平裝- d¥20"?1 -a中國:加入WTO與經濟改革-f王 夢 奎編著? -c外文-d011200"? ... -
我們看到,同test.csv相比,sm01632.ISO文件中的紀錄很不規則。
我們所需要的是這樣的紀錄
sm01632.ISO
... 7507310175,特精裝,1893,1,毛澤東珍品典藏(上、下冊),中共中央文獻研究室編著,中獻,011200...
...-7119029193,平裝,20,1,中國:加入WTO與經濟改革,王 夢 奎編著,外文,011200? ... -
TPgCSV能否對這種情況進行自動的處理呢?哇噻,這種萬能的控件好像不大可能有吧!(事實上也不需要)既然直接用TPgCSV處理無法實現正確導入的,我們就需要在每一條從文件中讀取出來的紀錄導入數據庫之前,用程序對它們進行處理,轉換之後再交由TPgCSV進行操作。怎麼樣處理這裡就不贅述了。我們所關心的是TPgCSV有沒有開放出這樣一個處理的接口呢?
我們來看DataSetToCSV方法的實現代碼(主要是注釋部分):
procedure TPgCSV.CSVToDataSet;
var
RecordString,
Temp : string;
i : Integer;
C : LongInt;
D : Boolean;
F : Real;
ErrorResponse : TPgCSVErrorResponse;
Buffer : Pointer;
begin
//create fIEld cache
FFIEldCache:=TList.Create;
//initiate map items
FMapItems:=0;
//allocate buffer size
GetMem(Buffer,FBufferSize);
//assign and open CSV file
AssignFile(FFile,FCSVFile);
SetTextBuf(FFile,Buffer^,FBufferSize);
Reset(FFile);
//open table if nessecary
if FAutoOpen then
begin
if Assigned(FBeforeOpenTable) then
FBeforeOpenTable(Self);
FDataset.Open;
if Assigned(FAfterOpenTable) then
FAfterOpenTable(Self);
end;
//export to table from CSV file
if Assigned(FBeforeExport) then
FBeforeExport(Self);
//set the counter to zero
C:=0;
Temp:=ShortDateFormat;
ShortDateFormat:=FDateFormat;
{**********以下是文本數據導入的核心代碼部分,也是我要關心的部分********}
FDataset.DisableControls;
while (not Eof(FFile)) and (not FStop) do
begin
//read from CSV
Readln(FFile,RecordString);
//注意,這裡好像差了一點什麼東西
//add new record
try
FDataset.Append;
for i:=1 to CountMapItems do
if Uppercase(GetMapItem(i,D)) <> Uppercase(FIgnoreStr) then
case FDataset.FIEldByName(GetMapItem(i,D)).DataType of
ftInteger:
FDataset.FIEldByName(GetMapItem(i,D)).AsInteger:=
StrToIntDef(Trim(GetCSVRecordItem(i,RecordString)),FDefaultInt);
ftFloat:
begin
try
F:=StrToFloat(Trim(GetCSVRecordItem(i,RecordString)));
except
F:=FDefaultInt;
end;
FDataset.FIEldByName(GetMapItem(i,D)).AsFloat:=F;
end;
else
if FTrimData then
FDataset.FIEldByName(GetMapItem(i,D)).AsString:=
Trim(GetCSVRecordItem(i,RecordString))
else
FDataset.FIEldByName(GetMapItem(i,D)).AsString:=
GetCSVRecordItem(i,RecordString);
end;
//post record
FDataset.Post;
except
on E:Exception do
if not FSilentExport then
raise
else
if Assigned(FExportError) then
begin
FExportError(Self,E.Message,C,ErrorResponse);
if ErrorResponse = pgcsvAbort then
Break;
end;
end;
if Assigned(FOnAddRecord) then
FOnAddRecord(Self);
if Assigned(FExportProgress) then
FExportProgress(Self, C, FStop);
Inc(C);
end;
FDataset.EnableControls;
{************以上是文本數據導入的核心代碼部分**************}
if Assigned(FAfterExport) then
FAfterExport(Self);
//close table if nessecary
if FAutoOpen then
begin
if Assigned(FBeforeCloseTable) then
FBeforeCloseTable(Self);
FDataset.Close;
if Assigned(FAfterCloseTable) then
FAfterCloseTable(Self);
end;
//close CSV file
CloseFile(FFile);
//disallocate buffer
FreeMem(Buffer);
ShortDateFormat:=Temp;
//free cache
for i:=FFIEldCache.Count - 1 downto 0 do
Dispose(FFIEldCache.Items[i]);
FFIEldCache.Free;
end;