Delphi: Import csv to Firebird Database

อันนี้ลองทำเล่น เมื่อมีโจทย์คือ ได้ file .csv มา 1 file และต้องการอ่านมันด้วย program ที่เราสร้างขึ้นเองและนำข้อมูบที่อ่านได้เหล่านั้นเข้าไปเก็บไว้ใน database ที่เราได้เตรียมเอาไว้ ทำไงดี...? ใช้เครื่องมือที่ถนัด Delphi 7 ก่อนอื่นให้ดูหน้าตา เจ้า csv file ว่าซะหน่อย


รูปบนเปิดด้วย Excel
รูปนี้เปิดด้วย EditPlus



หน้าตาประมาณ 2 ภาพด้านบนอ่ะครับ โดยมันจะมี , คั้นระหว่าง column

ต่อไปเรามาดู Table บน Database ที่เราจัดเตรียมไว้





ตารางที่จัดเตรียมไว้มีโครงสร้างดังภาพ

ต่อไปมาดูตัวอย่างการเขียน code ด้วย Delphi



เมื่อเรารันโปรแกรม แล้วกดปุ่ม Browse...
เพื่อหา file.csv













จะได้หน้าต่าง Open ดังภาพ
ให้เลือก a.csv ดังภาพตัวอย่างนี้
และเมื่อกดปุ่ม Open โปรแกรมจะอ่านข้อมูลจาก
.csv มาใส่ในตารางหน้าต่างโปรแกรมในภาพก่อนหน้านี้

ต่อไปมาดู code ที่ต้องเขียน
ส้ราง procedure หลัก 2 ตัว คือ
    procedure CreateMyDataset(fDataset: TClientDataset);
    procedure ImportCsvData(fDataset: TClientDataset);


code:
procedure TForm1.CreateMyDataset(fDataset: TClientDataset);
begin
{
Table OT_RECORD
-----------------------
| Field   | Type      |
|---------------------|
| empcode | String(9) |
| ot_date | Date      |
| ot_type | String(1) |
| ot_stat | time      |
| ot_stop | time      |
|---------------------|
}
    if not fDataset.Active then begin
        with fDataset do begin
            fDataset.FieldDefs.Add('emp_code', ftString, 9);
            fDataset.FieldDefs.Add('ot_date', ftDate, 0);
            fDataset.FieldDefs.Add('ot_type', ftString, 1);
            fDataset.FieldDefs.Add('ot_start', ftTime, 0);
            fDataset.FieldDefs.Add('ot_stop', ftTime, 0);
            fDataset.CreateDataSet;
            IndexFieldNames:='emp_code';
            //Open;
        end;
    end
    else begin
        fDataset.Close;
        fDataset.Open;
        fDataset.EmptyDataSet;
        fDataset. IndexFieldNames:='emp_code';
    end;
end;


procedure TForm1.ImportCsvData(fDataset: TClientDataset);
var
  csv: TextFile;
  Rec: string;
  Fields: TStringList;
  LineNo: Integer;
  i: Integer;
  vFileName: string;
begin
  Fields := TStringList.Create;
  try
    //Fields.StrictDelimiter := True;
    Fields.Delimiter := ',';
    if OpenDialog1.Execute then
       vFileName:= OpenDialog1.FileName
    else
       Abort;

    AssignFile(csv, vFileName);
    CreateMyDataset(fDataset);
    try
      Reset(csv);

      LineNo := 0;
      while not Eof(csv) do begin
        Inc(LineNo);
        Readln(csv, Rec);

        Fields.DelimitedText := Rec;
        fDataset.Append;

        for i := 0 to Fields.Count - 1 do
          try
            fDataset.Fields[i].Value := Fields[i]; 
          except
            on E:EDatabaseError do begin
              fDataset.Cancel;        // Failed, discard the record

              // log the error instead of showing a message
              ShowMessage(Format('Cannot set field "%s" at line %d' + sLineBreak +
                  'Error: %s', [fDataset.Fields[i].FieldName, LineNo, E.Message]));
              Break;             // Continue with next record
            end;
          end;

        if fDataset.State = dsInsert then // It's not dsInsert if we Cancelled the Insert
          try
            fDataset.Post;
          except
            on E:EDatabaseError do begin
              // log error instead of showing
              ShowMessage(Format('Cannot post line %d' + sLineBreak + 'Error: %s',
                  [LineNo, E.Message]));
              fDataset.Cancel;
            end;
          end;

      end;
    finally
      CloseFile(csv);
    end;
  finally
    Fields.Free;
  end;
end;

ขั้นตอนการทำงาน
- สร้าง dataset ขึ้นมา
- browse .csv
- loop อ่านค่า จาก .csv


Ref. code ตัวอย่าง

Comments

  1. เมื่อปีก่อน เป็นคนเขียนเอาไว้
    ไม่คิดว่าต้องมาอ่านของตัวเองเพื่อแกโจทย์เก่า

    ReplyDelete

Post a Comment