Использование графических операций. Класс Tcanvas
Выбери формат для чтения
Загружаем конспект в формате doc
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Использование графических операций.
Класс Tcanvas
Многие компоненты имеют свойство Canvas (TForm, TImage).
Canvas – это область, в которую можно выводить различные графические изображения.
Свойство Canvas предоставляет возможность управлять областью рисунка во время работы приложения.
Свойства:
• Font - шрифт;
• Pen – задает тип карандаша, используемого для рисования линий и границ фигур;
• Brush – кисть. Позволяет задать цвет и шаблон заполнения.
Методы:
• MoveTo(x,y) – перемещение точки в позицию (x,y);
• LineTo(x,y) – рисование линии из текущего положения курсора в точку (х,у);
• Line(x1,y1,x2,y2) – проведение линии от точки (x1,y1) в точку (x2,y2);
• TextHeight(‘00’) – возвращает высоту (в пикселах) указанной строки с учетом текущего шрифта;
• TextWidth(‘00’) – ширина указанной строки с учетом текущего шрифта;
• TextOut(x,y,’Текст’) – вывод строки с координаты (x,y).
Примеры:
1) Пунктирная красная линия на форме:
With Form1.Canvas do
Begin
Pen.Style:=psDot; //пунктир
Pen.Width:=4; //толщина линии
Pen.Color:=clRed; //цвет линии
MoveTo(100,200);
LineTo(150,80);
End;
2) Закрашенный прямоугольник красного цвета:
With Form1.Canvas do
Begin
Brush.Style:=bsDiagCross;
Rectangle(125,180,90,68); //прямоугольник
Font.Color:=clRed;
Font.Size:=20;
TextOut(130,140,’Test’);
End;
3) Вывести таблицу на форме:
В OnClick кнопки:
Var i,Y,h: Integer;
S: Integer;
Begin
Y:=10;
Canas.Font.Size:=12;
S:=’Test №1’;
Canvas.TextOut(10,Y,S) ;
//рисуем вертикальную линию
Canvas.MoveTo(Canvas.TextWidht(st’00’),Y);
Canvas.LineTo(Canvas.TextWidth(S+’00’)), Height – Y);
h:=Round(Canvas.TextHeight(‘0’)*1,2);
Y:=Y+h;
//рисуем горизонтальную линию
Canvas.MoveTo(10,Y);
Canvas.LineTo(Width-10, Y);
//Вывод цифр
For i:=1 to 10 do
Begin
Y:=Y+h;
Canvas.TextOut(10, Y, IntToStr(i));
End;
End.
Использование принтера
Для использования принтера создан специальный класс TPrinter в модуле Printers.
Свойства:
Все свойства доступны только во время работы приложения.
• Canvas – область страницы, в которую выводится информация.
• PageNumber – номер текущей страницы. Значение этого свойства увеличивается автоматически на 1 при каждом вызове метода NewPage.
Методы:
• NewPage – переход на следующий лист бумаги (PageNumber:=PageNumber+1).
• BeginDoc – посылает информацию на принтер, но печать не начинается.
• EndDoc – завершает работу с принтером и начинается печать этого метода.
Пример:
Вывести на принтер таблицу (как в примере 3)
Var i,Y,h: Integer;
S: Integer;
Begin
Printer.Orientation:=poPortrait;
//расположение на листе: portrait – вертикально, LandScape – горизонтально //
Printer.Title:=’Проба’ //заголовок в очереди на печать
Printer.BeginDoc;
With Printer do
Begin
Y:=10;
Canas.Font.Size:=12;
S:=’Тест №1’;
Canvas.TextOut(10,Y,S) ;
//вертикальная линия
Canvas.MoveTo(Canvas.TextWidht(st’00’),Y);
Canvas.LineTo(Canvas.TextWidth(S+’00’)), PageHeight – Y);
//горизонтальная линия
Canvas.MoveTo(10,Y);
Canvas.LineTo(PageWidth-10, Y);
//Вывод цифр
For i:=1 to 10 do
Begin
Y:=Y+h;
Canvas.TextOut(10, Y, IntToStr(i));
End;
End;
Printer.EndDoc;
End.
Закладки (Win32)
1) TTabControl – набор закладок.
Используется для представления одноименных данных. Пример – картотека. Текст метки всегда может изменяться при изменении закладки (но на все закладках метка одна).
Свойства:
• Tab: TString – набор названий закладок;
• TabWidth – ширина закладок;
• TabHeight – высота закладок (если эти свойства равны нулю, то высота и ширина закладок зависят от заголовка закладки);
• TabPosition – местоположение закладок:
◦ tpTop
◦ tpBottom
◦ tpLeft
◦ tpRight
• TabIndex – содержит индекс выбранной закладки (нумерация с нуля);
• MultiLine: Boolean. Если MultiLine=true, то закладки могут располагаться в несколько рядов; если MultiLine=false, то в – один ряд (может быть скроллер).
Методы:
• Tabs.Add; – добавить;
• Tabs.Delete; – удалить.
Пример:
В OnCreate формы:
Var i: Integer;
Begin
For i:=1 to 5 do
TabControl1.Tabs.Add(IntToStr(i));
End.
События:
• OnChanging – возникает перед выбором закладки (с помощью этого события можно запретить, например, выбор закладки. Для этого AllowChange := False);
• OnChange – возникает после выбора закладки
Пример:
В метку выводить дату и время
В TabControl1.Change
Case TabControl1.TabIndex of
0: Label1.Caption:= DateToStr(Date);
1: Label1.Caption:= TimeToStr(Time);
end;
2) TPageControl – набор страниц с закладками.
Отличие от предыдущего:
Может содержать не одну, а несколько страниц, каждая из которых может включать свой набор компонентов. (Добавить страницу – правой кнопкой мыши – NewPage; Удалить страницу – выделить страницу, а не компонент, нажать Delete; Размещение компонентов: если выделить весь компонент и поместить двойным щелчком, например, кнопку, то этот компонент окажется на всех страницах).
Свойства:
• TabWidth – ширина закладок;
• TabHeght – высота закладок;
• TabPosition – местоположение закладок;
• MultiLine. Если MultiLine=true, то закладки могут располагаться в несколько рядов; если MultiLine=false, то в – один ряд (может быть скроллер).;
• ActivePage – содержит ссылку на активную страницу;
• PageCount – количество страниц;
• Pages[Index] – возвращает ссылку на страницу по ее индексу.
Методы:
• Function FindNextPage(CurPage: TTAbSheet; GoForward, CheckTabVisible: Boolean) – ищет следующую страницу, где CurPage – текущая страница; GoFoward – если «истина», то поиск идет от первой к последней странице, если «ложь»– наоборот, CheckTabVisible – если «истина», то из поиска исключаются все «невидимые» страницы. Эта функция возвращает номер следующей страницы.
3) THeaderControl – управляющий заголовок. Многоколоночный заголовок с регулируемыми размерами секций.
Пример:
БАЗЫ ДАННЫХ
Применение Delphi для разработки программ,
предназначенных для создания и обслуживания баз данных.
База Данных (БД) – электронное хранилище информации, доступ к которому может осуществляться с одного или нескольких компьютеров.
СУБД – система управления БД – это программное средство, предназначенное для создания, наполнения, редактирования и удаления БД.
СУБД по расположению различают:
1) Локальные – все части СУБД расположены на компьютере пользователя;
2) Распределенные (клиент-серверные СУБД) – большая часть программно-аппаратных средств централизована и расположена на мощном сервере, остальная небольшая часть (клиенты) расположена на компьютерах пользователей, которые могут быть удалены на значительное расстояние, но рассматриваются как единое целое.
Единицей БД является таблица, у которой строки – записи и столбцы – поля.
БД, не хранящаяся в виде таблиц, между которыми существует связи, является реляционными.
В реляционной БД таблицы нормализованы.
Достоинство нормализации:
Уменьшение избыточности, что ведет к экономии памяти носителей информации.
Недостатки нормализации:
• При больших объемах данных создается очень много таблиц, т.е. сложно проследить взаимосвязи (уменьшатся видимость);
• При одном запросе в БД может потребоваться поиск по нескольким таблицам, что ведет к снижению скорости.
Таблицы взаимодействуют по правилу: «ГЛАВНАЯ – ПОДЧИНЕННАЯ».
(master) (detail)
Мы будем работать с СУБД Paradox 7.0 (Для каждой таблицы индексы и memo-поля создают отдельный файл).
Основные понятия
Ключи и индексы
Primary Key – первичный ключ – одно или группа полей, которые однозначно идентифицируют каждую запись.
Требования:
• уникальность значения;
• таблицы всегда отсортированы по первичному ключу (по умолчанию).
Наиболее простой способ создания первичного ключа – создать дополнительное поле типа «autoincrement (+)» (внутренний счетчик) – нет повторений с удаленными записями.
Внешний ключ – столбец одной таблицы, значение которого совпадает со значением первичного ключа другой таблицы (для связи таблиц).
Вторичные ключи – Secondary Indexes – создаются при необходимости поиска и сортировки данных. Вторичные ключи создаются по тем полям, которые часто участвуют в поиске и сортировке. Уникальность значения не требуется.
По всем полям, по которым построены ключи, СУБД автоматически строит физические индексы – специальный механизм, обеспечивающий быстрый доступ к элементам.
Сущность индексов:
Они хранят отсортированные по возрастанию значения индексных полей и указатели на записи в таблице. Каждый индекс хранится в отдельном файле.
Почему не индексируют все поля таблицы?
• потому что резко увеличивается объем БД (создается много лишних файлов);
• при модификации таблицы система автоматически обновит все свои физические индексы, что увеличивает затраты времени.
Индекс по полю ФИО:
Индексы по номеру группы:
На построение индексов первый раз может уйти много времени (в зависимости от объема БД), но это только первый раз. Зато для поиска по этим индексированным полям можно применять быстрые методы поиска.
Вторичные индексы могут строиться и по нескольким полям. Например, построим индекс по группе и ФИО (порядок включения полей в индекс важен!)
Индекс по группе и ФИО (in Group FIO):
Создание таблицы
1) Запустить утилиту DataBase Desktop (DBD). Она предназначена для создания, редактирования, просмотра таблиц (через Пуск или Tools);
2) Установить рабочую директорию, где будет храниться БД (В DBD: File/Working Directory) или псевдоним;
3) File/New Table (формат Paradox 7.0);
4) Создание полей;
В начале всегда указывают первичный ключ.
Требования к имени поля:
• не более 25 символов;
• имя поля не может начинаться с пробела;
• внутри может быть пробел;
• нельзя использовать: (, ), [, ], {, }, , , #.
Некоторые типы:
• Alpha – строка [1..255];
• Integer, хотя в списке его нет;
• Number – числовое поле с плавающей точкой длиной 8 байт (положительные и отрицательные числа);
• Short – [-32768..+32767] – 2 байта;
• Memo – > 255 символов; 1 – 240 символов хранятся в БД, а остальные в Memo-файлах с расширением *.mb (для примечаний).
5) После задания имени, типа, задать первичный ключ (*);
6) Определение дополнительных свойств таблицы:
- установка необходимых параметров:
Validity Checks - проверка правильности (относится только к конкретному полю);
Referential Integrity – ссылочная целостность таблицы (для построения внешних ключей);
Secondary Indexes – построение вторичных ключей.
-включение и выключение обязательного заполнения поля;
- минимальное значение;
- максимальное значение;
- значение поля по умолчанию;
- шаблон изображения поля.
Назначение опций в окне создания вторичного ключа:
• Unique – создание уникального ключа;
• Maintained – индекс обновляется автоматически в момент открытия таблицы;
• Case Sensitive – учет регистра;
• Ascending – сортировка значений индексных полей по возрастанию;
• Descending – сортировка значений индексных полей по убыванию.
7) Сохранить таблицу (Save).
Редактировать и заполнять данные можно двумя способами:
1) Используя DBD:
◦ Открыть таблицу Table\Open;
◦ Table\Edit Data – перейти в режим редактирования (просмотр – View Data)
2) В работающем приложении. Данные автоматически сохраняются.
Некоторые средства Delphi для создания
и использования приложений для работы с БД
Просмотр структуры БД:
DBD; Restructure – изменять (только в режиме Table.Active = False или Table.Close, т.е. только при закрытом наборе данных)
Просматривать Info Restructure – в любом режиме.
BDE – Borland database Engine – машина БД, представляющая собой набор DLL – библиотек, обеспечивающих низкоуровневый доступ к локальным и клиент-серверным БД. BDE не является частью программы, а является связующим звеном между БД и программой. BDE должна быть установлена на каждом компьютере, который использует приложения, работающие с БД, написанные на Delphi. BDE позволяет работать с различными форматами данных. Начиная с Delphi 5.0 появились новые технологии, позволяющие работать без ИВУ – ADO, InterBase Express, у них есть свои плюсы и минусы.
Схема взаимодействия БД с программой:
1) BDE Administrator – это утилита для установки псевдонимов (имен) БД, а также параметров на конкретном компьютере;
2) Data Base Desktop (DBD) – средство для создания, редактирования, хранения, просмотра таблиц БД для локальной БД;
3) SQL Explorer – эта утилита включает многие функции BDE Administrator и DBD: просмотр и создание псевдонимов, просмотр структуры и содержимого БД, но не создание; формирование запросов с БД, используя язык SQL;
4) Невизуальные компоненты для работы с БД: закладка Data Access – служит для связи приложения с таблицами БД, для формирования запросов и для другой работы с данными.
• Ttable (имеют общего предка)
• TQuery Эти компоненты обеспечивают
связь и работу с БД
• TDataSource – обеспечивает связь между визуальными и невизуальными компонентами при работе с БД.
5) Визуальные компоненты для работы с БД: закладка Data Controls:
• TDbGrid позволяет целиком увидеть всю таблицу;
• TDbText – метка;
• TDbEdit – для вывода записей и полей БД, можно привязаться к конкретному полю БД.
- локальная архитектура:
DataBaseName – путь (или псевдоним) до БД
TableName – имя таблицы;
DataSet:= Table1;
DataSource – номер компонента TDataSource;
•
- клиент – серверная архитектура:
Создание приложения
1) Поместить на форму компоненты TTable, TDataSource, TDbGrid (следовательно Table1, DataSource1, DbGrid1);
2) Table1.DataBaseName:=’путь до базы’;
Table1.TableName:=’имя таблицы’;
3) DataSource1.DataSet:=Table1;
4) DbGrid1.DataSource:=DataSource1;
5) Table1.Active:=True;
{Table1.Open}
Создание псевдонимов
Псевдоним Alias содержит информацию для обеспечения доступа к БД.
В paradox 7.0 – это путь до БД.
1) Путь\Delphi\BDE Administrator
2) В Object\New
3) Database Driver Name
Выбираем «STANDARD» и нажимаем ОК
4)
В PATH выбираем путь до каталога с БД.
4) Изменить имя «STANDARD1» на имя псевдонима БД (например, MyBase).
5) Object\Applay.
Объединение таблиц
Table Group
G_N
№
G_Name
Группа
Kol_Std
Количество
Ball
Балл
1
П-21
28
1,5
2
П-22
26
1,7
3
П-23
30
1,2
4
П-24
25
1,8
Table Stud
St_N
№
FIO
ФИО
Number
N
KS1
КС1
KS2
КС2
1
Потапов
1
1
1,3
2
Васильев
2
1,5
1,2
3
Андреев
1
1,7
2
Задача: Соединить две таблицы по группе.
Построение внешнего ключа:
Внешний ключ строится у подчиненной таблицы:
Table Properties \ Referential Integrity
Нажимаем ОК, далее всплывает следующее окошко, где задаем имя и сохраняем.
Нажимаем ОК. После этого становятся активными кнопки «Erase» и «Modify», с помощью которых мы можем соответственно удалить или модифицировать внешний ключ.
Далее – сохранить ключ (SAVE) – во время этого главная таблица должна быть закрыта.
Автоматически после построения внешнего ключа система строит вторичный ключ по полю внешнего ключа (чтобы посмотреть: Properties / Secondary Indexes).
Создание приложения
1) Поместить на форму компоненты: TTable (2), TDataSource (2), TDbGrid (2);
2) Установить все связи БД для открытия таблицы;
3) Объединить таблицы в приложении
Объединение таблиц в приложении
Свойства TTable:
• MasterSource: TDataSource – содержит источник главной таблицы, т.е. определяет имя главной таблицы в связи «главный - подчиненный»;
tbTableMasterSource:=dsGroup;
• MasterFields: String – поле главной таблицы, по которому построен внешний ключ
В Available Indexes хранятся все существующие индексы подчиненной таблицы. Тут надо выбрать поле, по которому выбран внешний ключ (NumGrp). В итоге в поле MasterFields: G_N.
Работа с визуальными компонентами
У всех визуальных компонентов 2 свойства (закладка TControls), которые всегда лучше устанавливать:
• DataSource;
• DataFields.
Создание объектов столбцов у компонента dbGrid:
Это нужно для того, чтобы работать отдельно с каждым полем.
1) Вызвать редактор столбцов:
• через инспектор объектов Columns;
• правой кнопкой на компоненте Column Editor;
2) Add – добавляет пустой дополнительный столбец, не связанный ни с каким полем. Чтобы связать с каким-либо полем используем свойство FieldName;
3) AddAllFields – все столбцы становятся объектами.
Формирование списка возможных значений объекта столбца:
1) Вызвать редактор, выделить нужный столбец;
2) Свойство PickList – заполнить списком значений;
3) Установить свойство Button Style = cbsAuto (при работе приложения в момент редактирования полей выбранного столбца-объекта в него автоматически будут помещаться ComboBox со списком, набранным нами).
Как перенести свое приложение на другой компьютер?!
Наша база в папке BASE и там же Project.exe;
В OnCreate формы:
Var S: String;
Begin
If Table1.Active then
Table1.Active:= False;
S:=ExtractFilePath(Application.Exename)+’Base’;
Table1.DataBaseName:=S;
Table1.Active:=True;
End.
Работа с TTable
1) Обращение к полю – Value (as String, as Integer, as Boolean). В этом случае тип данных и тип поля должны строго совпадать.
Запись в поле:
◦ Table1.Fields[1].asString:=…
◦ Table1.FieldByName(‘FIO’).Value:=…
◦ Table1FIO.asString:=… (у компонента Table есть редактор полей, и каждое поле можно сделать отдельным объектом, и в этом случае имя объекта = сам компонент + имя поля)
◦ Table1.[‘FIO’]:=…
2) Перемещение по таблице
• Table1.First, Table1.Next, Table1.Prior, Table1.Last – перемещение на соответствующую позицию
• Table1.MoveBy(N) – перемещение через N записей
• Движение записей:
Table1.First;
While not Table1.EOF do
Begin
…
Table1.Next;
End;
3) Добавление записи из Edit1:
Table1.Insert; - режим вставки
Table1.Fields[1].asString:=Edit1.Text;
…
Table1.Post; – сохранить редактирование
Table1.Cancel; – отменить редактирование
4) Удаление записи:
Table1.Delete – удаляет все записи поля и устанавливает курсор на следующую запись
5) Редактирование записей
Table1.Edit – таблица в режиме редактирования
Редактирование текущего значения выделенного поля:
Table1.Fields[dbGrid1.SelectedFields.Field№-1].asString:=Edit1.text;
Table1.Post;
6) Программный доступ к записям без использования видимых компонентов:
Table1.Open; – открыт набор данных
If not Table1.IsEmpty then
While not Table1.EOF do
Begin
…
Table1.Next;
End;
Table1.Close;
7) Создание вычисляемого поля
1. Компоненты TTable. В редакторе полей:
New Fields;
Add Fields – для создания полей объектов;
2. В окне необходимо заполнить:
Name KSSr (например, средний контрольный срок)
Type ◘ Calculated
Таблица tbStd:
St_Num
G_Num
FIO
KS1
KS2
KSSr
1
4
Андреев
1.5
2
3. TTable → onCalcFields;
Пример:
Var KS1,KS2:integer;
Code:integer; S:String;
Begin
Val(tbStd KS1.asString, KS1, Code); //если «0» – число перевелось
If (Code <> 0) then KS1:=0;
Val(tbStd KS2.asString, KS2, Code);
If Code <> 0 then KS2:=0;
Str((KS1+KS2)/2 :2:2, S); //перевод обратно в строку
tbStd KSSr.asString:=S;
End;
Пример:
S_Num
G_Num
F (фамилия)
I (имя)
O (отчество)
FIO
1
4
Создание виртуального поля «FIO» - аналогично:
Ttable → onCalcFields:
tbStd FIO.asString:=tbStd F.asString+’ ’+tbStd I.asString+’ ’+tbStd O.asString;
8) Поиск данных
1. Поиск методом перебора
Пример: Поиск фамилии по имени (имя – в Edit):
Table1.First;
While (not Table1.EOF) and (Table1.Name <> Edit1.Text) do Table1.Next;
2. Поиск по заданному шаблону. Точный поиск.
Table1.IndexName:=’inName’; – должен быть построен индекс inName. Поиск по отсортированному набору данных.
Вариант1: Table1.Setkey; – переход в режиме поиска данных dsSetKey.
Table1[‘Name’]:=Edit1.Text; – установка шаблона поиска
Table1.Gotokey; – осуществляет поиск и переводит курсор на найденную запись. Если запись не найдена – ничего не происходит и курсор остаётся на прежней позиции.
Вариант2: Table1.Findkey([Edit1.Text]); – находит запись, удовлетворяющую критерию поиска и делает ее текущей. Поиск ведется по полю, по которому построен вторичный ключ, находящийся в свойстве находящийся в свойстве IndexName в данный момент.
3. Поиск наилучшего совпадения
Вариант1: Table1.IndexName:=’inName’;
Table1.Setkey;
Table1[‘Name’]:=Edit1.Text;
Table1.GotoNearest;
Вариант2: Table1.FindNearest([Edit1.Text]);
4. Поиск в группе по составному индексу.
Таблица tbGrp:
NumGrp→N
Таблица tbStd:
Пример: Поиск студентов в указанной группе
Точный поиск:
Edit1 → onKeyUp:
tbStd.IndexName:=’inGrpStd’; – внешний ключ, включающий два поля
группа (главное)
студенты
tbStd.Findkey([tbGrpN.asInteger, Edit1.Text]); – на первом месте указывается поле, входящее во внешний ключ-поле главной таблицы (в данном случае – поле N).
Неточный поиск:
tbStd.IndexName:=’inGrpStd’;
tbStd.FindNearest([tbGrp.asInteger, Edit1.Text]);
5. Метод Locate
Function Locate(const KeyFields:String; const KeyValues:Variant;
Options:TLocateOptions):Boolean;
Выдает:
True – если запись, удовлетворяющая критерию поиска, найдена. Данная
функция делает её текущей.
False – если запись не найдена; курсор остаётся на прежнем месте.
KeyFields – имена поисковых полей. Если их несколько, то поля разделяются «;»
KeyValues – значение полей;
Options : loCaseInsensitive; - без учёта регистров;
loPartialkey; - неточный поиск (поиск наилучшего совпадения);
[ ] - если не первый и не второй;
Locate позволяет искать поле по неотсортированным полям. Но если поле, по которому осуществляется поиск, отсортировано, то Locate применяет быстрые методы поиска, следовательно, время поиска сокращается.
Пример:
If Table1.Locate(‘Name’, Edit1.Text,[ ]) then …
6. Метод LookUp
Находит запись, удовлетворяющую условиям поиска, но не делает её текущей, а возвращает значения некоторых её полей.
Поиск только на точное совпадение.
Function LookUp(const KeyFields:String; const KeyValues:Variant;
const ResultFields:String):Variant;
ResultFields - перечисляет все поля, значение которых мы хотим получить.
Пример:
Label:
KS1:
KS2:
В onClick Поиск:
Var LookUpResult:Variant;
Begin
LookUpResult:=Table1.LookUp(‘Name’, Edit.Text, ‘KS1;KS2’);
If VarType(LookUpResult)=VarNull then ShowMessage(‘не найдено’);
Else
Begin
Label1.Caption:=LookUpResult[0];
Label2.Caption:=LookUpResult[1];
End;
End;
Фильтрация записей
N
FIO
Data
KS1
KS2
NumGroup
1
Васильев
1
2
Вербицкий
3
3
Давыдов
3
4
Потапов
2
◘ CheckBox1 CheckBox2
N группы Фамилия
CheckBox4
Фильтрация по заданному значению текущего индекса
В CheckBox1Click:
Var NumGrp:Integer;
Begin
If Edit1.Text=’ ’ then exit;
If CheckBox1.Checked then
Begin
NumGrp:=StrToInt(Edit1.Text);
tbStd.CancelRange;
tbStd.SetRange([NumGrp], [NubGrp]);
End
Else tbStd.CancelRange;
End;
SetRange(const StartValues, EndValues:Array of const) - показывает только те записи, индексные поля которых лежат в диапазоне от StartValues до EndValues.
CancelRange - отменяет все предыдущие условия фильтрации.
Для работы обработчика свойство IndexName должно быть равно индексу, построенному по тому полю, по которому начнётся фильтрация.
В данном примере:
IndexName:=’NumGroup’; – NumGroup - это имя вторичного индекса по полю NumGroup
Фильтрация записей по заданному диапазону
значений текущего индекса
IndexName:=’NumGroup’;
В CheckBox2Click:
Var NumGrp1, NumGrp2:Integer;
Begin
If Edit1.Text=’ ’ then exit;
If CheckBox2.Checked then
Begin
NumGrp1:=StrToInt(Edit1.Text);
NumGrp2:=StrToInt(Edit2.Text);
tbStd.CancelRange;
tbStd.SetRange([NumGrp1], [NumGrp2]);
End;
Else tbStd.CancelRange; //CheckBox1 не установлен
End;
Если IndexName перед фильтрацией не установлен, то по умолчанию – фильтр по первичному ключу.
Сортировка. Выбор режима фильтрации для кнопки CheckBox3.
RadioGroup1Click:
Case RadioGroup1.ItemIndex of //сортировка только одной несвязанной таблицы
0: tbStd.IndexName:=’inFio’;
1: tbStd.IndexName:=’NumGroup’;
End;
Если две таблицы («Group» – главная, «Stud» - подчинённая) и нужно отсортировать студентов только третьей группы:
При наличие двух таблиц: чтобы сортировать студентов текущей группы (той, на которой стоит указатель в таблице «Group»), нужно построить составной вторичный индекс по двум полям у таблицы «Stud»:
1–ое поле – NumGroup
2-ое поле – FIO
RadioGroup1Click:
Case RadioGroup1.ItemIndex of
0: tbStd.IndexName:=’inGrpFio’;
1: tbStd.IndexName:=’NumGroup’;
End;
CheckBox3Click:
Var NumGrp:Integer;
f1,f2:String;
Begin
If CheckBox3.Checked then
Begin
If RadioGroup1.ItemIndex=1 then
Begin
NumGrp:=StrToInt(Edit1.Text);
NumGrp2:=StrToInt(Edit2.Text);
tbStd.SetRange([NumGrp1], [NumGrp2]);
End
Else
Begin
f1:=Edit1.Text;
f2:=Edit2.Text;
tbStd.SetRange([f1], [f2]);
End;
End
Else
tbStd.CancelRange;
End;
Выбор режима фильтрации в CheckBox3.Click использует 1 случай. RadioGroup1.Click
Фильтрация по составному индексу
◘ CheckBox4
CheckBox4Click:
Var NumGrp:Integer;
f:String;
Begin
tbStd.IndexName:=’inGrpFIO’;
if CheckBox4.Checked then
Begin
NumGrp:=StrToInt(Edit3.Text);
f:=Edit4.Text;
tbStd.CancelRange; // вывод записей из данной группы с фамилиями на заданную букву
tbStd.SetRange([NumGrp, f], [NumGrp, f+’ЯЯ’]);
End;
End;
Рассмотренный механизм фильтрации позволяет отфильтровать только те записи, у которых значение ключевых полей находятся в заданном диапазоне.
Фильтрация по заданному критерию.
Ttable:
Filter – задает фильтрующее выражение
Filtered:Boolean – запрещает/разрешает фильтрование
◘ FilterOptions; – определяет условие фильтрации
fo CaseInseSitive – учитывать регистр
fo NoPartialCompare – поиск по большему соответствию образцу
Пример: Вывести все записи со студентами третьей группы, у которых KS1>1.5
Свойства:
1. Filter: (KS1>1.5) and (NumGroup=3)
2. Filtered=True
tbStd.Filter:=Edit1.Text;
tbStd.Filtered:=CheckBox1.Checked; – фильтровать или нет; должен быть отмечен галочкой.
Событие OnFilterRecord
Событие OnFilterRecord возникает при установке значения True в свойстве Filtered.
Procedure TForm1.tbStdFilteredRecord(Data Set:TDataSet; Var Accept:Boolean;);
Begin
Accept:=(DataSet[‘KS1’]>1.5) and (DataSet[‘KS1’]<=1.8);
End;
DataSet – имя фильтруемого набора данных
Accept =True – если текущая запись удовлетворяет условиям фильтрации.
Работа с компонентом TQuery.
Переходы в режимы изменения данных: вставка и т.д.
Совместное использование Ttable и TQuery.
TDB DataSet: TTable
TQuery
Общие свойства:
- Active;
- EOF, BOF;
- DataBaseName;
- AutoCalcFields;
- FieldCount:integer -количество полей в наборе данных;
- Fields;
- Filter, Filtered, FilterOptions;
- RecNo:longint - номер текущей записи (только для чтения);
- RecordCount:longint - количество записей в текущем наборе данных;
- State - состояние набора данных;
Общие методы:
- Close;
- Cancel;
- ClearFields - очистка всех полей текущей записи;
- Delete;
- Insert;
- Edit;
- First, Next и др.;
- FieldByName;
- LookUp;
- Locate;
- Open;
- MoveBy;
- FindFields(var FileName:string) - ищет поле и, если оно найдено, возвращает
ссылку на это поле. Если поле не найдено, то
значение Null;
Схема работы Delphi–Приложения с базой данных (БД)
через компоненты TTable и TQuery.
(свойство DataSet)
↕ визуальные компоненты для работы с БД
TDBGrid
Пример: Приложение 1
Таблица Stud:
DBGrid1 DataSource1
N
FIO
Data
KS1
KS2
NumGrp
1
Степанов
23.04.04
2
Ступин
19.12.04
3
Бондарь
03.07.05
Button:
- нажали.
После этого в инспекторе объектов:
Table1: DataBaseName:=
TableName:=Stud.db;
Active:=False;
Query1: DataBaseName:=
SQL - пусто;
Active:=False;
DataSource: DataSet - пусто;
DBGrid1: DataSource:=DataSource1;
• В OnClick кнопки Group:
Query1.Close; – сначала закрываем набор данных
Query1.SQL.Clear; – очищаем свойство SQL
Query1.SQL.Add(‘Select * from Group’);
Query1.Open; – выполнение запроса
• Для кнопки Stud изменяется только:
Query1.SQL.Add(‘Select * from Stud’);
• Для кнопки GrpStd изменяется только:
Query1.SQL.Add(‘Select FIO, KolStd from Stud, Group’);
• Общий обработчик для всех кнопок:
Begin
Form1.Table1.Close;
Form1.DataSource1.DataSet:=Query1; //вывод в качестве набора данных
TQuery
If (Sender as TButton)=ButGroup then tag:=1; //ButGroup - имя кнопки Group
If (Sender as TButton)=ButStd then tag:=2; //ButStd - имя кнопки Stud
If (Sender as TButton)=ButGrpStd then tag:=3; //ButGrpStd - имя кнопки GrpStd
With Query1 do
Begin
Close;
SQL.Clear;
Case tag of
1: SQL.Add(‘Select * from Group’);
2: SQL.Add(‘Select * from Stud’);
3: SQL.Add(‘Select FIO, KolStd from Stud, Group’);
End;
Open;
End;
Существует два способа выполнения запроса:
1. Метод Query1.Open. Для запросов типа Select применяется Open (возвращает набор данных)
2. Метод Query1.ExecSQL. Для всех остальных видов запросов (Insert, UpDate, Create и т.д.) используется ExecSQL.
Также запросы можно считывать из файла:
Query1.SQL.LoadFromFile(OpenDialog1.FileName);*.sql
Устанавливаем ширину столбцов:
• dbGrid1.Columns[n].Width:=m; - где n – номер столбца, m – задаваемая ширина
n-го столбца
• В OnClick кнопки Add:
Begin
DataSource1.DataSet:=Table1;
Table1.Open;
Case RadioGroup1.ItemIndex of
0: Table1.Insert;
1: Table1.Append; //добавляет запись в конец таблицы
End;
Ctrl+Del - удаление любой записи из таблицы
- Form2.Show; //(в OnClick)
В метке – имя поля, в dbEdit1 – значение поля (при выделении поля на Form1)
• В onActivate Form2:
Var S:String;
Begin
DBEdit1.DataSource:=Form1.DataSource1;
S:=Form1.DBGrid.Columns[Form1.DBGrid1.SelectedField.FieldNo-1].Title.Caption;
//Title - работа с заголовком
DBEdit1.DataField:=S; //DataField только связывает компоненты с указанным
//полем данных
Label1.Caption:=S;
End;
DBEdit1.DataField:=’FIO’; - не зависимо от того, на каком поле таблицы мы
кликнули в dbEdit1, выдаётся значение поля FIO текущей записи
Query1.Text - содержит текст запроса (только для чтения)
Edit1.Text:=Form1.Query1.Text;
Если на Form1 нажата Group, затем Form2, то в Edit1 на Form2 появится запрос:
Select * from Group;
//Edit1.Text:=Form1.Query1.FieldByName(‘FIO’).asString; - выдаётся значение
поля FIO текущей записи, НО ТОЛЬКО при наступлении события onActivate Form2.
Добавим на Form2 кнопку Info и создадим Form3.
На Form3:
→
Form3.Close;
• В OnClick Info:
Var j:Integer;
Begin
For j:=0 to 5 do
StringGrid1.Cells[j,0]:=Form1.dbGrid1.Columns[j].Field.asString;
Пример 2:
Navigator1: DataSource:=Form1.DataSource;
ShowHint=True;
Unit1:
В Список Click:
If Edit1.Text=’ ’ then
Begin
ShowMessage(‘Ввести дату’);
ActiveControl:=Edit1;
Exit;
End;
Form2.Show;
Unit2:
В Form2.Activate:
Label1.Caption:=Form1.Edit1.Text; //связываем Query с dbGrid:
Form1.DataSource1.DataSet:=Form1.Query1;
dbGrid1.DataSource:=Form1.DataSource1;
with Form1.Query1 do
Begin
Close;
SQL.Clear;
SQL.Add(‘Select FIO, Data from Stud where Data>=:p’);
//в таблице Stud предварительно было добавлено поле «Data» типа Data
Params[0].AsDate:=StrToDate(From1.Edit1.Text); //или (Label1.Caption) //при работе с параметрами нужно использовать явное преобразование типов, т.е. свойства asXXXX
Open;
End;
dbGrid1.Columns[0].Width:=120;
dbGrid1.Columns[0].Title.Caption:=’Фамилия’;
dbGrid1.Columns[0].Title.Color:=clRed;
Insert Click:
If Not(Form1.Query1.RequestLive) then
Begin
Form1.Query1.Active:=False;
Form1.Query1.RequestLive:=True;
Form1.Query1.Active:=True;
End;
Form1.Query1.Insert;
Запрос с параметром
Select * from Stud where KS1>:p1 and KS2<=:p2;
Вариант1:
Params[0].asString:=’1.5’;
Params[1].asString:=’2’;
Вариант2:
ParamByName(‘p1’).asString:=’1.5’;
ParamByName(‘p2’).asString:=’2’;
Объединение таблиц, т.е. создание подчинённой связи
Таблица Stud – подчинённая таблица
Query2: DataSource:=DataSource1;
SQL:Select * from Stud where NumGrp=:NumGrp; //имя параметра (NumGrp) должно быть таким же, как имя поля главной таблицы, по которому осуществляется связь
TQuery и Параметры
Delphi позволяет составить “гибкую” форму запроса, называемую параметризованным запросом. Такие запросы позволяют подставить значение переменной вместо отдельных слов в выражениях “where” или “insert”. Эта переменная может быть изменена практически в любое время. (Если используется локальный SQL, то можно сделать замену почти любого слова в утверждении SQL, но при этом та же самая возможность не поддерживается большинством серверов.)
select * from Stud where FIO like :Name
Двоеточие сообщает Delphi о необходимости заменить переменную NameStr некоторой величиной, которая будет известна позже.
Cлово Namer выбрано абсолютно случайно. Использовать можно любое допустимое имя переменной.
Есть два пути присвоить значение переменной в параметризованном запросе SQL. Один способ состоит в том, чтобы использовать свойство Params объекта TQuery. Второй - использовать свойство DataSource для получения информации из другого DataSet.
Вот ключевые свойства для достижения этих целей:
property Params[Index: Word];
function ParamByName(const Value: string);
property DataSource;
Если подставлять значение параметра в параметризованный запрос через свойство Params, то обычно нужно сделать четыре шага:
• Закрыть TQuery
• Подготовить объект TQuery, вызвав метод Prepare
Этот шаг выполняется в том случае, если данный текст запроса выполняется впервые, в дальнейшем его можно опустить.
• Присвоить необходимые значения свойству Params
• Открыть TQuery
Вот фрагмент кода, показывающий как это может быть выполнено практически:
Query1.Close;
Query1.Prepare;
Query1.Params[0].AsString := ‘Ступин’;
Query1.Open;
Params - это индексированное свойство, которое имеет синтаксис как у свойства Fields для TDataSet. Например, можно получить доступ к первой переменной в SQL запросе, адресуя нулевой элемент в массиве Params:
Конечный результат (т.е. то, что выполнится на самом деле) - это следующее предложение SQL:
select * from Stud where FIO =‘Ступин’
Все, что произошло, это переменной :NameStr было присвоено значение "Аргентина" через свойство Params..
Если в запросе содержится более одного параметра, то получить доступ к ним можно, изменяя индекс у свойства Params
Например,
Select * from Stud where KS1>:p1 and KS2<=:p2;
Вариант1:
Query1.Params[0].asString:=’1.5’;
Query1.Params[1].asString:=’2’;
Вариант2:
Query1.ParamByName(‘p1’).asString:=’1.5’;
Query1.ParamByName(‘p2’).asString:=’2’;
Итак, параметризованные SQL запросы используют переменные, которые всегда начинаются с двоеточия, определяя места, куда будут переданы значения параметров.
Прежде, чем использовать переменную Params, сначала можно вызвать Prepare. Этот вызов заставляет Delphi разобрать ваш SQL запрос и подготовить свойство Params так, чтобы оно "было готово принять” соответствующее количество переменных. Можно присвоить значение переменной Params без предварительного вызова Prepare, но это будет работать несколько медленнее.
Передача параметров через TDataSource
Речь пойдет о создании отношения однин-ко-многим между двумя таблицами с использованием объекта TQuery. Этот способ более гибок, чем при использовании TTable, в том отношении, что он не требует индексации по полям связи.
Объект TQuery имеет свойство DataSource, которое может использоваться для того, чтобы создать связь с другим DataSet. Не имеет значения, является ли другой DataSet объектом TTable, TQuery, или некоторым другим потомком TDataSet. Все что нужно для установления соединения - это удостовериться, что у того DataSet есть связанный с ним DataSource.
Предположим, что Вы хотите создать связь между таблицами Group и Stud так, что каждый раз, когда Вы просматриваете конкретную запись о группе, будут видны только студенты этой группы.
Рассмотрите следующий параметризованный запрос:
select * from Stud where NumGrp = :NumGrp
В этом запросе :NumGrp - связывающая переменная, которой должно быть присвоено значение из некоторого источника. Delphi позволяет использовать поле TQuery.DataSource чтобы указать другой DataSet, который предоставит эту информацию автоматически. Другими словами, вместо того, чтобы использовать свойство Params и “вручную” присваивать значения переменной, эти значения переменной могут быть просто взяты автоматически из другой таблицы. Кроме того, Delphi всегда сначала пытается выполнить параметризованный запрос используя свойство DataSource, и только потом (если не было найдено какое-то значение параметра) будет пытаться получить значение переменной из свойства Params. При получении данных из DataSource считается, что после двоеточия стоит имя поля из DataSource. При изменении текущей записи в главном DataSet запрос будет автоматически пересчитываться.
Связывание двух таблиц. Создайте новый проект, положите на форму один набор TTable, TDataSource и TDBGrid. Привяжите его к таблице Group. Положите на форму второй набор - TQuery, TDataSource и TDBGrid и свяжите объекты между собой.
В свойстве SQL наберите текст запроса:
select * from Stud where NumGrp = :NumGrp
В свойстве DatabaseName для Query1 укажите путь
В свойстве DataSource для Query1 укажите DataSource1.
Поставьте Active = True и запустите программу.
Пример: Запрос с параметром. Работа с Датой. Режим Insert.
Создание списка допустимых значений, определённых с помощью редактора полей при создании нового поля
1. Для формирования связи между таблицами необходимо вызвать редактор полей (по правой кнопке Table) у подчиненной таблицы.
2. Необходимо вызвать контекстное меню (по правой кнопке) NewField (команда). Появится окно.
Установить:
Field Properties
Name:Tovar1; //имя нового поля
Type:String; //выбрать тип
Size:15; //размер строки
Field Type:
◘ LookUp //будет поле выбора
LookUp Definition (раздел)
KeyFields - ключевое поле связи зависимой таблицы (подчинённой);
DataSet - имя таблицы источника допустимых значений;
LookUp Keys - ключевое поле связи исходной таблицы;
ResultField - имя поля из главной таблицы, которое используем для выпадающей списка таблицы;