Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Как реализовать поиск с переходом в StringGrid?


Автор: S@nderS 10.7.2008, 13:57
Вот вопрос, как в случае если мы обнаруживаем нужную нам ячейку, как к ней перейти?

Автор: VICTAR 10.7.2008, 15:23
Код

  StringGrid1.Col := X;
  StringGrid1.Row := Y;

Автор: S@nderS 10.7.2008, 16:37
Спасибо, вот это я тупица  smile   smile 

Автор: VICTAR 10.7.2008, 16:43
Бывает  smile 
Пометь как решенный

Автор: S@nderS 11.7.2008, 12:40
Столкнулся с очередно проблемой. Все найденные ячейки я записываю в массив из записей

Код

type
 FCells = record
  Col: integer;
  Row: integer;
end;

....

var
FindArray: array[1..100] of FCells;

....



Затем я ищу в StringGrid искомые значения. 

Код

procedure Search(SG: TStringGrid; FindStr: string; OnlyWord: boolean);
var
i,j,counter: integer;
begin
  for i := 1 to 100 do
   begin
    FindArray[i].Col := 0;
    FindArray[i].Row := 0;
   end;
 counter := 1;
 if OnlyWord = True
  then
   begin
    for i := 0 to SG.ColCount do
     for j := 1 to SG.RowCount do
      begin
       if FindStr = SG.Cells[i,j]
        then
         begin
          FindArray[counter].Col := i;
          FindArray[counter].Row := j;
          Inc(counter);
         end;
      end;
   end
    else
     begin
      for i := 0 to SG.ColCount do
       for j := 1 to SG.RowCount do
        begin
         if pos(SG.Cells[i,j],FindStr) <> 0
         then
          begin
           FindArray[counter].Col := i;
           FindArray[counter].Row := j;
           Inc(counter);
          end;
        end;
     end;
end;


Затем при попытке перемещения по найденым ячейкам мне выдаёт EAccessViolation...

Поиск вверх по StringGrid:

Код

procedure TForm2.Button2Click(Sender: TObject);
begin
 if (Arrow >= 1) and (Arrow<=100) and (FindArray[Arrow].Col <> 0) and (FindArray[Arrow].Row <> 0)
 then Arrow := Arrow - 1;
 Form1.StringGrid1.Col := FindArray[Arrow].Col;
 Form1.StringGrid1.Row := FindArray[Arrow].Row;
end;


Поиск вниз по StringGrid:

Код

procedure TForm2.Button3Click(Sender: TObject);
begin
 if (Arrow >= 1) and (Arrow<=100) and (FindArray[Arrow].Col <> 0) and (FindArray[Arrow].Row <> 0)
 then Arrow := Arrow + 1;
 Form1.StringGrid1.Col := FindArray[Arrow].Col;
 Form1.StringGrid1.Row := FindArray[Arrow].Row;
end;



Где я косячу?

Автор: VICTAR 11.7.2008, 13:32
Вообще у TStringGrid есть такое свойство Rows[Индекс] которое является TStrings. Соответственно поиск логичней осуществлять с помощью  TStrings.IndexOf().

Автор: S@nderS 11.7.2008, 23:22
Цитата(VICTAR @ 11.7.2008,  11:32)
Вообще у TStringGrid есть такое свойство Rows[Индекс] которое является TStrings. Соответственно поиск логичней осуществлять с помощью  TStrings.IndexOf().

Спасибо. Если не получится так, как хочу я, то сделаю по вашему способу. 

И всё же, почему происходит эта ошибка?

Автор: VICTAR 12.7.2008, 00:09
Цитата(S@nderS @  11.7.2008,  23:22 Найти цитируемый пост)
И всё же, почему происходит эта ошибка? 

Потому что происходит выход за пределы массива вот здесь
Код

 Form1.StringGrid1.Col := FindArray[Arrow].Col;
 Form1.StringGrid1.Row := FindArray[Arrow].Row;

когда Arrow не принадлежит [1..100]

Автор: S@nderS 12.7.2008, 01:40
Уже и так его вертел, и так... IndexOf этот... В итоге психанул и забыл сохранить  smile  Как сделать поиск с помощью него? Подскажите пожалуйста, а то сейчас бошка рванёт. smile 

Автор: THandle 12.7.2008, 05:40
Цитата(VICTAR @  11.7.2008,  14:32 Найти цитируемый пост)
Соответственно поиск логичней осуществлять с помощью  TStrings.IndexOf().


А если в StringGrid искомая строка встречается в одной строке несколько раз?

Тут IndexOf не подойдет... Или я еще не проснулся... Можно сделать как-нибудь так:


Код


type
  TCells = record
    Col: integer;
    Row: integer;
  end;

var
  FindArray: array of TCells;



На форме TStringGrid,TButton, TEdit, TMemo.

Просто для удобства.

Нажатие кнопки:
Код


procedure TForm1.Button1Click(Sender: TObject);
var
  i, j : integer;
  FindText : string;
  Count : integer;
begin
  Count := 0;
  FindText := Edit1.Text;
  SetLength(FindArray, StringGrid1.ColCount * StringGrid1.RowCount);
  for i := 0 to StringGrid1.RowCount - 1 do
    for j := 0 to StringGrid1.ColCount - 1 do
      if StringGrid1.Cells[j, i] = FindText then
        begin
          FindArray[Count].Col := j;
          FindArray[Count].Row := i;
          Inc(Count);
        end;
  SetLength(FindArray, Count - 1);
  for i := 0 to Length(FindArray) do
    Memo1.Lines.Add(IntToStr(FindArray[i].Col) + ', ' + IntToStr(FindArray[i].Row));
end;


Ищем текст, который введен в Edit, заносив все содержимое массива в Memo.

Автор: VICTAR 12.7.2008, 16:57
Цитата(THandle @  12.7.2008,  05:40 Найти цитируемый пост)
А если в StringGrid искомая строка встречается в одной строке несколько раз?

Не совсем понял, что не устраивает.
Цитата

if StringGrid1.Cells[j, i] = FindText then

А вот так не советую строки сравнивать, для этого есть спец функции CompareStr(), CompareText() ect

Автор: diamondd 13.7.2008, 09:22
хм.. а зачем вообще хранить найденные ячейки в массиве? если таблица будет большой, то каждый раз просматривать ее всю будет накладно. я набросал пример, посмотри.

кстати, реализовал почти все возможности поиска - с учетом регистра, поиск по фразе целиком, поиск вверх и вниз по таблице. 

Автор: S@nderS 16.7.2008, 02:21
Цитата(diamondd @ 13.7.2008,  07:22)
хм.. а зачем вообще хранить найденные ячейки в массиве? если таблица будет большой, то каждый раз просматривать ее всю будет накладно. я набросал пример, посмотри.

кстати, реализовал почти все возможности поиска - с учетом регистра, поиск по фразе целиком, поиск вверх и вниз по таблице.

Спасибо большое. Я использовал часть твоей процедуры... 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)