|
Здравствуйте. Установлена RAD Studio 11.3, у которой отсутствует вкладка BDE и, соответственно, компонент Table, который обеспечивает доступ к таблице средствами механизма BDE.
|
Индексы, фильтрация, отчетность
Подстановочные поля
Иной раз приходится добавлять поле, которого изначально в данной таблице не было. Возьмите главную форму – там у нас выходит поле с номером автора, но не с его фамилией, а пользователю номер вряд ли поможет. Значит, для его удобства нам нужно будет вставить поле, где бы вместо номера выходили фамилия, имя и отчество автора. Это поле мы будем брать из таблицы авторов, подставлять нужные значения и выводить их так, будто изначально они были в первой таблице.
Создание нового поля возможно только при неактивной таблице, поэтому закройте таблицу TBooks (свойство Active переведите в False ).
Щелкните дважды по компоненту TBooks, который находится в модуле DM, чтобы открыть редактор полей. Далее щелкните по свободному месту редактора правой кнопкой и выберите команду "New Field" (новое поле). Появится окно, где мы должны указать все необходимые атрибуты поля.
В поле Name раздела Field properties нужно указать имя нового поля. Назовем его Fio_Avtors. Далее, в поле Type нужно указать тип нового поля, у нас это String, строковое поле для вывода фамилий авторов. В разделе Fieldtype нужно выбрать тип поля, выберем Lookup, это значит, что мы будем брать данные из другой таблицы.
Остался раздел Lookup definition. Здесь в поле Key Fields мы должны указать поле нашей таблицы, откуда мы будем брать значения. У нас это Avtor, здесь хранятся числа – номера авторов. В поле Dataset мы укажем таблицу, откуда будем брать значения, это таблица TAvtors. В поле Lookup Keys укажем начальное поле, которое хранит цифры – номера авторов, поле Key2. А в поле Result Field – результативное поле, значения которого будем подставлять. Это поле FIO.
Далее нажмите кнопку ОК. В редакторе полей перетащите новое поле поближе к полю Avtor, в начало таблицы. Переведите таблицу в активное состояние. Уже в проекте видны недостатки – заголовок подстановочного поля выходит латинскими буквами, и поле Avtor, содержащее цифры, уже не нужно. Снова вызовите редактор полей. Поле Avtor сделайте невидимым ( visible в false ). У поля Fio_Avtors в свойстве DisplayLabel укажите "Авторы". Теперь данные в сетке выходят в удобочитаемом виде. Новое поле никак не влияет на таблицы. Оно необходимо только для вывода данных в нормальном виде.
Далее займемся поиском нужной записи с помощью фильтров.
Фильтрация данных
Фильтрация данных предназначена для облегчения и ускорения поиска необходимой записи. Если у нас в базе всего около 100-200 записей, то найти нужную запись несложно путем обычного перебора записей, с первой по последнюю, либо пока не будет найдена нужная запись. А вот если записей миллион? Или сто миллионов? Тогда время поиска заметно увеличится, и тут придет на помощь фильтрация.
Когда вы применяете фильтр, то на экран выходят только те данные, которые удовлетворяют условиям фильтра. В нашем примере удобней всего делать фильтр по названию книги, так как подстановочное поле использовать в фильтре нельзя, а авторы у нас числятся как целые числа. На экран выйдут только те книги, название которых удовлетворяет условиям поиска, а уж среди них найти нужную книгу будет несложно.
Приступим к программированию. На панель главной формы, которая находится под меню, установите один компонент Label, на котором напишите "Найти книгу:", и один Edit, у которого удалите текст и сделайте его немного длинней. Когда мы будем вводить название книги в поле ввода Edit, на сетке будут отображаться только отфильтрованные данные.
Для компонента Edit создайте событие onChange, где напишите такой код:
//если пусто - не фильтруем.
if Length(Edit1.Text) = 0 then begin
fDM.TBooks.Filtered := False;
Exit;
end
else fDM.TBooks.Filtered := True;
//индексируем по названию, чтобы они были по алфавиту
fDM.TBooks.IndexName := 'Sort_Nazvanie';
//устанавливаем фильтр:
fDM.TBooks.Filter := 'Nazvanie>='+QuotedStr(Edit1.Text);Здесь мы вначале проверяем – есть ли текст? Если нет, то убираем фильтр ( Filtered := False ) и выходим из процедуры. Если же текст есть, то указываем, что таблица должна фильтроваться: Filtered := True. Далее, чтобы быстрей найти нужную книгу из списка отфильтрованных записей, делаем сортировку по названию книги.
И наконец, устанавливаем сам фильтр. Функция QuotedStr() возвращает текст, заключенный в кавычки. Можно было бы кавычки установить самостоятельно, однако здесь есть некоторые сложности – приходится считать, сколько же кавычек нужно ставить. Дело в том, что условие фильтрации требует такой записи:
Table1.Filter := 'значение';
А само значение может быть в таком виде:
Nazvanie >= 'Значение'
То есть, внутри строки будет еще одна строка, которую необходимо поставить в одинарные кавычки. Чтобы внутри текста указать одинарную кавычку, ее нужно написать дважды, так что строка превратится в такой вид:
fDM.TBooks.Filter := 'Nazvanie>='''+ Edit1.Text+'''';
Чтобы избежать таких сложностей подсчитывания кавычек, и существует функция QuotedStr().
Отчетность
Для создания отчетности существует очень много способов. Наиболее "продвинутый", но и наиболее сложный – вывод отчета с помощью компонентов отчетности, таких как Quick Report. Другой профессиональный способ – вывод отчета в файл MS Excel или MS Word. Мы разберем самый простой способ отчетности – будем выводить отчет в компонент Memo, а при желании – сохранять его в файл.
Создайте новую форму. В свойстве Name укажите fOtchet, в свойстве Caption – "Отчет", а саму форму сохраните в модуле Otchet.
Далее, в верхнюю часть формы установим Memo, и растянем его по всему верху (свойство Align = alTop ).
В нижней части поместим кнопку и компонент SaveDialog. На кнопке напишем "Сохранить в файл".
У Memo уберем весь текст, и установим вертикальную прокрутку. Не забудем добавить к этой форме модуль DM с помощью команды Uses Unit, а в главной форме той же командой добавим новое окно Otchet.
По нажатию кнопки напишем такой код:
if SaveDialog1.Execute then
Memo1.Lines.SaveToFile(SaveDialog1.FileName);Теперь нам необходимо написать код, по которому Memo будет заполняться данными. Это лучше всего сделать по событию главной формы onShow:
var
s : String;
begin
//очищаем Memo:
Memo1.Lines.Clear;
//устанавливаем закладку:
bm := fDM.TBooks.Bookmark;
//готовим таблицу:
fDM.TBooks.First;
fDM.TBooks.Filtered := False;
//делаем отпервой до последней записи:
while not fDM.TBooks.Eof do begin
//собираем данные в переменную s:
s := 'Автор: '+ GetFIO(fDM.TBooks['Avtor'])+#13+#10;
s := s + 'Название: '+ fDM.TBooks['Nazvanie']+#13+#10;
s := s + 'Экземпляров: '+ IntToStr(fDM.TBooks['Exemp'])+#13+#10;
s := s + 'Стоимость: '+ FloatToStr(fDM.TBooks['Cena'])+#13+#10;
s := s + 'Дата поставки: '+DateToStr(fDM.TBooks['Date'])+#13+#10;
s := s + '--------------------------------------------' +#13+#10;
fDM.TBooks.Next;
Memo1.Lines.Add(s);
end; //while
//переходим на закладку:
fDM.TBooks.Bookmark := bm;
bm := '';Мы указали функцию GetFIO(), которой пока нет. Эта функция будет принимать номер автора, и возвращать его фамилию, имя и отчество. Создайте эту функцию выше процедуры onShow:
function GetFIO(i : Integer):String;
begin
Result := '';
fDM.TAvtors.First;
while not fDM.TAvtors.Eof do begin
if fDM.TAvtors['Key2'] = i then begin
Result := fDM.TAvtors['FIO'];
Break;
end; //if
fDM.TAvtors.Next;
end; //while
if Length(Result)= 0 then
Result := 'Автор не найден';
end;Вот теперь все! Сохраните проект, скомпилируйте его и посмотрите, как он работает. Мы в этом проекте использовали почти все приемы работы с таблицами, хотя приложение, конечно, получилось не совсем профессиональным. Например, если удалить автора из таблицы авторов, то разрушится целостность таблиц – книга будет указывать автора, которого нет. В профессиональных проектах все это учитывается, однако на это уходит гораздо больше времени, и пишется гораздо больше кода. Когда вы освоите работу с таблицами самостоятельно, для вас все это не будет представлять никаких проблем.
Подытоживая сказанное о базах данных, заметим еще раз, что приложения бывают локальными – когда приложение и сама база данных располагаются на машине клиента. Такой подход следует использовать в приложениях, в которых сотрудники предприятия не должны обращаться к одним и тем же данным, например, в собственном телефонном справочнике, в приложении с кулинарными рецептами, в каталоге домашней библиотеки и тому подобными программами.
Сетевая база данных работает примерно так же, как локальная, только сама база данных находится на сетевом ресурсе, и с ее данными работают несколько клиентских приложений. Такой подход следует использовать для небольших сетевых приложений, когда сотрудников, работающих с данными тоже немного. Если записей в таблице перевалит за десяток тысяч, то обработка такой базы данных очень сильно загрузит сеть.
Клиент – серверная база данных работает иначе. Данные хранятся на сервере. Там же хранится СУБД (Система Управления Базами Данных). Пользователь работает не напрямую с данными, а получает к ним доступ из СУБД с помощью SQL – запросов. Сервер эти данные обрабатывает, и пользователю возвращается результат – только те данные, которые необходимы. А в предыдущем случае каждый клиент получал свою копию полной БД. Нетрудно сообразить, что клиент – серверный подход значительно ускоряет работу с БД и снижает нагрузку на сеть.
Однако начинать программирование БД следует все же с локальных приложений. По мере накопления опыта вы будете двигаться дальше, к сетевым и клиент – серверным БД.

