Студопедия
Случайная страница | ТОМ-1 | ТОМ-2 | ТОМ-3
АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Требования к отчету по лабораторной работе №3.

Читайте также:
  1. II. ТРЕБОВАНИЯ К МЕСТУ ДЛЯ РАЗБИВКИ ЛАГЕРЯ
  2. II. Требования к оформлению статьи
  3. III. ОПИСАНИЕ ЛАБОРАТОРНОЙ УСТАНОВКИ
  4. III. Требования к организации и проведению работ по заготовке древесины
  5. IV. ТРЕБОВАНИЯ К ВОДОСНАБЖЕНИЮ В ЛАГЕРЕ
  6. Nbsp;   Схема лабораторной установки
  7. V. ТРЕБОВАНИЯ К ОРГАНИЗАЦИИ ПИТАНИЯ. ЛИЧНОГО СОСТАВА В ЛАГЕРЕ

Отчет должен содержать:

1. Тексты обработчиков событий OnShow и OnClose главной формы приложения.

2. Тексты процедур расчета интегральных показателей.

3. Все экранные формы работающего приложения и тексты процедур обработки нажатия всех кнопок.

Замечание: приводимые в отчетах фрагменты программного кода должны содержать необходимые комментарии.


4. ЛАБОРАТОРНАЯ РАБОТА №4

 

Тема работы: фильтрация и поиск в наборах данных.

Длительность работы: 8 академических часов.

 

5.1. ФИЛЬТРАЦИЯ НАБОРОВ ДАННЫХ

 

Фильтрация - это отображение в НД только тех записей, которые удовлетворяют определенному условию (фильтру).

Для осуществления фильтрации в TDataSet используются свойства: Filter, FilterOptions, Filtered и событие OnFilterRecord.

В свойстве Filter указывается условие фильтрации в виде строки SQL-подобного синтаксиса. В этой строке могут использоваться только имена полей, литералы (явно заданные значения), операторы отношения (>, <, <=, =>,<> ), а также логические операторы (OR, AND, NOT). Переменные, объявленные в программе, здесь использовать нельзя.

Например, для показа только тех проводок, в которых передающим было лицо с условным номером 1, а принимающим – с номером 3, фильтр следует задать следующим образом:

 

DM.ProvodkiT.Filter := ’([Rashod]=1) AND ([Prihod]=3)’;

 

Свойство FilterOptions устанавливает режимы выполнения фильтрации для условия Filter (и только для него). Можно указать два режима:

foCaseInsensitive - игнорирование регистра букв;

foNoPartialCompare - поиск по точному соответствию. Если этот режим выключен (foNoPartialCompare = False), то в фильтре можно использовать символ ‘*’ для указания произвольного числа любых символов. Например, для выбора всех лиц, наименование которых начинается с «Ив», «ИВ», «ив», следует задать фильтр:

 

DM.LicoTb.Filter:=’[Name]=”ИВ*”’;

 

с включенной опцией foCaseInsensitive и выключенной foNoPartialCompare.

Гораздо большие возможности фильтрации представляет обработчик события OnFilterRecord. Его процедура имеет два параметра: имя фильтруемого НД и параметр Accept. В отфильтрованный НД включаются только те записи, для которых в теле процедуры Accept будет установлен в True. Приведенный выше пример можно переписать следующим образом:

 

procedure DM.ProvodkiT.FilterRecord(DataSet: TDataSet;

var Accept: Boolean);

begin

Accept := (DataSet[‘Rashod’]=1) AND (DataSet[‘Prihod’]=3);

end;

 

Следует отметить, что обработчик OnFilterRecord представляет более гибкие возможности для фильтрации НД, чем свойство Filter. В частности, в нем можно использовать и программные переменные.

Свойство Filtered используется для включения/выключения фильтрации. Причем это касается фильтрации, заданной как в свойстве Filter, так и в обработчике OnFilterRecord.

Замечание1: фильтры в свойстве Filter и обработчике OnFilterRecord могут использоваться одновременно. Соответственно, в отфильтрованный НД будут включаться записи, удовлетворяющие обоим условиям фильтрации.



Замечание2: в условия фильтрации могут включаться любые поля, в том числе и те, по которым индексы не строились. Как следствие, фильтрация может потребовать полного перебора всех записей НД. Поэтому использовать в фильтрах неиндексированные поля для больших НД следует с осторожностью, чтобы не замедлить работу с БД. Для ускорения фильтрации можно использовать метод SetRange компонента TTable, который работает только с индексированными полями.

Приведем пример использования фильтрации. Необходимо на форме с таблицей лиц (рис. 27) показывать лица только определенного типа (тип выбирается с помощью RadioGroup), если отмечен соответствующий CheckBox.

 

// Процедура включения/выключения фильтрации

procedure TMainForm.TipCheckBoxClick(Sender: TObject);

begin

DM.LicaT.Filtered := TipCheckBox.Checked;

end;

 

// Процедура задания фильтра

procedure TMainForm.TipRadioGroupClick(Sender: TObject);

begin

DM.LicaT.Filtered := false; // Выключаем фильтрацию

case TipRadioGroup.ItemIndex of // Задаем фильтр

0: DM.LicaT.Filter := '[Tip]=2';

1: DM.LicaT.Filter := '[Tip]=1';

2: DM.LicaT.Filter := '[Tip]=3';

else DM.LicaT.Filter := '';

end;

// Восстанавливаем состояние фильтрации

Загрузка...

DM.LicaT.Filtered := TipCheckBox.Checked;

end;

 

 

Рис. 27. Фильтрация таблицы лиц

 

Задание.

1. Подумайте, какие фильтры были бы полезны для пользователей Вашего приложения. Реализуйте их. Тексты процедур и соответствующие экранные формы включите в отчет.


5.2. ПОИСК В НАБОРАХ ДАННЫХ

 

Как для компонента TDataSet в целом, так и для компонента TTable в частности реализовано несколько методов поиска, позволяющих найти нужную запись в наборе данных по значениям ее полей. Рассмотрим некоторые из этих методов.

Метод Locate – общий для всех потомков TDataSet. Он ищет первую запись, имеющую искомые значения полей. Если такая запись найдена, то делает ее текущей и возвращает True, иначе False. Метод определяется следующим образом:

 

function Locate(const KeyFields: string;

const KeyValues: Variant;

Options: TLocateOptions): Boolean;

 

Параметр KeyFields содержит список имен полей, по которым производится поиск. Имена в списке разделяются точкой с запятой.

Параметр KeyValues - вариантный массив, который содержит искомые значения. Первое значение для первого поля из списка KeyFields, второе – для второго и т.д.

Параметр Options указывает условия поиска:

loCaseInsensitive - игнорирование регистра букв;

loPatrtialKey - поиск по частичному соответствию, то есть могут быть заданы только начальные символы значения (здесь символ ‘*’ не используется).

Для примера реализуем с помощью рассмотренного метода поиска процедуру выполнения проводки. В качестве параметров этой процедуре передаются условные номера лица расхода, лица прихода и передаваемого предмета, а также его количество и дата проводки. Предполагается, что эти параметры были предварительно проверены на допустимость проводки, т.е. на соответствие всем бизнес-правилам.

Необходимо: у передающего лица (если это подотчетное лицо) уменьшить наличие передаваемого предмета. Если в результате выполнения проводки у передающего лица не останется указанных предметов, то соответствующая строка из таблицы наличия должна быть удалена. У принимающего лица (если это подотчетное лицо) надо увеличить наличие передаваемого предмета. Если у него не было таких предметов, то следует добавить в таблицу наличия соответствующую строку. Наконец, информация о выполненной проводке должна быть записана в таблицу проводок.

 

procedure DoProvod(rashod, prihod, predmet: integer; kolvo: double; data: TDateTime);

begin

// Ищем лицо расхода в таблице лиц

if DM.LicaT.Locate('NLic', rashod, []) then

if DM.LicaTTip.AsInteger = 2 then // Если это п/о лицо

// Ищем у него наличие передаваемого предмета

if DM.NalichieT.Locate('Lico;Predmet', VarArrayOf([rashod, predmet]), []) then

// Если у него предметов больше, чем надо передать

if DM.NalichieTKolvo.AsFloat > kolvo then

begin // Уменьшаем наличие

DM.NalichieT.Edit;

DM.NalichieTKolvo.AsFloat := DM.NalichieTKolvo.AsFloat - kolvo;

DM.NalichieT.Post;

end

else // Иначе удаляем строку наличия

DM.NalichieT.Delete

else

begin

ShowMessage('Ошибка при поиске наличия у лица расхода');

exit;

end

else

else

begin

ShowMessage('Ошибка при поиске лица расхода');

exit;

end;

// Ищем лицо прихода в таблице лиц

if DM.LicaT.Locate('NLic', prihod, []) then

if DM.LicaTTip.AsInteger = 2 then // Если это п/о лицо

// Ищем у него наличие передаваемого предмета

if DM.NalichieT.Locate('Lico;Predmet', VarArrayOf([prihod, predmet]), []) then

begin // Если предмет есть в наличии, то увеличиваем его кол-во

DM.NalichieT.Edit;

DM.NalichieTKolvo.AsFloat := DM.NalichieTKolvo.AsFloat + kolvo;

DM.NalichieT.Post;

end

else

begin // Иначе добавляем строку в наличие

DM.NalichieT.Insert;

DM.NalichieTLico.AsInteger := prihod;

DM.NalichieTPredmet.AsInteger := predmet;

DM.NalichieTKolvo.AsFloat := kolvo;

DM.NalichieT.Post;

end

else

else

begin

ShowMessage('Ошибка при поиске лица прихода');

exit;

end;

// Добавляем проводку в таблицу проводок

DM.ProvodkiT.Insert;

DM.ProvodkiTRashod.AsInteger := rashod;

DM.ProvodkiTPrihod.AsInteger := prihod;

DM.ProvodkiTPredmet.AsInteger := predmet;

DM.ProvodkiTKolvo.AsFloat := kolvo;

DM.ProvodkiTData.AsDateTime := data;

DM.ProvodkiT.Post;

end;

 

Замечание: поиск методом Locate возможен по любым полям, в том числе и по неиндексированным. Если индексы есть, то они используются. Если есть несколько индексов по полям поиска, то предсказать какой из них будет использован нельзя. Поэтому если искомое значение содержится в нескольких записях, то предсказать какая из записей будет найдена первой нельзя. При отсутствии индексов метод работает медленно, поскольку выполняет последовательный перебор записей.

Помимо методов для TDataSet в TTable могут использоваться методы FindKey и FindNearest. Поиск этими методами возможен только по полям текущего индекса. Допустим поиск и по части полей, но эти поля должны быть ведущими и следовать подряд.

Метод FindKey определяется следующим образом:

 

function FindKey(const KeyValues: array of const): boolean;

 

Он ищет первую запись, у которой значение индексных полей точно совпадают с искомыми значениями в KeyValues. Если запись найдена, то курсор перемещается на нее и метод возвращает True. В противном случае – False и курсор не перемещается.

Метод FindNearest рассчитан на приближенный поиск. В начале он делает попытку найти запись, точно соответствующую искомым значениям. Если запись найдена, то происходит перемещение курсора в зависимости от свойства НД KeyExclusive. Если оно – False (по умолчанию), то курсор переходит на найденную запись. Если же True, то на запись, следующую за найденной.

Если точно соответствующая запись не найдена, курсор перемещается на запись с ближайшим большим значением индексных полей. Причем сначала происходит наращивание значения самого внутреннего поля в индексе.

С помощью метода FindNearest легко реализуется так называемый инкрементальный локатор – это механизм поиска записей в НД, при котором поиск производится по мере ввода искомого значения. Для ввода значения может быть использован, например, компонент TEdit.

Пусть НД LicaT отсортирован по индексу, построенному по полю Name и содержит записи со следующими лицами:

 

Афанасьев

. . .

Лосев

Малов

Молотов

Мосин

. . .

 

Тогда после ввода в TEdit буквы ‘М’ текущей должна стать запись ‘Малов’; после ввода ‘Мо’ – ‘Молотов’; после ‘Мос’ - ‘Мосин’ и т.д.

Такой алгоритм можно реализовать, например, с помощью следующего обработчика события OnChange компонента TEdit:

 

procedure TForm1.Edit1Change(Sender: TObject);

begin

DM.LicaT.FindNearest([Edit1.Text]);

end;

 

При реализации инкрементального локатора можно обойтись и без TEdit. Например, если DBGrid не используется для непосредственной модификации НД, то локатор можно реализовать в обработчике события OnKeyPress соответствующего компонента TDBGrid. Тогда (если фокус ввода принадлежит DBGrid) при наборе символов будет происходить перемещение к требуемой строке.

Для наглядности вводимые символы можно отображать в какой-либо метке. А для простоты перехода к новому поиску – сбрасывать введенное значение с некоторой задержкой. Например, сбрасывать его по истечении 2 секунд после ввода последнего символа.

 

Задание.

2. Подумайте, какие операции будут выполнять пользователи с помощью Вашего приложения, какие обработки хранимой информации им понадобятся, какие преобразования и т.д., т.е. каково будет функциональное наполнение Вашего приложения. Как обеспечить максимальное удобство работы с Вашим приложением. В частности, предусмотрите инкрементальные локаторы в тех таблицах, где они будут полезны пользователям. Обсудите свои идеи с преподавателем. Реализуйте полномасштабное приложение с использованием полученных навыков.


Дата добавления: 2015-07-07; просмотров: 118 | Нарушение авторских прав


<== предыдущая страница | следующая страница ==>
Требования к отчету по лабораторной работе №2.| Требования к отчету по лабораторной работе №4.

mybiblioteka.su - 2015-2021 год. (0.072 сек.)