【问题标题】:Pulling Text From a Memo Box Line by Line逐行从备忘录框中提取文本
【发布时间】:2012-04-06 20:26:30
【问题描述】:

我需要查看存储在备注字段中的悖论表中的大量数据。我需要逐行处理这个数据并处理每一行。

如何告诉 Delphi 逐一获取备注字段中的每一行?

我可以使用#13#10 作为分隔符吗?

【问题讨论】:

    标签: database delphi paradox


    【解决方案1】:

    假设备忘录字段中的内容使用#13#10 作为行分隔符,那么我将使用TStringList 和非常有用的Text 属性将备忘录字段文本拆分为单独的行:

    var
      StringList: TStringList;
      Line: string;
    .....
    StringList.Text := MemoFieldText;
    for Line in StringList do
      Process(Line);
    

    即使您的备注字段使用 Unix 换行符,此代码也会正确解释备注字段。

    【讨论】:

    • TStringList 支持解析使用#13#10#13#10 作为换行符的文本。
    • @Remy 文档声明“设置 Text 时,只要遇到回车或换行,就会通过分隔成子字符串来解析值。(两者不需要形成对)。”那是不是已经过时了?我在最后的宽限期编辑(即最后一句话)之前检查了这一点的文档。
    • 不,它仍然有效。当LineBreak 属性设置为sLineBreak(操作系统本机换行符)时,将查找所有三种换行符类型(CRLFCRLF)。当 LineBreak 属性设置为其他值时,只会查找该值。
    • @remy 谢谢。看来文档在这些细节上有些欠缺
    • @David,“有点缺乏”这个措辞太客气了。
    【解决方案2】:

    这取决于 Paradox 中实际声明该字段的方式。如果是 TMemoField,那就很简单了:

    var
      SL: TStringList;
      Line: string;
    begin
      SL := TStringList.Create;
      try
        SL.Text := YourMemoField.GetAsString;
        for Line in SL do
         // Process each line of text using `Line`
      finally
        SL.Free;
      end;
    end;
    

    如果是 TBlobField,就复杂一点。您需要使用TBlobStream 读取备注字段,并将该流的内容加载到TStringList

    // For Delphi versions that support it:
    procedure LoadBlobToStringList(const DS: TDataSet; const FieldName: string;
      const SL: TStringList);
    var
      Stream: TStream;
    begin
      Assert(Assigned(SL), 'Create the stringlist for LoadBlobToStringList!');
      SL.Clear;
      Stream := DS.CreateBlobStream(DS.FieldByName(FieldName), bmRead);
      try
        SL.LoadFromStream(Stream);
      finally
        Stream.Free;
      end;
    end;
    
    // For older Delphi versions that do not have TDataSet.CreateBlobStream
    procedure LoadBlobToStringList(const DS: TDataSet; const TheField: TField; 
      const SL: TStringList);
    var
      BlobStr: TBlobStream;
    begin
      Assert(Assigned(SL), 'Create the stringlist for LoadBlobToStringList!');
      SL.Clear;
      BlobStr := TBlobStream.Create(DS.FieldByName(TheField), bmRead);
      try
        SL.LoadFromStream(BlobStr);
      finally
        BlobStr.Free;
      end;
    end;
    
    // Use it
    var
      SL: TStringList;
      Line: string;
    begin
      SL := TStringList.Create;
      LoadBlobToStringList(YourTable, YourMemoFieldName, SL);
      for Line in SL do
        // Process each Line, which will be the individual line in the blob field
    
      // Alternatively, for earlier Delphi versions that don't support for..in
      // declare an integer variable `i`
      for i := 0 to SL.Count - 1 do
      begin
        Line := SL[i];
        // process line of text using Line
      end;
    end;
    

    【讨论】:

    • 您应该使用TDataSet.CreateBlobStream() 方法而不是直接实例化TBlobStream 类。这允许 DB 组件决定用于流的最佳实现。
    • @Remy:我考虑过为此添加sn-p;我将更新我的代码以显示该替代方案。 (它在早期的 Delphi 版本中不存在,问题中也没有提到版本;我选择了最不常见的恶魔,以及当时我手边的东西。)
    • CreateBlobStream() 至少从 D5 开始就已经存在,也许更早。
    • 可能;我没有安装旧版本(或之前的版本)来检查。由于 OP 没有指定 any 版本,并提到了 BDEParadox,这可能与 Delphi 1 一样古老。:) 无论如何,我接受了你的建议并更新了我的答案以包括两者。
    猜你喜欢
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多