如何将StringList中的字符串复制到多个Memos

How to copy strings from StringList to multiple Memos

我有一个文本文件和 10 个 StringLists,我想打开 10 个 StringLists 中的 txt 文件,例如文本文件有 1000 行,我想要 StringList1 中的前 100 行和 StringLists2 中的第二个 100 行和依此类推,我的想法是计算文本文件行数并将其除以 10,然后将 100 个复制到 10 个 StringLists

var
 i, x :integer;
 U : TStrings;
 DatFile ,ExePath:string;

begin
 U := TStringList.Create;
 ExePath := ExtractFilePath(Application.ExeName);
 DatFile := ExePath + 'Test.txt';
 U.LoadFromFile(DatFile);
 x := U.Count Div 10;
 Edit1.Text := IntToStr(x);
 /// Stoped here
end;

如何继续?

你可以用一个数组来保存Memo指针,然后循环遍历文件的行,计算每行添加到哪个数组索引,例如:

var
  i, LinesPerMemo, LinesAdded: integer;
  U : TStrings;
  DatFile: string;
  Memos: array[0..9] of TMemo;
  CurMemo: TMemo;
begin
  Memos[0] := Memo1;
  Memos[1] := Memo2;
  Memos[2] := Memo3;
  Memos[3] := Memo4;
  Memos[4] := Memo5;
  Memos[5] := Memo6;
  Memos[6] := Memo7;
  Memos[7] := Memo8;
  Memos[8] := Memo9;
  Memos[9] := Memo10;

  DatFile := ExtractFilePath(Application.ExeName) + 'Test.txt';

  U := TStringList.Create;
  try
    U.LoadFromFile(DatFile);

    LinesPerMemo := U.Count div 10;
    if (U.Count mod 10) <> 0 then
      Inc(LinesPerMemo);

    Edit1.Text := IntToStr(LinesPerMemo);

    J := 0;
    CurMemo := Memos[J];

    try
      LinesAdded := 0;
      for I := 0 to U.Count-1 do
      begin
        CurMemo.Lines.Add(U[I]);
        Inc(LinesAdded);
        if (LinesAdded = LinesPerMemo) and (J < 9) then
        begin
          CurMemo.Lines.EndUpdate;
          Inc(J);
          CurMemo := Memos[J];
          CurMemo.Lines.BeginUpdate;
          LinesAdded := 0;
        end;
      finally
        CurMemo.Lines.EndUpdate;
      end;
    end;
  finally
    U.Free;
  end;
end;

或者,使用临时 TStringList 收集每个备忘录的行:

var
  i, LinesPerMemo: integer;
  U, Lines : TStrings;
  DatFile: string;
  Memos: array[0..9] of TMemo;
begin
  Memos[0] := Memo1;
  Memos[1] := Memo2;
  Memos[2] := Memo3;
  Memos[3] := Memo4;
  Memos[4] := Memo5;
  Memos[5] := Memo6;
  Memos[6] := Memo7;
  Memos[7] := Memo8;
  Memos[8] := Memo9;
  Memos[9] := Memo10;

  DatFile := ExtractFilePath(Application.ExeName) + 'Test.txt';

  U := TStringList.Create;
  try
    U.LoadFromFile(DatFile);

    LinesPerMemo := U.Count div 10;
    if (U.Count mod 10) <> 0 then
      Inc(LinesPerMemo);

    Edit1.Text := IntToStr(LinesPerMemo);

    Lines := TStringList.Create;
    try
      J := 0;
      for I := 0 to U.Count-1 do
      begin
        Lines.Add(U[I]);
        if (Lines.Count = LinesPerMemo) and (J < 9) then
        begin
          Memos[J].Lines.Assign(Lines);
          Inc(J);
          Lines.Clear;
        end;
      end;
      Memos[J].Lines.Assign(Lines);
    finally
      Lines.Free;
    end;
  finally
    U.Free;
  end;
end;

为了加快速度,如果需要,您可以使用 Texfile 和 Tstringstream 创建 Tmemo。

type
  TForm1 = class(TForm)
    Button1: TButton;
    ScrollBox1: TScrollBox;
    procedure Button1Click(Sender: TObject);
  private
    { Déclarations privées }
    function getNewMemo(const aStream : Tstream) : TMemo;
  public
    { Déclarations publiques }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
const nblines : Integer = 100;
var F : TextFile;
    sLine, sfile : string;
    cpt : Integer;
    Memo : TMemo;
    tmp : TStringStream;
begin
  sfile := 'C:\TEMP\Test.txt';

  tmp := TStringStream.Create;
  AssignFile(F, sFile);
  Reset(F);
  try
    LockWindowUpdate(ScrollBox1.Handle);
    cpt := 0;
    while not Eof(F) do begin
      Readln(F, sLine);
      Inc(cpt);

      tmp.WriteString(sLine + #13);
      if (cpt mod nbLines = 0) then begin
        Memo := getNewMemo(tmp);
        tmp.Clear;
      end;
    end;

    if tmp.Size > 0 then begin
      Memo := getNewMemo(tmp);
      tmp.Clear;
    end;
  finally
    CloseFile(F);
    tmp.Free;
    LockWindowUpdate(0);
  end;
end;

function TForm1.getNewMemo(const aStream : Tstream): TMemo;
begin
  Result := TMemo.Create(ScrollBox1);
  Result.Parent := ScrollBox1;
  Result.Top := High(integer);
  Result.Align := alTop;
  Result.Height := 150;
  Result.ScrollBars := ssBoth;
  if aStream <> nil then begin
    aStream.Seek(0, soFromBeginning);
    Result.Lines.LoadFromStream(aStream);
  end;
end;

end.