На главную   На главную   Форумы Новости Документация Скачать Купить  
Регистрация  
Система Allegro
Oб Allegro Характеристики Пример конфигурации Документация База ошибок Развитие
Версия для печати К списку книг Вернуться к оглавлению Предыдущий параграф Следующий параграф
Поиск по книге

Глава 5. СОЗДАЕМ ОКОННЫЙ ИНТЕРФЕЙС «ПОСТУПЛЕНИЯ НА СКЛАД»

Организуем поиск товаров «по нажатию клавиш»

Из бесед с заказчиком нам известно, что справочник товаров не так часто пополняется новыми позициями. Во всяком случае , непосредственно при вводе поступления на склад новые товары в справочнике, как правило, не создаются. Поэтому мы организуем интерфейс ввода, ориентированный не столько на добавление новых , сколько на максимально быстрый поиск уже имеющихся товаров. Известно, что заказчик использует локальную сеть 100 Mbit. Это позволяет нам организовать очень быстрый поиск, работающий практически мгновенно после нажатия каждой клавиши. Например, если пользователь нажмет букву «с», то сразу появляется список всех товаров, содержащих букву «с» в наименованиях. Если он после этого нажмет букву «т», то остаются все товары, содержащие в наименованиях подстроку «ст ». Если он введет следующую комбинацию букв после пробела, то наш поиск отберет наименования по одновременному вхождению в них обеих комбинаций: до и после пробела. Если пользователь хочет быстро отыскать все стиральные машины BOSCH, то ему достаточно будет набрать «ст bos» и, скорее всего, в списке останутся только стиральные машины BOSCH. Практика показывает, что этот способ поиска наименований чрезвычайно эффективен и позволяет с огромной скоростью набирать документы. К тому же способ поиска «по вхождению» в наименования очень гибок: если пользователю известен артикул товара, то достаточно набрать артикул, Если же он хочет увидеть все товары какого-то вида, например, «вытяжки» достаточно набрать «выт» или доже просто букву « ж», так как в других наименованиях эта буква не встречается. С таким же успехом можно найти все товары с маркой AEG, набрав «aeg». SQL- Запрос, осуществляющий поиск по вхождению, использует конструкцию

SELECT * FROM <таблица>
WHERE	(UPPERCASE(<поле>) LIKE ‘%<ПРИЗНАК1>%’) AND
(UPPERCASE(<поле>) LIKE ‘%<ПРИЗНАК2>%’) AND
и так далее…

Для реализации «поиска по вхождению» имеется специальный компонент -сетка DBGridA с палитры Allegro, который мы использовали в качестве сетки для позиций документа. В отличие от простой сетки (DBGrid с палитры Data Controls) сетка DBGridA имеет специальное событие OnSetEditText, которое происходит после нажатии каждой клавиши в режиме редактирования и в строковом параметре Value передает текущий в ячейке текст в обработчик. Вызвав в этом обработчике SQL-запрос, осуществляющий поиск по вхождению , мы сможем отобразить результаты поиска во второй сетке ( нижней) и дать возможность пользователю вставить найденный товар в основную сетку.

Итак, добавим на форму компонент IBQuery с палитры InterBase . Назовем его qryGoods , установим свойство:

Transaction = traCurrent

а в свойстве SQL напишем запрос:

SELECT O1.OBJECT_ID, O1.SHORT_NAME
FROM GOODS G, OBJECT_NAMES O1
WHERE G.ID = O1.OBJECT_ID

Этот SQL-запрос запрашивает все наименования товаров из таблицы OBJECT_NAMES, он нужен нам лишь для того , чтобы создать «постоянные» поля у компонента запроса и настроить колонки нижней сетки. Щелкнем дважды на компоненте qryGoods и в редакторе полей добавим все поля с помощью соответствующего пункта контекстного меню. Для поля SHORT_NAME установим свойство:

DisplayLabel = Наименование

Добавим компонент DataSource с палитры InterBase (или Data Access ) , назовем его dsrGoods и установим его свойство:

DataSet = qryGoods

У нижней сетки dbgGoods установим

DataSource = dsrGoods

а в свойстве Options установим птичку на dgRowSelect.

Теперь создадим еще «постоянную» колонку у нижней сетки dgbGoods. Для этого вызовем редактор свойства Columns, дважды щелкнув на нем в Инспекторе объектов, добавим в список одну колонку и установим в Инспекторе объектов ее свойство:

FieldName = SHORT_NAME

Откроем запрос, установив свойство Active = True. Убедимся , что список всех наименований товаров появился в нижней сетке :



Закроем запрос, установив

Active = False

Теперь для сетки позиций документа dbgDetail создадим обработчик события OnSetEditText :

{Поиск по нажатию любой клавиши в сетке позиций}
procedure TStockInForm.dbgDetailSetEditText(Sender: TObject; ACol, ARow: Integer;
     const Value: String);
var
  s: string;
begin
  if Value = LastValue then
    exit; //защита от повторного поиска по тем же признакам
  if dbgDetail.SelectedField <> qryDetail.FieldByName('ITEM_NAME') then
    exit; //ограничение поиска нажатием клавиш в поле "Наименование"
  LastValue := Value;
  {Конструирование запроса из строки признаков, разделенных пробелами}
  s := 'SELECT O1.OBJECT_ID, O1.SHORT_NAME'#13+
       'FROM GOODS G, OBJECT_NAMES O1'#13+
       'WHERE G.ID = O1.OBJECT_ID AND O1.OBJECT_ID <> 0';
  if Value <> '' then
    s:=Format('%s AND'#13'%s',[s, StrToVarcharFilter('O1.SHORT_NAME','',Value)]);
  ResetCurrentTime; //сброс счетчика времени
  {включение светодиода в статусной строке Allegro}
  StatusBarDisplay(clLime,0,0,0,'','','');
  with qryGoods do
  begin
    Close;
    SQL.Text := s;
    Open; //открытие запроса
  end;
  {отображение в статусной строке времени, затраченного на поиск}
  StatusBarDisplay(clBlack,0,0,0,GetCurrentTimeStr,'','');
end;

В секцию var в разделе implementation модуля StockIn добавим объявление переменной:

  LastValue: string;

Добавим также в обработчик события AfterInsert компонента qryDetail строки, выделенные здесь жирным шрифтом:

procedure TStockInForm.qryDetailAfterInsert(DataSet: TDataSet);
begin
  if not lock_insert then
  begin
    lock_insert := True;
    qryDetail.Cancel; //отменяем режим вставки
    qryDetail.Append; //вставляем в конец набора
    LastValue := '';
    dbgDetail.SelectedField := qryDetail.FieldByName('ITEM_NAME');
                     //перемещаем фокус ввода в поле наименования
  end;
  lock_insert := False;
end;

Создадим у сетки позиций dbgDetail обработчик события OnKeyPress, для того, чтобы при нажатии пользователем клавиши Enter фокус ввода из сетки позиций перемещался бы в сетку найденных наименований товаров :

{Нажатие клавиш Enter в списке позиций}
procedure TStockInForm.dbgDetailKeyPress(Sender: TObject; var Key: Char);
begin
  if (Key = 13) and not qryGoods.IsEmpty then
    dbgGoods.SetFocus; //Перемещение фокуса ввода в нижний список
end;

После того, как пользователь выберет в нижней сетке нужный товар, он двойным щелчком мыши на нем или нажатием клавиши Enter скопирует его в сетку позиций. При этом фокус ввода переместится обратно в сетку позиций. Реализуем это в виде двух обработчиков для нижней сетки dgbGoods. Сначала создадим обработчик для двойного щелчка мыши OnDblClick:

{Копирование позиции из нижнего списка товаров двойным щелчком мыши}
procedure TStockInForm.dbgGoodsDblClick(Sender: TObject);
begin
  qryDetail.Edit; {Присвоение значений полям позиции}
  qryDetail.FieldByName('GOODS').AsInteger :=
     qryGoods.FieldByName('OBJECT_ID').AsInteger;
  qryDetail.FieldByName('ITEM_NAME').AsString :=
     qryGoods.FieldByName('SHORT_NAME').AsString;
  LastValue := qryDetail.FieldByName('ITEM_NAME').AsString;
  dbgDetail.SelectedField := qryDetail.FieldByName('QUANTITY');
  dbgDetail.SetFocus; //Возвращение фокуса ввода в сетку позиций
end;

А теперь создадим обработчик OnKeyPress:

procedure TStockInForm.dbgGoodsKeyPress(Sender: TObject; var Key: Char);
begin
  if Key = 13 then
    dbgGoodsDblClick(nil) // Выбор и добавление товара в сетку позиций на Enter
  else if Key = 27 then
    dbgDetail.SetFocus; //Простое возвращение фокуса ввода в сетку позиций на Esc
end;

Для отображения подсказки при наведении курсора мыши на нижнюю сетку dbgGoods, установим у нее свойства:

Hint = Для перемещения в этот список нажмите Enter

Для выбора из этого списка также нажмите Enter

ShowHint = True

Теперь запустим проект и последовательно выполним следующие действия:

  • Выберем нижнюю позицию в документе
  • Нажмем на клавиатуре «стрелку вниз». Должна добавиться пустая строка, а фокус ввода должен оказаться в поле « Наименование»
  • Наберем с клавиатуры две буквы: bo. В сетке наименований должны остаться только товары марки BOSCH:

  • Нажмем клавишу «пробел» и после него нажмем русскую букву ф. В сетке наименований должны остаться только кофеварки BOSCH. Нажмем клавишу Enter. Фокус ввода должен переместиться в сетку наименований. Выберем нужную кофеварку из списка, перемещаясь по списку клавишами «стрелка вверх» и « стрелка вниз»
  • Нажмем еще раз клавишу Enter. Выбранный из списка товар вставится в текущую позицию документа, а фокус ввода вернется в сетку позиций и переместится в ячейку «Количество», ожидая ввода пользователем количества выбранного товара.
  • Вводим количество и нажимаем клавишу «стрелка вправо» для того, чтобы перейти в ячейку, в которой вводится цена.
  • Введем цену и нажмем клавишу «стрелка вниз». Нажатие этой клавиши приведет к посылке всей набранной позиции на сервер , а в сетку добавится новая пустая позиция.
  • Для отмены добавления/редактирования очередной позиции нужно нажать клавишу Escape 2 раза. Первое нажатие отменяет редактирование ячейки, второе – редактирование всей строки.
  • Сохранение документа производится нажатием кнопки с дискетой или комбинации горячих клавиш Ctrl+S.


 
 




              


Пример создания склада в Allegro Наверх