StringGrid内の文字列検索

解決


iogimi  2014-07-29 07:04:04  No: 46504  IP: [192.*.*.*]

Delphi4で作業中です。
StringGrid内の特定の文字列を探す方法はあるのでしょうか。
(=特定の文字列が書かれたStringGridを探し当てる)
ネット内ブラウジングしても「これだ」と思える記載が見つかりません。
できましたら早めのお教えをお願いします。

編集    削除
iogimi  2014-07-29 07:08:04  No: 46505  IP: [192.*.*.*]

すみませんバージョンを4と打ち間違えましたがDelphi7です。

編集    削除
igy  2014-07-29 07:39:45  No: 46506  IP: [192.*.*.*]

セルの文字列と探したい文字列が一致する場合なら、
RowsプロパティやColsプロパティがTStringsなので、全行あるいは全列に対し、
ループ内でIndexOf メソッドを使えば、探せそうな気がします。

そうでない場合、セルの文字列をループで1つずつAnsiPos関数とかで確認する方法になるかと。

編集    削除
RAD命  2014-08-01 09:38:09  No: 46507  IP: [192.*.*.*]

あると便利そうなので、それらしいのを作ってみました。
StringGridと変数を関数に入れると、

ヒットしたセルの数を返値に、
Stringlistに見つかった文字の位置を、
格納して返します。

ansipos_strgrid(
  グリッドを指定;
  =か<>を指定;
  比較対象文字列を指定;
  ヒットした座標を格納するStringlistを指定):integer;
例:
i := ansipos_strgrid(StringGrid1,'=','aaa',st);//aaaと一致する文字列を探します。
showmessage(inttostr(i) + '個見つかりました' + char(13) + st.Text);//結果を表示



※何分まだ未熟者ですので、この程度の簡易なものが限界ですが・・・。



function count_if_str(st,gety:tstringlist;s,set_str:string;int1:integer):integer;
var
  i,i1,i2:integer;
  st1,st2:TStringList;
  s1,s2,s3:string;
  function choice_if:string;
  begin
    choice_if := '';
    if s = '=' then begin
      if 0 < ansipos(set_str,s1) then begin
        choice_if := st[i];
      end;
    end else if s = '<>' then begin
      if 0 = ansipos(set_str,s1) then begin
        choice_if := st[i];
      end;
    end else begin
     //
    end;
  end;
begin
   st1 := TStringList.Create;
   st1.Clear;
   st2 := TStringList.Create;
   st2.Clear;

   for i := 0 to st.Count -1 do begin
     s1 := st[i];
     s2 := '0';
     s3 := '0';
     if '' <> choice_if then begin
       st1.Add(s1);
       s2 := inttostr(int1);
       s3 := inttostr(i);
       st2.Add(s2 + ',' + s3);
     end;

   end;
   count_if_str := st1.Count;
   st1.Free;
   gety.Text:= st2.Text;
   st2.Free;
end;

function ansipos_strgrid(g:TStringGrid;s,set_str:string;st_ans:TStringList):integer;
var
  st,st1,gety:TStringList;
  i,i1,i2:integer;
begin
  st :=TStringList.Create;
  st.Clear;
  st1 :=TStringList.Create;
  st1.Clear;
  gety :=TStringList.Create;
  gety.Clear;
  i2 := 0;
  for i := 0 to g.ColCount -1 do begin
    st_arry[i] := TStringList.Create;
    st_arry[i].Clear;
    gety.Clear;
    st.Text:= g.Cols[i].Text;
    i1 := count_if_str(st,gety,s,set_str,i);
    st1.Text:= st1.Text + gety.Text;
    i2 := i2 + i1;
  end;
  ansipos_strgrid:= i2;
 
  st_ans.text := st1.text;
  st.Free;
  gety.Free;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  st:TStringList;
begin
  st := TStringList.Create;
  st.Clear;
  showmessage(inttostr(ansipos_strgrid(form1.StringGrid1,'=','aaa',st)));
  showmessage(st.Text);
  st.free;
end;

編集    削除
RAD命  2014-08-01 15:59:53  No: 46508  IP: [192.*.*.*]

すいません、ansipos_strgrid関数に問題がありましたので修正します。
不要な変数の一部を消し忘れていましたので、修正しました。



function ansipos_strgrid(g:TStringGrid;s,set_str:string;st_ans:TStringList):integer;
var
  st,st1,gety:TStringList;
  i,i1,i2:integer;
begin
  st :=TStringList.Create;
  st.Clear;
  st1 :=TStringList.Create;
  st1.Clear;
  gety :=TStringList.Create;
  gety.Clear;
  i2 := 0;
  for i := 0 to g.ColCount -1 do begin
    gety.Clear;
    st.Text:= g.Cols[i].Text;
    i1 := count_if_str(st,gety,s,set_str,i);
    st1.Text:= st1.Text + gety.Text;
    i2 := i2 + i1;
  end;
  ansipos_strgrid:= i2;
 
  st_ans.text := st1.text;
  st.Free;
  gety.Free;
end;

編集    削除
deldel  2014-08-01 17:59:51  No: 46509  IP: [192.*.*.*]

私も作ってみました^^

procedure TForm1.FormCreate(Sender: TObject);
var
  iwC, iwR: Word;
begin
  //実験用データ
  for iwR := 0 to Pred(StringGrid1.RowCount) do begin
    for iwC := 0 to Pred(StringGrid1.ColCount) do begin
      StringGrid1.Cells[iwC, iwR] := IntToStr(Random(1000));
    end;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  iwC, iwR: Word;
begin
  //500なら行列番号をリストに追加
  for iwR := 0 to Pred(StringGrid1.RowCount) do begin
    for iwC := 0 to Pred(StringGrid1.ColCount) do begin
      if StringGrid1.Cells[iwC, iwR] = '500' then begin
        ListBox1.Items.Add(IntToStr(iwC) + ',' + IntToStr(iwR));
      end;
    end;
  end;

  //50を含むなら行列番号をリストに追加
  for iwR := 0 to Pred(StringGrid1.RowCount) do begin
    for iwC := 0 to Pred(StringGrid1.ColCount) do begin
      if Pos('50', StringGrid1.Cells[iwC, iwR]) <> 0 then begin
        ListBox2.Items.Add(IntToStr(iwC) + ',' + IntToStr(iwR));
      end;
    end;
  end;
end;

編集    削除
iogimi  2014-08-01 18:06:03  No: 46510  IP: [192.*.*.*]

みなさま
ありがとうございました。
いただいたプログラムでなんとかいけそうです。

ちなみにプログラムが作れなかったら
例外処理をしてセル単位でなくカラム単位に
とぶようにしてしのごうと思っていました。

編集    削除