从定界符分隔值文件中还原数据集 [英] Restoring dataset from delimiter separated values file

查看:80
本文介绍了从定界符分隔值文件中还原数据集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简而言之,我是delphi的新手,我想实现以下目标:

In short, i'm new to delphi and I want to achieve the following:


  • 我将表定义为.cds文件{index,data ,日期}和一些.csv格式的数据。

  • 我想将.csv文件加载到表中并显示其更改和错误(例如:无效的日期格式)的日志。 / li>
  • I have table definition as .cds file {index, data, date}, and some data in .csv format.
  • I want to load the .csv file to the table and show log it's changes and errors (ex: invalid date format).

如何优雅地解决此任务?

How to solve this task elegantly?

推荐答案

您可以从.csv逐行读取,将每行设置为StringList的'DelimitedText',将记录追加到数据集,循环字符串列表以设置每个字段的值然后发布到数据集。
您可以将字段值赋值 /发布放在try-except块中,并记录引发异常的任何错误消息以及所需的信息(例如,格式错误的字段值/名称,行号和/或整行等)到文件fi

You can read line by line from the .csv, set each line to 'DelimitedText' of a StringList, append a record to the dataset, loop the string list to set each field's value and then post to the dataset.
You can put the 'field value assinging'/'posting' in a try-except block and log any error message of raised exceptions together with information you like (e.g. malformed field value/name, line number, and/or entire line etc.) to a file f.i.

(我不理解您所说的更改是什么意思,据我了解,.csv中的行将是

(I don't understand what you mean by 'changes', from what I understood, lines from the .csv will be inserted to a dataset, hence all changes will be inserts.)


编辑:为了能够讨论一些具体的内容(我很难抓紧任务:))


edit: To be able to discuss on something concrete (I'm having a hard time grasping the task :))

样本数据(CodeGear样本 Clients.cds的一部分):

Sample data (part of CodeGear sample 'Clients.cds'):


Davis; Jennifer; 1023495,0000; 100
Cranberry
St.; Wellesley; MA; 02181; 516-292-3945; 01.01.93
Jones; Arthur; 2094056,0000; 10 Hunnewell
St; Los
Altos; CA; 94024; 415-941-4321; 07.02.81
Parker; Debra; 1209395, 0000; 74 South
St; Atherton; CA; 98765; 916-213-2234; 23.10.90
Sawyer; Dave; 3094095,0000; 1 01 Oakland
St; Los
Altos; CA; 94022; 415-948-9998; 21.12.89
White; Cindy; 1024034,0000; 1 Wentworth
Dr; Los
Altos; CA; 94022; 415-948-6547; 01.10.92

Davis;Jennifer;1023495,0000;100 Cranberry St.;Wellesley;MA;02181;516-292-3945;01.01.93 Jones;Arthur;2094056,0000;10 Hunnewell St;Los Altos;CA;94024;415-941-4321;07.02.81 Parker;Debra;1209395,0000;74 South St;Atherton;CA;98765;916-213-2234;23.10.90 Sawyer;Dave;3094095,0000;101 Oakland St;Los Altos;CA;94022;415-948-9998;21.12.89 White;Cindy;1024034,0000;1 Wentworth Dr;Los Altos;CA;94022;415-948-6547;01.10.92



procedure TForm1.FormCreate(Sender: TObject);
begin
  CDS.FieldDefs.Add('LAST_NAME', ftString, 20);
  CDS.FieldDefs.Add('FIRST_NAME', ftString, 20);
  CDS.FieldDefs.Add('ACCT_NBR', ftInteger);
  CDS.FieldDefs.Add('ADDRESS_1', ftString, 30);
  CDS.FieldDefs.Add('CITY', ftString, 15);
  CDS.FieldDefs.Add('STATE', ftString, 2);
  CDS.FieldDefs.Add('ZIP', ftString, 5);
  CDS.FieldDefs.Add('TELEPHONE', ftString, 12);
  CDS.FieldDefs.Add('DATE_OPEN', ftDate);
  CDS.CreateDataSet;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  csv: TextFile;
  Rec: string;
  Fields: TStringList;
  LineNo: Integer;
  i: Integer;
begin
  Fields := TStringList.Create;
  try
    Fields.StrictDelimiter := True;
    Fields.Delimiter := ';';

    AssignFile(csv, ExtractFilePath(Application.ExeName) + 'clients.csv');
    try
      Reset(csv);

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

        Fields.DelimitedText := Rec;
        CDS.Append;

        for i := 0 to Fields.Count - 1 do
          try
            CDS.Fields[i].Value := Fields[i];   // Variant conversion will raise
                                 // exception where conversion from string fails
          except
            on E:EDatabaseError do begin
              CDS.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', [CDS.Fields[i].FieldName, LineNo, E.Message]));
              Break;             // Continue with next record
            end;
          end;

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

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

procedure TForm1.CDSBeforePost(DataSet: TDataSet);
begin
  // Superficial posting error
  if CDS.FieldByName('LAST_NAME').AsString = '' then
    raise EDatabaseError.Create('LAST_NAME cannot be empty');
end;

这篇关于从定界符分隔值文件中还原数据集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆