开发者

Stringlist with delimiter as a string?

开发者 https://www.devze.com 2023-01-08 18:12 出处:网络
I have an attribute called HistoryText in a object that is stored as a string. I want to show all rows in a grid. I should be able to delete and edit rows in the grid.

I have an attribute called HistoryText in a object that is stored as a string. I want to show all rows in a grid. I should be able to delete and edit rows in the grid. The format is:

16.5.2003-$-12:09-$-anna-$-Organization created
2.6.2005-$-13:03-$-jimmy-$-Organization edited
19.12.2005-$-13:33-$-madeleine-$-Organization edited

So each row have 4 fields, date, time, user, and message with a delimiter string as '-$-'. As the delimiter a string and not a char it cannot be assigned to the stringlists delimiter property.

I have a routine to extract the string to a Stringlist:

procedure ParseDelimited(const aStringList: TStringList; const aOrgList, aDelimiter: string);
var
   vDelimiterPos : integer;
   vPartialStr : string;
   vRemaingTxt : string;
   vDelimiterLength : integer;
begin
   vDelimiterLength := Length(aDelimiter);

   if (AnsiRightStr(aOrgList, Length(aDelimiter)) = aDelimiter) then
     vRemaingTxt := aOrgList
   else
     vRemaingTxt := aOrgList + aDelimiter;

   aStringList.BeginUpdate;
   aStringList.Clear;
   try
     while Length(vRemaingTxt) > 0 do
     begin
       vDelimiterPos := Pos(aDelimiter, vRemaingTxt);
       vPartialStr := Copy(vRemaingTxt,0,vDelimiterPos-1);
       aStringList.Add(vPartialStr);
       vRemaingTxt := Copy(vRemaingTxt,vDelimiterPos+vDelimiterLength,MaxInt);
     end;
   finally
     aStringList.EndUpdate;
   end;
end;

and it seems to work fine. My problem is syncing the changes in the StringList back to the original String property ? There are so much historical data with this delimiter so I don't think change it to a TChar is a realistic option.

Update: A clarification. I think I can manage to convert the String to a StringList with the method above. Then display it in the grid should not be so hard. The problem come when I want to convert the TStringList back to the original String property wih '-$-' as delimiter. I cannot do HistoryText := myStringList.Delimitedtext for example.

Second update: I have solved it. You all got a +1 for fast answers and really trying to help. In summary how I did it.

Read from Historytext:

MyStringList.Text := Historytext;

Now each row have 3 delimiters of '-$-' 开发者_Go百科and each line is separated by a linefeed as usual.

  • In a loop parse the Stringlist and show it in the grid. I don't bother about MyStringList anymore.
  • Let the user delete and edit rows in the grid.
  • When finished loop by row and columns in the grid and build a new string with the same format as original.
  • Assign that string to HistoryText.

So shift focus from StringList to the grid made it easier :)


Instead of Delimiter (a char) and DelimitedText, you can also use LineBreak (a string) and Text:

lst := TStringList.Create;
try
  lst.LineBreak := '-$-';
  lst.Text := '16.5.2003-$-12:09-$-anna-$-Organization created';
  Memo1.Lines := lst;  // or whatever you do with it
finally
  lst.Free;
end;

Ans it works even the other way round.


Wild stab in the dark (it isn't very clear what you are asking):

Work through the grid rows:

  • For each row:
    • assign an empty string to a temporary string var
    • For each column add row/column value plus your delimiter to temporary string var
    • remove last delimiter from temporary string var (if it is non-empty)
    • add temporary string var to stringlist
  • Write stringlist's text property back to your HistoryText

const
  Delimiter = '-$-';
var
  row: Integer;
  col: Integer;
  SL: TStringList;
  rowString: string;
begin
  SL := TStringList.Create;
  try
    for row := 0 to StringGrid1.RowCount - 1 do begin
      rowString := '';
      for col := 0 to StringGrid1.ColCount - 1 do begin
        rowString := StringGrid1.Cells[col, row] + Delimiter;
      end;
      if rowString <> '' then begin
        rowString := Copy(rowString, 1, Length(rowString) - Length(Delimiter));
      end;
      SL.Add(rowString);
    end;
    HistoryText := SL.Text;
  finally
    SL.Free;
  end;
end;

Using Uwe's solution of TStrings' LineBreak property:

var
  row: Integer;
  col: Integer;
  SLRows: TStringList;
  SLCols: TStringlist;
begin
  SLRows := TStringList.Create;
  try
    SLCols := TStringList.Create;
    try
      SLCols.LineBreak := '-$-';
      for row := 0 to StringGrid1.RowCount - 1 do begin
        SLCols.Clear;
        for col := 0 to StringGrid1.ColCount - 1 do begin
          SLCols.Add(StringGrid1.Cells[col, row]);
        end;
        SLRows.Add(SLCols.Text);
      end;
      HistoryText := SLRows.Text;
    finally
      SLCols.Free;
    end;
  finally
    SLRows.Free;
  end;
end;
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号