Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: ActiveX/СОМ/CORBA > Организация поиска текста в файле Excel


Автор: Dukalys 6.9.2010, 20:50
День добрый. Подскажите каким инструментом Delphi можно организовать поиск в Excel (2007), желательно с примером.

Поиск должен осуществляться ТОЛЬКО по столбцу A Excel, при этом, при нахождении нужного, необходимо записывать данные текущей строки из ячеек B, C в переменные/массив (неважно).
Результатом поиска является МНОЖЕСТВО строк. Хорошо бы если результатом поиска являлись бы строки или конкретные ячейки A101 ...

P.S. Перерыл кучу материала ( в том числе книг), нашёл следующее - 
http://it.kgsu.ru/DelCOM/com_0137.html - поиск определяет только найдено (true) или ненайдено (false) - а хочется номер ячейки ( лучше строки) - чегото материального.
http://www.delphi.int.ru/articles/10/ - поиск данных на листе, в конце интересный repeat until которого я непонимаю, может через него можно выйти на нужное мне.
http://zando.org.ru/content/view/28/31/ - тоже поиск данных, который резко оканчивается Find().Activate; что этот активейт, куда он что возвращает, для меня загадка.

На вашем форуме почитал темы интересные про работу с Excel, но тем с подробным решением данной задачи так и не нашёл.


Автор: Данкинг 6.9.2010, 21:17
Ну, проходи циклом по листу и ищи, что нужно. Способ медленный, но верный.

Автор: okkonst 6.9.2010, 22:34
а еще лучше - запиши макрос, который бы делал то, что тебе нужно (имеется ввиду - нажми "запись макроса" и соверши нужные действия), а сгенеренный код транслируй в дельфи. Там же отличный поиск есть...

Автор: Данкинг 6.9.2010, 23:15
Цитата(okkonst @ 6.9.2010,  23:34)
а еще лучше - запиши макрос, который бы делал то, что тебе нужно (имеется ввиду - нажми "запись макроса" и соверши нужные действия), а сгенеренный код транслируй в дельфи. Там же отличный поиск есть...

Согласен, это ещё лучше: я сиё предположил, но не стал пока озвучивать.

Автор: Dukalys 7.9.2010, 06:32
Ребят спасиб. С макросами я ещё не работал, если честно то даже ммм не представляю что придётся делать. можете это описать как-то. как придётся транслировать ...

А что касается цикла с проверкой каждой ячейки совпадает ли значение (true) то это наверное долго - в файле Excel 200 000 строк. и перебирать в цикле и обращаться к каждой ячейке это жёстко.

P.S. Возможно ли все данные их Excel как-то по-умному рассовать по массивам в Дельфи ? (получается 3 столбца(массива) of String по 200 000) так чтобы вначале программы это заняло секунд 15-20 или меньше. Мне кажется что потом в итоге это съэкономит кучу времени и сил. спасибо за ответы.



Автор: Albinos_x 7.9.2010, 14:12
Цитата(Dukalys @  6.9.2010,  20:50 Найти цитируемый пост)
Ссылка3 - тоже поиск данных, который резко оканчивается Find().Activate; что этот активейт, куда он что возвращает, для меня загадка.

выделяется найденная ячейка

координаты можно получить дав команды в стиле:
Код

column:= ExcelWorksheet1.Columns.Column; 
row:=ExcelWorksheet1.Rows.Row;

Автор: Dukalys 7.9.2010, 21:14
Попробовал ...
Итого - не работает.
подробнее:

Выдержки из первоисточника (книги):

1. "Если задана область ячеек и получена ссылка на неё, то количество столбцов будет определяться свойством Count коллекции Columns объекта Range, а количество строк - свойством Count коллекции Rows объекта Range". Доступ ко всем строкам и столбцам листа рабочей книги предоставляют коллекции Rows и Columns объекта ActiveSheet - активного листа рабочей книги.


2. "Мы определились, что ячейка всегда определяется объектами Range или Cells"

Такая многозначность + отсутствие в Delphi предввода методов, свойств (Excel. пусто) для работы с Excel меня загоняет в тупик.

Код

FindRange := WB.ActiveSheet.Cells.Find(What:=Edit2.Text).Activate; //находит и выделяет

Form1.Edit3.Text := IntToStr(WB.ActiveSheet.Rows.Row); //ролсрой
Form1.Edit4.Text := IntToStr(WB.ActiveSheet.Columns.Column);

Form1.Edit5.Text := IntToStr(WB.ActiveSheet.Cells.Row);
Form1.Edit6.Text := IntToStr(WB.ActiveSheet.Cells.Column);


Во всех эдитах значение = 1   (реальное расположение ПРАВИЛЬНО НАЙДЕННОЙ И ВЫДЕЛЕННОЙ ячейки = 'B3'=(2,3))

Методом подбора - получить какое либо свойство из FindRange (типа Row) так и не получилось.

Выкладываю пример программы - теста, с которой работаю. за основу взята криво написанная (в том числе и мной) программа из нета и неудачно адаптирована под поиск координат ячейки.

прога прикреплена.






P.S. есть у когонить идеи по этому поводу ??? Я в нете коечто нарыл - http://citforum.ru/programming/windows/excel_faq/part3.shtml#3.06 Похоже от туда можно коечто выдернуть, через 2 часика проверю и отпишусь.

Автор: Albinos_x 8.9.2010, 13:39
сделай так, это самый простой вариант:
Код
...
 Form1.Edit3.Text := E.ActiveCell.Row;
 Form1.Edit4.Text := E.ActiveCell.Column;
...

Автор: Dukalys 8.9.2010, 14:36
Цитата

...
 Form1.Edit3.Text := E.ActiveCell.Row;
 Form1.Edit4.Text := E.ActiveCell.Column;
...


Оргомное спасибо код работает !!!


Ребят а вот смотрите заметил какую особенность при выполнении метода "Find" для Cells и для Range

Код
 FindRange := WB.ActiveSheet.Cells.Find(What:=Edit2.Text).Activate; 


Выделяет правильную ячейку 3,2

Код
 FindRange := WB.ActiveSheet.Range[Edit1.Text].Find(What:=Edit2.Text).Activate; 


Выделяет 4 ячейку вместо третьей и по выше приведённых свойствам возвращает 4,2

ну наверно можно просто -1 делать от значения Row ? или это особенность какаято ?



Автор: Albinos_x 9.9.2010, 13:33
Цитата(Dukalys @  8.9.2010,  14:36 Найти цитируемый пост)
ну наверно можно просто -1 делать от значения Row ? или это особенность какаято ?

Это если запускать в любой последовательности???

Автор: Dukalys 9.9.2010, 18:29
Несовсем догоняю что имеете ввиду здесь про последовательность (начало поиска - с начала документа или конца ?). результат поиска с начала документа - искомой строки, ссылается на последующую строку, вродебы всё время ...

Автор: Albinos_x 13.9.2010, 08:01
хм... у тебя в приложенном проекте, если не ошибаюсь, было 2 кнопки, где реализовано 2-мя способами поиск, вот я и спрашиваю в какой последовательности запускаешь...

Автор: Deeptown12 26.4.2017, 13:12
Код

Function FindValueInCell(ExcelWS : TExcelWorksheet; What : string; var CellsFound : TList<TPositionCell>) : Boolean;
var
Found : ExcelRange;
Addr, Addr2 : String;
Position : TPositionCell;
begin
 Result := False;
 //Выполняем поиск в пределах используемого дипазона.
 //Поиск. MatchCase:=False - поиск не зависит от регистра букв.
 // xlPart - по сопадению
 // xlWhole - точное
 Found := ExcelWS.Cells.Find(What, EmptyParam, xlValues, xlWhole, xlByRows, xlNext, False, EmptyParam);
 if Assigned(Found) then
 begin
   Result := True;
   Addr   := Found.Address[True, True, xlA1, EmptyParam, EmptyParam];
   Position.Col  := Found.Column;
   Position.Row  := Found.Row;
   CellsFound.Add(Position);
   repeat
       Found := ExcelWS.Cells.FindNext(Found);
       if Assigned(Found) then
       begin
          Addr2  := Found.Address[True, True, xlA1, EmptyParam, EmptyParam];
          // адрес совпал (круг завершен)
          if SameText(Addr, Addr2) then Break;

          Position.Col  := Found.Column;
          Position.Row  := Found.Row;
          CellsFound.Add(Position);
       end;
   // выход если не найдено
   until not Assigned(Found)
 end;
end;

Procedure Find;
var
 ListCellFound : TList<TPositionCell>;
 I, Row, Col : Integer;
begin
 ListCellFound := TList<TPositionCell>.Create;
 if FindValueInCell(ExcelWS, 'Что искать', ListCellFound) then
 begin
    for I := 0 to ListCellFound.Count-1 do
    begin
        Col := ListCellFound.Items[I].Col;
        Row := ListCellFound.Items[I].Row;
    end;
 end;
 if Assigned(ListCellFound) then FreeAndNil(ListCellFound);
end;

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