Copy string to StringGrid?

I would like to copy the contents of Memo into a TStringGrid.

If there is a space or a space between the lines, then this word should be added to its cell in the StringGrid.

So, suppose my Memo, which is Wordwrapped, contains some information:

enter image description here

How can I copy this information to a StringGrid?

For the purposes of this example, I made a sample image to illustrate how the result should look:

enter image description here

It is important to know that I will not always know the number of columns used if, for example, Memo is loaded from a text file.

Maybe a predetermined number of columns will be determined, for example 5 or 6 columns. The number of rows will also be unknown.

How can i do this?

+6
source share
3 answers

If I understand you correctly, then this should be done:

procedure TForm1.FormClick(Sender: TObject); type TWordPos = record Start, &End: integer; end; const ALLOC_BY = 1024; var Words: array of TWordPos; ActualLength, i: integer; txt: string; ThisWhite, PrevWhite: boolean; begin ActualLength := 0; txt := Memo1.Text; PrevWhite := true; for i := 1 to Length(txt) do begin ThisWhite := Character.IsWhiteSpace(txt[i]); if PrevWhite and not ThisWhite then begin if ActualLength = Length(Words) then SetLength(Words, Length(Words) + ALLOC_BY); Words[ActualLength].Start := i; inc(ActualLength); PrevWhite := false; end else if (ActualLength>0) and ThisWhite then Words[ActualLength - 1].&End := i; PrevWhite := ThisWhite; end; SetLength(Words, ActualLength); StringGrid1.RowCount := Ceil(Length(Words) / StringGrid1.ColCount); for i := 0 to Length(Words) - 1 do begin StringGrid1.Cells[i mod StringGrid1.ColCount, i div StringGrid1.ColCount] := Copy(Memo1.Text, Words[i].Start, Words[i].&End - Words[i].Start); end; end; 

Screen shot

+5
source

There is Tokenizer in RTL (as David commented). It will split the text into words using the separator of your choice.

This example is from a comment by Olaf Moinen in an article by Zarko Gaijic: how-to-split-a-delphi-string-to-words-tokens.htm .

 uses HTTPUtil; procedure TForm1.Button1Click(Sender: TObject); var LTokenizer: IStringTokenizer; begin Memo1.Clear; LTokenizer := StringTokenizer(Edit1.Text, ' '); while LTokenizer.hasMoreTokens do Memo1.Lines.Add(LTokenizer.nextToken); end; 

He will take the text from the edit control and place it in the memo. I will leave this as an exercise to do the same from a note in a stringgrid.

+5
source

TStringGrid has the function of filling non-existent cells whose cells are outside of ColCount * RowCount . Thus, there is no need to count words before filling the grid of rows.

Then a direct approach leads to:

 procedure TForm1.Button1Click(Sender: TObject); var WordCount: Integer; WordStart: Integer; S: String; I: Integer; begin WordCount := 0; WordStart := 1; S := Memo.Text + ' '; for I := 1 to Length(S) do if S[I] = ' ' then begin if WordStart <> I then begin Grid.Cells[WordCount mod Grid.ColCount, WordCount div Grid.ColCount] := Copy(S, WordStart, I - WordStart); Inc(WordCount); end; WordStart := I + 1; end; Grid.RowCount := ((WordCount - 1) div Grid.ColCount) + 1; end; 

Note. . To prevent additional memory allocation for text (due to the addition of ' ' ), add the last word to the grid after the loop.

Bonus Function:

To set up column counting, reclassify the row grid as follows, and all cells will be automatically rearranged:

 type TStringGrid = class(Grids.TStringGrid) protected procedure SizeChanged(OldColCount, OldRowCount: Integer); override; end; TForm1 = class(TForm) ... procedure TStringGrid.SizeChanged(OldColCount, OldRowCount: Integer); var I: Integer; begin if OldColCount < ColCount then begin for I := 0 to OldColCount * OldRowCount - 1 do Cells[I mod ColCount, I div ColCount] := Cells[I mod OldColCount, I div OldColCount]; end else if OldColCount > ColCount then begin for I := OldColCount * OldRowCount - 1 downto 0 do Cells[I mod ColCount, I div ColCount] := Cells[I mod OldColCount, I div OldColCount]; end; if OldColCount <> OldRowCount then for I := OldColCount * OldRowCount to ColCount * RowCount - 1 do Cells[I mod ColCount, I div ColCount] := ''; end; 
+2
source

Source: https://habr.com/ru/post/910450/


All Articles