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

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

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

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

1. Списки полей всех используемых в Вашей базе наборов данных с подробным описанием вновь созданных вычисляемых и Lookup полей.

2. Тексты всех обработчиков событий OnCalcFields.

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

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

 

Тема работы: общие принципы работы с наборами данных в приложениях баз данных, создаваемых в среде Delphi.

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

 

4.1. СОСТОЯНИЯ НАБОРОВ ДАННЫХ

 

Набор данных может находиться в одном из семи состояний:

dsInactive - набор данных закрыт: возможны действия только в отношении всего НД (его удаление или создание); доступ к отдельным записям не возможен;

dsBrowse - состояние просмотра (в это состояние НД переводится после открытия); возможны любые перемещения по НД;

dsEdit - состояние редактирования текущей записи;

dsInsert - состояние добавления новой записи;

dsSetKey - состояние поиска записи; по окончании поиска НД переходит в состояние dsBrowse;

dsCalcFields - состояние расчета вычисляемых полей; по окончании расчета НД переходит в состояние, которое имело место до перехода в dsCalcFields; в этом состоянии могут изменяться только вычисляемые поля;

dsFilter - состояние фильтрации: обработчик OnFilterRecord проверяет, удовлетворяет ли текущая запись условиям фильтрации; по окончании НД переходит в состояние dsBrowse.

Основные приемы перехода между состояниями:

 

dsInactive → dsBrowse

Метод Open (Например: LicaT.Open; - открыть таблицу лиц);

Свойство Active (LicaT.Active:= true;- эквивалентно предыдущему)

 

dsBrowse → dsInactive

Метод Close (LicaT.Close; - закрыть таблицу лиц);

Свойство Active (LicaT.Active:= false;).

 

Замечание: если в момент закрытия набор данных находится в состоянии dsEdit или dsInsert, то внесенные изменения будут утрачены. В частности, если редактирование допускается непосредственно в TDBGrid, то перед закрытием НД следует проверить – не находится ли он в состоянии редактирования, чтобы пользователь не потерял последние исправления.

 

dsBrowse → dsEdit

Метод Edit (LicaT.Edit; - перейти в режим редактирования текущей записи таблицы лиц).

 

Замечание: метод Edit может вызываться не явно. Например, при редактировании в TDBGrid.

 

dsEdit → dsBrowse

Метод Post (LicaT.Post; - подтверждение изменений, внесенных в текущую запись таблицы лиц);

Метод Canсel (LicaT.Cancel; - отмена изменений).

 

Замечание: эти методы также могут вызываться неявно. Например, при переходе между строками в TDBGrid или при нажатии клавиши Esc.

 

dsBrowse → dsInsert

Метод Insert (LicaT.Insert; - вставка новой записи после текущей);

Метод Append (LicaT.Append; - вставка новой записи в конец НД).

Замечание: методы могут вызываться неявно.

 

dsInsert→ dsBrowse

Метод Post (подтверждение изменений в текущей записи);

Метод Cancel (отмена изменений).

 

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

Например, перед началом выполнения каких-либо действий в НД следует проверить, открыт ли он:

 

if not LicaT.Active then LicaT.Open;

 

поскольку попытка выполнения действий в закрытом НД повлечет ошибку.

Перед закрытием формы с возможностью редактирования в TDBGrid следует проверить, не находится ли НД в состоянии редактирования:

 

if LicaT.State in [dsEdit, dsInsert] then LicaT.Post;

 

Задание.

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

 

4.2. НАВИГАЦИЯ ПО НАБОРАМ ДАННЫХ

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

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

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

Для перемещения по набору данных (изменения текущей записи; перемещения курсора) могут использоваться следующие методы:

First - перейти на первую запись;

Last - перейти на последнюю запись;

Next - перейти к следующей записи;

Prior - перейти к предыдущей записи;

MoveBy(n: integer) - перейти на n записей к концу НД при n > 0, или к началу НД при n < 0.

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

BOF - начало НД. Устанавливается в true, если НД пуст, а также после выполнения метода First или метода Prior, когда текущей является первая запись;

EOF - конец НД. Устанавливается в true, если НД пуст, а также после выполнения метода Last или метода Next, когда текущей является последняя запись.

Приведем пример использования методов навигации по наборам данных.

Пусть необходимо на форме с таблицей подразделений (рис. 22) по нажатию некоторой кнопки (SummBtn) необходимо выводить в некоторую метку (SummLbl) общую сумму предметов, имеющихся в наличии у подотчетных лиц, работающих в выбранном подразделении. И пусть в наборе данных, связанном с таблицей наличие, имеется Lookup поле Cena, извлекающее цену предметов из таблицы предметов. Тогда реализовать требуемые действия можно в виде следующей процедуры:

 

procedure TForm1.SummBtnClick(Sender: TObject);

var

s: currency;

begin

// Открываем используемые наборы данных

if not LicaT.Active then LicaT.Open;

if not PredmetyT.Active then PredmetyT.Open;

if not NalichieT.Active then NalichieT.Open;

s:= 0; // Очищаем аккумулятор

LicaT.First; // Переходим в начало таблицы лиц

while not LicaT.Eof do // Перебираем все записи таблицы лиц

begin

// Если п/о лицо работает в выбранном подразделении

if LicaTPodr.AsInteger = PodrTNPodr.AsInteger then

begin

NalichieT.First; // Переходим в начало таблицы наличия

// Перебираем все записи таблицы наличия

while not NalichieT.Eof do

begin

// Если эта запись относится к выбранному п/о лицу

if NalichieTLico.AsInteger = LicaTNLic.AsInteger then

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

s:= s + NalichieTKolvo.AsFloat * NalichieTCena.AsFloat;

NalichieT.Next; // Переходим к след. записи таблицы наличия

end;

end;

LicaT.Next; // Переходим к следующей записи таблицы лиц

end;

// Выводим результат

SummLbl.Caption:= 'на сумму ' + FormatFloat('0.00 "руб."', s);

end;

 

 

Рис. 22. Общая сумма предметов, имеющихся в наличии

 

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

 

Задание.

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

 

4.3. МОДИФИКАЦИЯ НАБОРОВ ДАННЫХ

 

Для того чтобы в набор данных можно было вносить изменения, его свойство ReadOnly должно быть установлено в False. Однако ReadOnly = False не гарантирует допустимость изменений. Например, изменения будут недопустимы, если НД открыт другим пользователем в режиме исключительного доступа. Для выяснения возможности внесения изменений в НД в конкретной ситуации можно проверить доступное только по чтению свойство CanModify. Если CanModify = True, то изменения допустимы.

Для добавления новой записи или внесения изменений в текущую запись НД должен быть переведен в состояние dsInsert или dsEdit, соответственно. Это может быть сделано явно (программно) путем вызова соответствующих методов или неявно в результате соответствующих действий пользователя в визуальных компонентах. Неявный переход в состояние dsEdit возможен только в том случае, когда свойство AutoEdit соответствующего TDataSource установлено в True. На переход в состояние dsInsert это свойство не влияет.

Замечание: для запрета добавления записей в НД его свойство ReadOnly должно быть установлено в True. В этом случае будет невозможно изменение уже существующих в наборе записей. Если же необходимо редактирование существующих записей без возможности добавления новых, то можно указать ReadOnly = True для полей первичного ключа НД.

Для добавления новой записи в НД используется метод Insert. После его вызова следует присвоить значения полям новой записи и для подтверждения изменений вызвать метод Post.

Если необходимо отказаться от добавления новой записи, то вызывается метод Cancel.

Для удаления записей используется метод Delete, который может вызываться как явно, так и неявно (нажатие Ctrl+Delete в TDBGrid). Поскольку удаление записей может повлечь необратимую потерю информации, то на такого рода действия следует обязательно запрашивать подтверждение пользователя.

Для изменения значений полей текущей записи необходимо вызвать метод Edit, присвоить новые значения полям и подтвердить изменения вызовом метода Post или отменить их – Cancel.

Выполнение метода Post не зависимо от способа его вызова может закончиться неудачно. Например, если не были присвоены значения полям, требующим обязательного ввода значения (Required), нарушены условия уникальности первичного ключа или уникального индекса и т.п. Для исключения подобных ситуаций используются различные приемы, не позволяющие пользователю нарушать требования ограничений целостности хранимой в БД информации. Рассмотрим некоторые из них.

Для контроля правильности вводимых в поле значений можно использовать свойство EditMask компонента TField. В этом свойстве задается маска для значений поля; ввод символов не соответствующих маске не допускается. Маска представляет собой строковую константу, состоящую из трех частей, разделяемых символами «точка с запятой». В первой части задается собственно маска с помощью следующих символов:

! – убирать ведущие пробелы (если в маске нет этого символа, то из введенного значения будут убраны только хвостовые пробелы);

> – все следующие символы должны вводиться в верхнем регистре;

< – все следующие символы должны вводиться в нижнем регистре;

<> – далее регистр определяется пользователем;

L – в данной позиции должна быть буква;

l – то же, но символ может и отсутствовать;

A – в данной позиции должна быть буква или цифра;

a – то же, но символ может и отсутствовать;

0 – в данной позиции должна быть цифра;

9 – то же, но символ может и отсутствовать;

# – в данной позиции должна быть цифра, + или -, но символ может и отсутствовать;

C – в данной позиции должен быть любой символ;

: – разделитель часов, минут и секунд;

/ – разделитель дня, месяца и года;

_ (подчеркивание) – заменяет в маске пробел;

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

Во второй части маски указывается 1 или 0. Если 1 – то литералы включаются в сохраняемое значение, если 0 – то значение сохраняется без литералов.

В третьей части маски – символ, который в экранной форме будет указывать позиции, требующие ввода символов.

Например, поле с маской ‘!(999)000-00-00;0;X’ перед вводом будет иметь вид: (XXX)XXX-XX-XX

после ввода: (495)525-15-27

а сохранено будет значение: 4955251527

Для задания формата показа и редактирования значений числовых полей используются свойства DisplayFormat и EditFormat, которые также могут состоять из трех частей, разделенных точкой с запятой. Если все части присутствуют, то первая используется для форматирования положительных значений, вторая – отрицательных, третья – нулевых. Если третья часть отсутствует, то нулевые значения форматируются так же, как и положительные. Если указана одна часть, то все значения форматируются одинаково. Если указано значение только для свойства DisplayFormat, то оно используется и при редактировании.

Формат задается следующими символами:

0 – в этой позиции цифра, ведущие нули показываются;

# – в этой позиции цифра, ведущие нули не показываются;

. – разделитель дробной и целой частей;

, – разделитель групп разрядов;

E+ – научный формат чисел.

Символы внутри двойных или одинарных кавычек выводятся «как есть».

Например, при формате: ‘#,##0.00 "руб."’

значение: 1234.4

будет показываться как: 1 123,40 руб.

Замечание: какие символы, будут использованы для разделения дробной и целой частей и групп разрядов, зависит от настроек операционной системы.

Для проверки введенного в поле значения можно использовать свойство IsNull и обработчик события OnValidate компонента TField.

Свойство IsNull возвращает True, если полю не присвоено значение.

Событие OnValidate возникает при попытке присвоения полю нового значения до выполнения Post. Если введенное значение не удовлетворяет предъявляемым к нему требованиям, то для предотвращения Post в обработчике OnValidate можно использовать метод Abort.

Для проверки значений, присвоенных всем полям записи, можно использовать обработчик события BeforePostRecord. Если же запись изменений определяется явно, например, по нажатию некоторой кнопки на форме (например, кнопки с названием «Записать»), то проверка может быть произведена непосредственно в обработчике события OnClick этой кнопки.

Для оценки того: были внесены изменения в текущую запись или нет, можно использовать свойство набора данных Modified. Оно устанавливается в True, если в режиме dsInsert или dsEdit было изменено значение какого-либо поля. Методы Post и Cancel сбрасывают это свойство в False.

 

4.4. ИНТЕРФЕЙС ПОЛЬЗОВАТЕЛЯ ПРИ МОДИФИКАЦИИ НД

 

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

Наиболее логичной формой представления информации в приложениях баз данных является табличная форма. Она наглядна, соответствует физической модели хранения информации и удобна для навигации. Но удобна ли она для модификации данных, хранимых в БД? К сожалению, далеко не всегда, поскольку имеет ряд существенных недостатков.

Главный из них – не акцентируется внимание пользователя на моментах перехода к изменению записи и фиксации изменений. В результате, могут быть утрачены изменения, которые с точки зрения пользователя были занесены в БД, а с другой стороны в ней могут быть зафиксированы изменения, которые пользователь не собирался вносить. Например, в результате перехода НД в режим редактирования при случайном нажатии на клавиши.

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

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

Обычно более предпочтителен вариант, при котором модификация набора данных производится вне TDBGrid. Для этого на форме помещаются кнопки для инициирования действий над текущей записью (добавления записи, ее удаления или изменения), визуальные компоненты для работы с отдельными полями текущей записи, а также кнопки для фиксации («Записать») или отмены («Отменить») изменений (рис. 23).

 

 

Рис. 23. Вариант интерфейса модификации набора данных

 

При необходимости внести какие-либо изменения в НД нажимается соответствующая кнопка («Добавить» или «Изменить»). В ее обработчике НД переводится в режим dsEdit или dsInsert, и разрешается доступ к компонентам для работы с отдельными полями текущей записи, а доступ к TDBGrid (и кнопкам «Добавить», «Удалить», «Изменить») наоборот запрещается. (Для разрешения или запрета доступа к группам компонентов в данном случае будет удобно разместить их на двух панелях, и манипулировать доступом посредством свойства Enabled этих панелей.)

Хорошим тоном будет предупреждение пользователя о том, что он в данный момент делает: добавляет новую запись или изменяет уже существующую. Для этого можно использовать надпись (TLabel), соответствующего содержания.

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

Для отмены изменений нажимается кнопка «Отменить», вызывается метод Cancel и происходит возврат к TDBGrid.

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

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

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

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

Это очень удобный инструмент, называемый контейнером невизуальных компонентов TDataModule. (Для его создания используется пункт меню Delphi File|New... DataModule.) Контейнер представляет собой невизуальную форму (рис. 24), на которой можно расположить все невизуальные компоненты связи с БД, используемые в приложении. В этом случае не придется дублировать компоненты, синхронизировать их работу или разыскивать их по многочисленным формам приложения. Достаточно во всех формах, взаимодействующих с БД, поместить в предложении USE ссылку на модуль UNIT, в котором описан TDataModule. После этого во всех формах будут доступны общие компоненты связи с БД.

 

 

Рис. 24. Контейнер невизуальных компонентов

 

Замечание: ссылки на невизуальные компоненты, расположенные в TDataModule, записываются через имя этого контейнера. Например, если TDataModule имеет имя DM, то обращение к значению поля количества предметов в текущей записи таблицы наличия будет иметь вид: DM.NalichieTKolvo.AsInteger.

Следует отметить, что использование контейнера невизуальных компонентов TDataModule целесообразно во всех сколько-нибудь сложных приложениях баз данных.

Приведем пример реализации интерфейса модификации НД, связанного с таблицей лиц (рис. 25 и 26).

 

// Процедура обработки нажатия кнопки «Добавить»

procedure TMainForm.AddBtnClick(Sender: TObject);

begin

EdLicaForm.WhatLbl.Caption:= 'Запись будет добавлена';

DM.LicaT.Insert;

EdLicaForm.ShowModal;

end;

 

// Процедура обработки нажатия кнопки «Изменить»

procedure TMainForm.ChngBtnClick(Sender: TObject);

begin

EdLicaForm.WhatLbl.Caption:= 'Запись будет изменена;

DM.LicaT.Edit;

EdLicaForm.ShowModal;

end;

 

// Процедура обработки нажатия кнопки «Удалить»

procedure TMainForm.DelBtnClick(Sender: TObject);

begin

if Application.MessageBox('Вы хотите удалить это лицо?',

'Удаление лица', mb_YesNo + mb_IconQuestion + mb_DefButton2) <> idYes then exit;

DM.LicaT.Delete;

end;

 

 

Рис. 25. Форма отображения таблицы лиц

 

// Процедура обработки нажатия кнопки «Отменить»

procedure TEdLicaForm.CancelBtnClick(Sender: TObject);

begin

DM.LicaT.Cancel;

EdLicaForm.ModalResult:= mrCancel;

end;

 

 

Рис. 26. Форма модификации таблицы лиц

 

// Процедура обработки нажатия кнопки «Записать»

procedure TEdLicaForm.OkBtnClick(Sender: TObject);

begin

if trim(DM.LicaTName.AsString) = '' then

begin

ShowMessage('Укажите наименование лица');

NameDBEdit.SetFocus;

exit;

end;

if DM.LicaTTip.IsNull then

begin

ShowMessage('Укажите тип лица');

TipDBLookupComboBox.SetFocus;

exit;

end;

if DM.LicaTTip.AsInteger <> 2 then

DM.LicaTPodr.AsVariant:= null

else

if DM.LicaTPodr.IsNull then

begin

ShowMessage('Укажите подразделение');

PodrDBLookupComboBox.SetFocus;

exit;

end;

try

DM.LicaT.Post;

EdLicaForm.ModalResult:= mrOk;

except

ShowMessage('При записи изменений произошла ошибка');

end;

end;

 

Задание.

3. Создайте полноценные формы ввода информации во все таблицы Вашей БД с учетом разного рода ограничений и контроля возможных ошибок. Тексты процедур обработки и соответствующие экранные формы включите в отчет.

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

 


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


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

mybiblioteka.su - 2015-2024 год. (0.04 сек.)