Problem z pętlami i StringGrid

0

Mam następujący problem:
Mam tekst który wczytuje do Memo1. Potem w pętli analizuje każdy wiersz z Memo1, i za pomocą ExtractStrings rozdzielam go wedle określonego znaku. Następnie podzelony wiersz wrzucam do Memo2. Teraz mój problem polega na tym, że chcę aby do pierwszej kolumny, pierwszego wiersza StringGrid1 trafił pierwszy wyraz, z Memo2, drugi wyraz do drugiej kolumny pierwszego wiersza itd. (i tak dla wszystkich wierszy, aż do końca tekstu znajdującego się w Memo1). Żeby rozjaśnić podam fragment kodu:

var
i,p,n: integer;
 begin
  StringGrid1.RowCount:=Memo1.Lines.Count; {Ustala ilość wierszy w StringGrid1};
   for i:=0 to Memo1.Lines.Count-1 do begin {Początek pętli analizującej każdy wiersz Memo1}
    Memo2.Clear; {Gdy wiersz zostaje rodzielony, trafia Memo2 i odrazu do StringGrid, po czym Memo2 zostaje wyczyszczone i użyte ponownie. Memo2 jednorazowo przetrzymuje tylko jeden, rozdzielony wiersz}
     ExtractStrings(['='],[' '],Pchar(Memo1.Lines.Strings[i]),Memo2.Lines); {Dzieli wiersz wedle znaku "=", pocięte kawałki wrzuca do Memo2}
      for p:=0 to StringGrid1.ColCount-1 do {petla analizująca ilość kolumn}
       for n:=0 to Memo2.Lines.Count-1 do begin {pętla która, TEORETYCZNIE, powinna przypisywać komórkom StringGrid kolejne elementy wiersza zapisanego chwilowo w Memo2}
       StringGrid1.Cells[p,i]:=Memo2.Lines.Strings[n]; {p = kolumna, i = wiersz - to działa OK, ale niestety wartość n jest inna niż powinna być}
       end;
      end;
 end;

Wiem że tutaj wszystko jest kwestią odpowiedniego zapętlenia, ale nie mogę sobie z tym jakoś poradzić :/

Gdy mam określoną ilość kolumn wtedy jest łatwo, przypisuje pierwszej kolumnie pierwszy element Memo2 , drugiej drugi, trzeciej trzeci, i tak aż do końca:
StrinGrid.Cells[0,i]:=Memo2.Lines.Strings[0];
StrinGrid.Cells[1,i]:=Memo2.Lines.Strings[1];
StrinGrid.Cells[2,i]:=Memo2.Lines.Strings[2];
itd.

Ale niestety mam zmienną liczbę kolumn, w zależności od otwartego pliku (od jednej aż do kilkudziesięciu), więc robienie tego ręcznie odpada (jest to możliwe, ale zbyt czasochłonne).

Jeżeli ktoś potrafi mi pomóc, to bardzo proszę o pomoc.

Pozrawiam i przepraszam jeżeli gdzieś na forum jest już odpowiedz na moje pytanie. Wątpie jednak, bo ja nie pytam o sposób (bo ten znam), ale o wykonanie :D

====EDIT=====
Poradziłem sobie, ale...

var
i,p,n: integer;
 begin
  StringGrid1.RowCount:=Memo1.Lines.Count;
   for i:=0 to Memo1.Lines.Count-1 do begin
    Memo2.Clear;
     ExtractStrings(['='],[' '],Pchar(Memo1.Lines.Strings[i]),Memo2.Lines);
       for n:=0 to Memo2.Lines.Count-1 do begin
       StringGrid1.Cells[n,i]:=Memo2.Lines.Strings[n]; {działa to w ten sposób, że wypełnienie kolumn tekstem, zależy od ilości elementów w Memo2, jeżeli tychże będzie więcej niż kolumn, to niestety będzie zgrzyt :(}
       end;
      end;
 end;

Tylko właśnie żeby to zadziałało muszę wcześniej ustawić większą liczbę kolumn w StringGrid1, a potem wywalić niepotrzebne... Niby nic wielkiego, ale jestem pewien że można zrobić to lepiej :]

0

Przed podstawieniem do konkretnej komórki stringgrid'a sprawdzaj czy adres gdzie chcesz wpisać dane mieści się w zakresie ColCount, RowCount jeśli nie to rozciąg stringgrid'a.

b

0

A może jakiś przykładowy kodzik? :)

0

If n >= StringGrid1.ColCount then
StringGrid1.ColCount := n;
If i >= StringGrid1.RowCount then
StringGrid1.RowCount := i;
StringGrid1.Cells[n,i]:=Memo2.Lines.Strings[n]

0

To tak proste że aż głupie, czyli - dziękuje bardzo za pomoc :] (jak mogłem na to nie wpaść? ;-P)

PS. nie wiedziałem że tak ciężko jest napisać prościutki arkusz w stylu execa, ale trochę w tym winy StringGrida, bardzo okrojony komponent. Brakuje mu wielu podstawowych funkcji, choćby dodawania czy kasowania wierszy, oczywiście jest to do napisania bez większych problemów, ale jednak powinno to być wbudowane...

Pozdro.

0

Ostatnio klepnąłem sobie coś takiego do pracy z plikami CSV. Jak się zastanowić to wszystko można sobie ładnie zrobić. Wstawianie wierszy, kolumn ... Ale także parę innych rzeczy jak np rozbijanie kolumn, dopasowywanie szerokości ...
Kiedyś kiedyś pamiętam że było w Delphi coś takiego jak F1Book czy workbook, chyba na zakładce z ActiveX'ami. Miał to funkcjonalność bardzo zbliżoną do wczesnych wersji Excela.

b

0

O miałem akurat pod ręką projekt:

procedure InsertColumn(aGrid : TStringGrid; aBefore : Integer);
  var i : Integer;
begin
  If aBefore = -1 then
    Exit;
  SaveTL(aGrid);
  try
    aGrid.ColCount := aGrid.ColCount + 1;
    For i := aGrid.ColCount - 1 downto aBefore + 1 do
      Begin
        aGrid.Cols[i] := aGrid.Cols[i - 1];
        aGrid.ColWidths[i] := aGrid.ColWidths[i - 1];
      End;
  finally
    RestoreTL(aGrid);
  end;
End;

procedure InsertRow(aGrid : TStringGrid; aBefore : Integer);
  var i : Integer;
begin
  If aBefore = -1 then
    Exit;
  SaveTL(aGrid);
  try
    aGrid.RowCount := aGrid.RowCount + 1;
    For i := aGrid.RowCount - 1 downto aBefore + 1 do
      Begin
        aGrid.Rows[i] := aGrid.Rows[i - 1];
      End;
  finally
    RestoreTL(aGrid);
  end;
End;
0

Mam kolejny problem, ale tym razem nie wiem nawet jak się za to zabrać...

Wcześniej dzieliłem wiersze wedle znaku '=' i przepisywałem to do komórek SG, ale teraz muszę zrobić proces odwrotny:

Memo.Lines.Add (Komórka pierwsza pierwszej kolumny+'='+Komórka pierwsza drugiej kolumny+'='... itd, aż do końca kolumn).

To oczywiście w pętli dla każdego wiersza w SG. Chodzi mniej więcej o to by tekst wrócił do pierwotnej postaci.

Kombinowałem z pętlami, ale nadal nie wiem :/

0

Trzeba było wkleić jakis kod ...

For i := stg.FixedRows to stg.RowCount - 1 do
begin
s := '';
For j := stg.FixedCols to stg.ColCount - 1 do
s := stg.Cells[j, i] + '=';
Delete(s, Length(s), 1);
memo1.lines.add(s);
end;

pisane bez kompilatora. Można by też spróbować wykorzystać właściwość Rows[x], ale nie chce mi sie odpalać delphi żeby sprawdzić jak.

b

1 użytkowników online, w tym zalogowanych: 0, gości: 1