Saltar al contenido

¿Copiar cadena a StringGrid?

Solución:

Si te entendí bien, entonces esto debería ser suficiente:

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;

Captura de pantalla

Hay un Tokenizer (como comenta David) en el RTL. Dividirá un texto en palabras, utilizando un delimitador de su elección.

Este ejemplo es de un comentario de Olaf Moinen en un artículo de 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;

Tomará el texto del control de edición y lo colocará en una nota. Lo dejaré como ejercicio para hacer lo mismo de una nota a una cuadrícula.

TStringGrid tiene la característica de llenar inexistente células, células que están más allá ColCount * RowCount. Por lo tanto, no es necesario contar las palabras antes de completar la cuadrícula de cadenas.

Entonces, un enfoque sencillo da como resultado:

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;

Nota: Para evitar la asignación de memoria adicional para el texto (debido a la adición de ' '), agregue la última palabra a la cuadrícula después del ciclo.

Característica de bonificación:

Para poder ajustar el recuento de columnas, subclasifique la cuadrícula de cadenas de la siguiente manera y todas las celdas se reorganizarán automáticamente:

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;
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *