Поиск файлов + отображение в DBGrid

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Поиск файлов + отображение в DBGrid

Сообщение mrkaban » 17.12.2016 10:30:15

Здравтвуйте, Уважаемые форумчане! Сразу прошу прощения за глупые ошибки, так как новичок.

Есть дополнительная форма для программы, в которой пытаюсь реализовать поиск программ по файлам и папкам по названию из SQLite, если результат истина, тогда отображаю сведения о программе из SQLite базы. Но это если коротко)))

Проблемы встретил две! Не могу разобраться с поиском, а также с использованием в данном случае компонента TSelectDirectoryDialog.

Лучше будет, если я приведу код всей формы, там кроме этого, ничего другого нет.
Код: Выделить всё
unit RuchPoisk;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, sqlite3conn, sqldb, db, FileUtil, Forms, Controls,
  Graphics, Dialogs, StdCtrls, DBGrids, StrUtils;

type

  { TfRuchPoisk }

  TfRuchPoisk = class(TForm)
    bRuchPoisk: TButton;
    bUkazKatalog: TButton;
    DataSource3: TDataSource;
    DBGrid1: TDBGrid;
    SelectDirectoryDialog1: TSelectDirectoryDialog;
    SQLite3Connection1: TSQLite3Connection;
    SQLQuery3: TSQLQuery;
    SQLTransaction3: TSQLTransaction;
    procedure bRuchPoiskClick(Sender: TObject);
    procedure bUkazKatalogClick(Sender: TObject);
  private
    { private declarations }
  public
      path : TSelectDirectoryDialog; // ввёл для извлечения пути, который будет выбран в TSelectDirectoryDialog
    { public declarations }
  end;

var
  fRuchPoisk: TfRuchPoisk;
implementation

{$R *.lfm}

{ TfRuchPoisk }

procedure TfRuchPoisk.bRuchPoiskClick(Sender: TObject); //кнопка поиска
Var
  Info : TSearchRec; // используется для поиска
  nameProg : String; // в данный момент не используется
  put:string; // в неё хотел засунуть значение из path : TSelectDirectoryDialog
  s : String; // используется для построения запроса SQL
  i : integer; // используется как счетчик
  MyListRuch: TStringList; // нужно для получения значений из SQLite

Begin

MyListRuch:=TStringList.Create;
SQLQuery3.SQL.Clear;
SQLQuery3.SQL.Text:='select name from program';
SQLQuery3.Open;
SQLQuery3.First;
MyListRuch.clear;                   // пытался из базы получать список прог
while not SQLQuery3.Eof do
begin
  MyListRuch.Add(SQLQuery3.FieldByName('name').AsString);
  SQLQuery3.Next;
end;
SQLQuery3.Close;

with MyListRuch.Create do
try
MyListRuch.StrictDelimiter := true;
    s := '';
    put := path.FileName;
      showmessage(put);
  for i := 0 to MyListRuch.Count - 1 do if Trim(MyListRuch.Strings[i]) <> '' then
  s := MyListRuch.Strings[i];
//   showmessage(nameProg);
  If FindFirst(UTF8ToSys(put + s), faAnyFile or faDirectory, Info)= 0 then
    begin
//showmessage('Работает поиск');
    s := s + Format('%s(name LIKE "%s")', [IfThen(i = 0, '', ' OR '), MyListRuch.Strings[i]]);
    s := 'SELECT * FROM program WHERE ' + s + ' ORDER BY id';
  //     showmessage(s);
    end;
  FindClose(Info);
finally
  Free;
end;
SQLQuery3.Close;
SQLQuery3.Active:=false;
SQLQuery3.SQL.Clear;
SQLQuery3.SQL.Add(s);
SQLQuery3.Active:=true;
SQLQuery3.Open;



end;

procedure TfRuchPoisk.bUkazKatalogClick(Sender: TObject);
begin
//     пытаюсь получить каталог
path := TSelectDirectoryDialog.Create(Application);
if path.Execute then fRuchPoisk.Caption:= path.FileName;
FreeAndNil(path);
//    конец получения каталога
//showmessage(path.FileName);
end;

end.       


А вот данные по компонентам на форме, точнее их настройкам!
Код: Выделить всё
object fRuchPoisk: TfRuchPoisk
  Left = 251
  Height = 255
  Top = 212
  Width = 764
  ClientHeight = 255
  ClientWidth = 764
  LCLVersion = '1.6.0.4'
  object bRuchPoisk: TButton
    Left = 240
    Height = 25
    Top = 8
    Width = 75
    Caption = 'Поиск'
    OnClick = bRuchPoiskClick
    TabOrder = 0
  end
  object DBGrid1: TDBGrid
    Left = 0
    Height = 219
    Top = 40
    Width = 764
    Color = clWindow
    Columns = <>
    DataSource = DataSource3
    TabOrder = 1
  end
  object bUkazKatalog: TButton
    Left = 336
    Height = 25
    Top = 8
    Width = 104
    Caption = 'Указать каталог'
    OnClick = bUkazKatalogClick
    TabOrder = 2
  end
  object SQLite3Connection1: TSQLite3Connection
    Connected = False
    LoginPrompt = False
    DatabaseName = 'Lpro.db'
    KeepConnection = False
    CharSet = 'UTF8'
    Options = []
    left = 520
    top = 104
  end
  object SQLTransaction3: TSQLTransaction
    Active = False
    Database = fMian.SQLite3Connection1
    Options = []
    left = 624
    top = 104
  end
  object DataSource3: TDataSource
    DataSet = SQLQuery3
    left = 520
    top = 176
  end
  object SQLQuery3: TSQLQuery
    FieldDefs = <>
    Database = fMian.SQLite3Connection1
    Transaction = fMian.SQLTransaction1
    Options = []
    Params = <>
    left = 624
    top = 184
  end
  object SelectDirectoryDialog1: TSelectDirectoryDialog
    left = 664
  end
end         


Заранее благодарен за любую помощь!
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Поиск файлов + отображение в DBGrid

Сообщение Снег Север » 17.12.2016 11:17:38

Сразу одно замечание - в стандартном SQLite сравнение строк по LIKE работает только для латинского алфавита. Если нужна поддержка сравнения на других алфавитах, то надо либо найти сборку SQLite с поддержкой юникодного сравнения (такие есть, но надо поискать), либо использовать другую БД, где такое реализовано изначально.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2996
Зарегистрирован: 27.11.2007 16:14:47

Re: Поиск файлов + отображение в DBGrid

Сообщение mrkaban » 17.12.2016 20:43:42

Снег Север писал(а):Сразу одно замечание - в стандартном SQLite сравнение строк по LIKE работает только для латинского алфавита. Если нужна поддержка сравнения на других алфавитах, то надо либо найти сборку SQLite с поддержкой юникодного сравнения (такие есть, но надо поискать), либо использовать другую БД, где такое реализовано изначально.


Это интересно! Я об этом не знал, надо проверить! Спасибо большое!
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Поиск файлов + отображение в DBGrid

Сообщение Снег Север » 18.12.2016 08:14:23

Из официальной документации:
Important Note: SQLite only understands upper/lower case for ASCII characters by default. The LIKE operator is case sensitive by default for unicode characters that are beyond the ASCII range.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2996
Зарегистрирован: 27.11.2007 16:14:47

Re: Поиск файлов + отображение в DBGrid

Сообщение mrkaban » 18.12.2016 08:48:20

Снег Север писал(а):Из официальной документации:
Important Note: SQLite only understands upper/lower case for ASCII characters by default. The LIKE operator is case sensitive by default for unicode characters that are beyond the ASCII range.

А случайно, не сможете подсказать где найти сборку SQLite?

Правда, у меня русских названий в базе мало, но всё равно.

Мне бы еще разобраться с поиском и присвоением TSelectDirectoryDialog переменной для поиска. Там судя по showmessage проблемы начинаются еще до появления русский названий :cry:
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Поиск файлов + отображение в DBGrid

Сообщение Снег Север » 18.12.2016 09:36:57

К сожалению ссылка у меня затерялась - это было несколько лет назад, да и там тогда были далеко не самые свежие сборки.
Для поиска директорий/файлов используйте utf8 версии функций из FileUtil.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2996
Зарегистрирован: 27.11.2007 16:14:47

Re: Поиск файлов + отображение в DBGrid

Сообщение mrkaban » 24.12.2016 13:54:48

Я прошу прощения, я уже немного запутался.

If FindFirst(UTF8ToSys(put + s), faAnyFile or faDirectory, Info)= 0 then

В данном случае =0 означает, что если результатов нет, тогда выполнить действие? истина это ведь 1?

И правильно ли я понимаю, что "faAnyFile or faDirectory" означает, что он будет искать файлы и папки?

а правильно ли я делаю указывая тут UTF8ToSys(put + s) путь + приблизительное название файла или папки без расширения соответственно?

Прошу прощения за глупые вопросы.
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Поиск файлов + отображение в DBGrid

Сообщение Снег Север » 24.12.2016 16:31:18

Во-первых, настоятельно рекомендую использоватьFindFirstUTF8 и т.д. Во-вторых, FindFirst = 0 означает, что поиск завершился успешно и можно продолжать искать по FindNex.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2996
Зарегистрирован: 27.11.2007 16:14:47

Re: Поиск файлов + отображение в DBGrid

Сообщение mrkaban » 24.12.2016 16:49:22

Снег Север писал(а):Во-первых, настоятельно рекомендую использоватьFindFirstUTF8 и т.д. Во-вторых, FindFirst = 0 означает, что поиск завершился успешно и можно продолжать искать по FindNex.


Спасибо, изменю на FindFirstUTF8. FindFirst = 0 может ли это означать, что он нашёл файл?

и потом обязательно надо использовать FindNext, иначе следующий поиск не получится?
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Поиск файлов + отображение в DBGrid

Сообщение Снег Север » 24.12.2016 18:44:54

FindFirst и FindNext работают с незнамо какой версии паскаля. Часто их вызывают рекурсивно, для обхода вложенных директорий. UTF8 версии работают точно так же. Можно взять любой подходящий пример из паскаль/делфи. Например, этот:
http://www.delphibasics.ru/FindFirst.php
Не забудьте в конце поставить FindClose.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2996
Зарегистрирован: 27.11.2007 16:14:47

Re: Поиск файлов + отображение в DBGrid

Сообщение mrkaban » 24.12.2016 18:58:21

Снег Север писал(а):Не забудьте в конце поставить FindClose.


а в самом конце поиска или в конце итерации?
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18

Re: Поиск файлов + отображение в DBGrid

Сообщение Снег Север » 24.12.2016 20:35:15

mrkaban писал(а):а в самом конце поиска или в конце итерации?
По полному завершению поиска. Посмотрите примеры по моей ссылке.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 2996
Зарегистрирован: 27.11.2007 16:14:47

Re: Поиск файлов + отображение в DBGrid

Сообщение mrkaban » 24.12.2016 20:38:52

Снег Север писал(а):
mrkaban писал(а):а в самом конце поиска или в конце итерации?
По полному завершению поиска. Посмотрите примеры по моей ссылке.

Спасибо большое!!!
mrkaban
новенький
 
Сообщения: 55
Зарегистрирован: 28.05.2016 09:48:18


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: MailRu[bot], Yandex [Bot] и гости: 36

Рейтинг@Mail.ru