00.2 Уч-мет пос МПиС d4 (1). Лабораторная работа Формирование статистической таблицы с возможностью сортировки, фильтрации и группировки данных 4
![]()
|
try ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM BlobTable'); ADOQuery1.Active:=True; except on e:Exception do end; Не забудьте на форму положить компонент TImage, куда будут выводится картинки и TOpenDialog. Для записи картинки на событие кнопки - OnClick напишем следующее: var Blob:TMemoryStream; begin try if OpenDialog1.Execute then begin ADOQuery1.Insert; Blob:=TADOBlobStream.Create(TBlobField(ADOQuery1.FieldByName('blobs')),bmWrite); Blob.LoadFromFile(OpenDialog1.FileName); Blob.Free; ADOQuery1.Post; end; except on e:Exception do end; end; Здесь переменная памяти, в которую грузим картинку, а затем при создании записываем в БД, указав идентификатор bmWrite, и необходимо сделать преобразование типов TBlobField, то есть указываем, что это точно поле с нашими двоичными данными. Запись должна пройти без ошибок, и если открыть БД, то можно увидеть, что в поле, где сохраняли картинку написана такое - Двоичные данные. Далее необходимо считать информацию из БД. Для этого на другую кнопку события OnClick пишем: var jpg:TJPEGImage; Blob:TMemoryStream; bmp:TBitmap; begin try bmp:=TBitmap.Create; jpg:=TJPEGImage.Create; ADOQuery1.First; Blob:=TADOBlobStream.Create(TBlobField(ADOQuery1.FieldByName('blobs')),bmRead); jpg.LoadFromStream(Blob); Image1.Picture.Assign(jpg); jpg.Free; Blob.Free; bmp.Free; except on e:Exception do begin jpg.Free; Blob.Free; bmp.Free; end; end; Здесь и TBitmap и TJpegImage, потому что заранее не известно, какой формат запишет в БД пользователь картинки. Также необходимо в БД сделать новое поле, где будет храниться наш формат данных, и при записи картинки записывать в это поле расширение нашей картинки, а при считывании проверять формат и в зависимости от него создавать ту или иную переменную. Если будете использовать TJpegImage, то необходимо в Uses подключить модуль jpeg - для работы с jpg-изображениями. Также можно увидеть здесь, что установлен указатель на первую запись в БД с помощью First. Здесь также присутствует переменная памяти, в которую считываем данные, указав идентификатор bmRead. Затем эту переменную загружаем в переменную изображения, ну а затем и в TImage. Как можно выполнять запросы к БД и сравнивать в условии даты? Два варианта решения проблемы 1. Создаем базу, добавляем необходимые поля (например, id - Счетчик, dat - Текстовый), а поле, где должна находиться дата, указываем тип - Текстовый. То есть, дата будет храниться, как обычный текст, записывать сможете в любом формате, а делать SQL-запрос. В проекте, использованы следующие компоненты: TADOConnection TADOQuery TButton Отображать данные, нигде не будем, а просто, для проверки выведем их в цикле, чтобы просто убедиться, что запрос выполнен правильно. Структура БД (рис. 15). ![]() Рис. 15. Структура таблицы БД Пример такого запроса, но не забывайте, что в БД в поле dat, стоит тип - Текстовый. var i:integer; begin try with ADOQuery1 do begin SQL.Clear; SQL.Add('SELECT * FROM MyTable WHERE dat='''+'07.05.2011'+''''); Active:=True; for i := 0 toRecordCount-1 do begin ShowMessage(FieldByName('dat').AsVariant); end; end; finally //-//-//-//-//-// end; Данный запрос, выводит одну запись, при следующих данных в таблице (рис. 16). ![]() Рис. 16. Пример результата запроса Что касается второго метода решения данной проблемы, то тут будем устанавливать в поле dat тип – Дата/Время и установим формат - дд.мм.гггг (краткий формат даты). Ниже приведена структура БД (поля и их тип данных) (рис. 17). ![]() Рис. 17. Структура таблицы БД Необходимо использовать параметры. Для этого, выделяем компонент TADOQuery и в свойстве Parameters, создаем новый параметр, где в свойстве Name задаем - data, а в свойстве DataType - ftDataTime. Дальше, на событие OnClick кнопки, пишем следующий код: var i:integer; begin try with ADOQuery1 do begin SQL.Clear; SQL.Add('SELECT * FROM MyTable WHERE dat=:data'); Parameters.ParamByName('data').Value:=FormatDateTime('dd.mm.yyyy',Date); Active:=True; for i := 0 to RecordCount-1 do begin ShowMessage(FieldByName('dat').AsVariant); end; end; finally //-//-//-//-//-// end; Определения значения параметра запроса, может осуществлять до запроса или после него. Ошибки при этом возникнуть не должно. В MS Access, в запросе, дату в условии, необходимо заключать в знаки #. Пример: SELECT * FROMMyTableWHEREdatBETWEEN#09.02.2011# AND #08.05.2011# Но, в Delphi, данный метод не работает, поэтому приходится работать, при помощи параметров. Как в БД можно работать с вычисляемыми полями (чтобы значение вычисляемого поля сразу менялось, при вводе нового значения)? Способ состоит в том, что все поля, в том числе и вычисляемое, создаем сразу в БД - MS Access, причем тип данных, поля, в котором будет менять значение - указываем Вычисляемое поле. Что касается второго способа, то вычисляемое поле создадим в нашем проекте, через компоненты TAdoQuery или TAdoTable. Ну и сразу скажу, что есть, не очень правильный 3 метод, при котором можно использовать TTimer. Давайте начнем с нашей БД. У меня в БД имеет следующую структуру (рис. 18). ![]() Рис. 18. Структура таблицы БД БД MS Access создана, теперь переходим к проекту в Delphi, на форме следующие компоненты: TDataSource TDBGrid TADOConnection TADOQuery TButton Выделяем компонент TADOQuery и в свойстве Connection указываем - TADOConenction. Далее, выделяем компонент TDataSource и в свойстве DataSet указываем TADOQuery. Затем, выделяем компонент TDBGrid и в свойстве DataSource указываем TDataSource. Теперь добавим все поля. Для этого, необходимо активировать запрос и подключение. В свойстве компонента TADOConenction – Connected устанавливаем True, а в свойстве компонента TADOQuery - SQL, напишем следующий запрос: SELECT * FROM Test Имя таблицы - Test. Активируем запрос, в свойстве Active, компонента TADOQuery устанавливаем в True. Далее нажимаем, двойным щелчком мыши по компоненту TADOQuery и появляется окно (рис. 19). ![]() Рис. 19. Окно диалога В данном окне, нажимаем правой кнопкой мыши, и из контекстного меню, выбираем пункт Add all fields. В список добавиться все наши поля таблицы. Ну, а теперь создадим Вычисляемое поле. Для этого, в данном окне, нажимаем правой кнопкой мыши и из контекстного меню выбираем пункт New Field, после чего появиться окно, где необходимо заполнить поля, как показано на рисунке (рис. 20). ![]() Рис. 20. Подключение поля Указываем имя вычисляемого поля, устанавливаем указатель на Calculated и указываем тип данных - Integer, можно и с плавающей точкой. Выделяем компонент TADOQuery и на событие OnCalcFields напишем следующий код: ADOQuery1Sum.AsInteger:=ADOQuery1Values.AsInteger*ADOQuery1Count.AsInteger; Не забываем, что свойство AutoCalcFields, компонента TADOQuery должно быть установлено в True. Фильтрация данных в БД Фильтрация данных – это поиск данных. Но фильтрация данных проходит гораздо быстрее, чем обычный поиск по всей БД, с перебором каждой записи. Фильтрация данных, поиск можно организовать с помощью sql-запросов и с помощью функции Locate. Добавим компоненты: TADOConnection TADOQuery TDBGrid TButton TDataSource Создадим произвольную базу данных и таблицу следующей структуры (рис. 21). ![]() Рис. 21. Структура БД Фильтрация данных - это тот же поиск по определенному условию, который указывается в свойстве Filter, например: ADOQuery1.Filtered:=True; ADOQuery1.Filter:='names='+'''Andrey'''; В данном свойстве, указывается поле, которое необходимо фильтровать и условия отбора. Работает достаточно быстро, при большом количестве записей. Не забываем, что необходимо активировать Filtered:=True. С помощью SQL-запросов Просто выбираем записи, по определенному условию, например: ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM Test WHERE names=''Andrey'''); ADOQuery1.Active:=True; Будут найдены записи, которые полностью удовлетворяют условию, а чтобы были найдены записи, по начальному совпадению, то необходимо использовать LIKE, например: ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM Test WHERE names LIKE ''%Andr%'''); ADOQuery1.Active:=True; Данным способом будут выбраны записи, которые начинаются на Andr. С помощью функции Locate Есть также, замечательная функция, которая позволяет также находить записи по неполному совпадению, например: if ADOQuery1.Locate('names','Andr',[loCaseInsensitive,loPartialKey])=Truethen begin ShowMessage('True'); end; Данная часть посвящена расширению компонентов ADO – ADOX. Библиотека ADOX, возможно в настоящее время, не очень используется, скорее всего больше заменяют SQL-запросы. Данная библиотека, поможет с помощью компонентов, классов, создавать базу данных MS Access, создавать таблицы MS Access, а также поля, в том числе и ключевые. Рассмотрим, как импортировать данную библиотеку в проект Delphi, на примере IDE Delphi 7. Выполним команду Project - Import Type Library…, после чего появится окно и в данном окне, выбираем Microsoft ADO Ext. 6.0 for DLL and Security (Version 6.0), после чего нажимаем Create Unit, если в списке только более ранняя версия или наоборот, выбирайте ее (рис. 22). ![]() Рис. 22. Подключение библиотеки После, создаем проект и в него подключаем модуль, в uses, ADOX_TLB, кроме этого на форму нашего проекта я поместил TButton. Теперь, давайте определимся, что будет происходить по нажатию на кнопку: создаваться БД (файл MDB) создаваться таблица (TestTable) создаваться ключевое поле (id-счетчик) создаваться поля, других типов данных (Фамилия-Текстовый, Возраст-Целочисленный) Теперь начнем с создания нашей БД. Для создания новой БД, в модуле ADOX_TLB, описан тип - _Catalog. Для создания правильного файла БД, необходимо написать следующий код: var DB:Catalog; Tables:Table; Columns:Column; begin DB:=CoCatalog.Create; DB.Create('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.mdb'); DB.Set_ActiveConnection('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.mdb'); end; При помощи функции Create, создаем mdb-файл, при этом указывая тип подключения, а также расположение нашей БД. Если файл, уже существует, то естественно будет ошибка. Дальше, при помощи процедуры Set_ActiveConnection устанавливаем активное подключение к БД, чтобы можно было работать, в дальнейшем. Теперь приступим к созданию таблицы. Для этого существует тип _Table. Необходимо вначале проинициализировать переменную, после чего указать имя таблицы, а также указать имя БД, к которой будет принадлежать наша таблица, вот такой код это делает: var DB:Catalog; Tables:Table; Columns:Column; begin DB:=CoCatalog.Create; DB.Create('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.mdb'); DB.Set_ActiveConnection('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.mdb'); Tables:=CoTable.Create; Tables.Name:='TestTable'; Tables.ParentCatalog:=DB; DB.Tables.Append(Tables); end; Инициализируем переменную Tables, затем с помощью свойства Name - задаем имя нашей таблицы, а с помощью свойства ParentCatalog, указываем базу данных, к которой будет принадлежать таблица, затем просто добавляем таблицу в нашу БД. Теперь приступаем к созданию полей, для этого существует тип - _Column, но можно обойтись и без него. Начнем с создания ключевого поля, для этого необходимо задать имя, задать тип данных, а также указать, что оно будет автоматически увеличиваться, при добавлении новой записи в БД, то есть increment, ну и добавить описание данного поля: var DB:Catalog; Tables:Table; Columns:Column; begin DB:=CoCatalog.Create; DB.Create('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.mdb'); DB.Set_ActiveConnection('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.mdb'); Tables:=CoTable.Create; Tables.Name:='TestTable'; Tables.ParentCatalog:=DB; DB.Tables.Append(Tables); Columns:=CoColumn.Create; with Columns do begin ParentCatalog:=DB; Name:='id'; type_:=adInteger; Properties['Autoincrement'].Value:=True; Properties['Description'].Value:='Ключевоеполе'; end; Tables.Columns.Append(Columns,0,0); end; С помощью свойства Name - указываем имя поля, затем с помощью свойства ParentCatalog - указываем БД, где находится таблица, с помощью свойства _type - указываем тип поля, а с помощью свойства Properties - указываем описание поля, а также тип, в нашем случае increment. В самом конце добавляем в таблицу поле, с помощью процедуры Append, где последние 2 параметра - 0. Создадим оставшиеся поля – это Фамилия и Возраст, но уже не будем использовать тип _Column. Для этого, сразу воспользуемся процедурой Append объекта CoTable. var DB:Catalog; Tables:Table; Columns:Column; begin DB:=CoCatalog.Create; DB.Create('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.mdb'); DB.Set_ActiveConnection('Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\test.mdb'); Tables:=CoTable.Create; Tables.Name:='TestTable'; Tables.ParentCatalog:=DB; DB.Tables.Append(Tables); Columns:=CoColumn.Create; with Columns do begin ParentCatalog:=DB; Name:='id'; type_:=adInteger; Properties['Autoincrement'].Value:=True; Properties['Description'].Value:='Ключевоеполе'; end; Tables.Columns.Append(Columns,0,0); Tables.Columns.Append('Фамилия',adVarWChar,255); Tables.Columns.Append('Возраст',adInteger,0); end; Как связывать таблицы между собой? Для начала, необходимо создать базу данных и как минимум две таблицы, которые будем связывать между собой. Например, две таблицы с именами - Таблица1 и Таблица2. Создадим таблицу с фамилиями, а вторая таблица будет с названиями автомобилей. То есть, у каждого владельца, может быть несколько автомобилей. Отношение связи, тут получается, один ко многим. Это так, что сейчас вспомнилось. Ну а теперь, посмотрим на структуры наших таблиц (рис. 23). ![]() ![]() Рис. 23. Подключение библиотеки Теперь необходимо связать эти две таблицы в MS Access. Поле id Таблицы2 предназначено для хранения идентификаторов записей из Таблицы1. По ним будет распознаваться, какая запись из Таблицы2 принадлежит записи из Таблицы1. Для того, чтобы связать таблицы, необходимо перейти в Схему данных, добавить таблицы и связать следующие поля, отношением - один ко многим (рис. 24): ![]() Рис. 24. Связь между таблицами Если в БД MS Access добавлять теперь записи, то для каждой фамилии можно добавлять сколько угодно автомобилей, а если выбрать определенную запись, то покажется список автомобилей для данного человека. В проекте будет что-то похожее. На форме следующие компоненты: TADOConnection TADOTable - 2 шт TDBGrid - 2 шт TDataSource - 2 шт TEdit TButton Необходимо связать компоненты. Выделяем компоненты TADOTable и в каждом, в свойстве Connection, указываем компонент TADOConnection. Дальше выделяем DBGrid1 и связываем с DataSource1, в свойстве DataSource. Компонент DataSource1, в свойстве DataSet, указываем AdoTable1. Дальше главную таблицу необходимо активировать. Выделяем AdoTable1, в свойстве TableName выбираем Таблица1 и свойство Active устанавливаем в True. Обязательно, свойство Connected компонента TADOConnection, должно быть установлено в True. Nеперь главная таблица полностью готова, приступим к подчиненной. Выделяем компонент DBGrid2 и в свойстве DataSource связываем его с компонентом DataSource2, а компонент DataSource2, в свойстве DataSet, связываем с компонентом AdoTable2. Все, теперь выделяем компонент AdoTable2 и в свойстве TableName выбираем Таблица2, в свойстве MasterSource выбираем DataSource1 (в данном случае необходимо выбрать тут TDataSource главной таблицы, то есть главную таблицу). Дальше, в свойстве MasterFields, компонента AdoTable2 (подчиненной таблицы), мы указываем связующие поля, следующим образом (рис. 25). ![]() Рис. 25. Подчиненные поля Все, когда все настроено, также активируем данную таблицу, свойство Active устанавливаем в True. Все, если есть какие-то данные, то можете запустить проект и выделить запись из главной таблицы, автоматически в DBGrid2 для данной записи из главной таблицы выводятся записи из подчиненной таблицы. Добавлять записи необходимо также, выделяем запись из главной таблицы и только после этого, необходимо добавлять запись в подчиненную таблицу. begin ADOTable2.Insert; ADOTable2.FieldByName('auto').AsString:=Edit1.Text; ADOTable2.Post; end; Использование ADO для доступа к базам данных форматов MS Access, xBase и Paradox2 Для хранения атрибутивной информации выбран формат MS Access, который имеет то обстоятельство, что все таблицы хранятся в одном файле (в отличие от Paradox и Dbase) и не требует при этом запущенного сервера, как, к примеру, Interbase. Необходима также связь с файлами форматов .dbf и .db для загрузки/выгрузки данных в/из БД. Возьмем файл .mdb формата MS Access. Можно сделать с помощью самого Access. И создадим небольшую таблицу, к примеру, такую: Object_ID Integer - идентификатор объекта на карте; Object_Description Text (50) - описание объекта на карте. Введем туда какие-либо данные (абсолютно все равно какие). Только надо учесть, что в силу специфики работы могут быть описания, которым пока объекты не соответствуют. Такая связка будет выполнена позже пользователем. Попробуем вывести содержимое таблицы в DBGrid. Например, как на картинке (рис. 26). ![]() Рис. 26. Пример таблицы базы данных Доступ к данным получен. Давайте попробуем что-нибудь исправить или добавить. Например, добавим несколько пустых записей и попробуем внести данные, нажмем POST. В результате (рис. 27). ![]() Рис. 27. Пример ошибки Пробуем добавить новую запись, удалить запись без Object_ID. Результат одинаков – все то же сообщение об ошибке. Запускаем MS Access, пробуем – все отлично. Когда создавали таблицу в MS Access, предлагал создать ключевые поля для таблицы: ADO предполагает, что таблица будет в первой нормальной форме – отсутствие повторяющихся записей. В данном случае не можем создать ключ на то, что есть. Добавим еще одно поле, чтобы каждая запись была однозначно определена (т.е. некий внутренний идентификатор). Чтобы не думать о содержимом нового поля, делаем просто – пусть будет автоинкрементное поле, и создадим на него первичный ключ. Делаем – все работает. Пока не добавляем больше одной записи. Если добавим подряд несколько, увидим очень интересную ситуацию как на картинке (рис. 28). ![]() Рис. 28. Пример результата с автоинкриментом Содержимое Internal_ID для записей равно нулю, хотя это автоинкрементное поле. Только закрытие и последующее открытие таблицы приводит к тому, что видим то, что ожидалось (рис. 29). ![]() Рис. 29. Пример результата с корректным автоинкриментом Чтобы пользователь не видел внутреннего идентификатора, делаем поле невидимым - TField.Visible := FALSE. ADO и файлы xBASE и Paradox В результате смогли наладить работу через ADO к файлам формата MS Access. Также должны использовать файлы xBase и Paradox в качестве обменных файлов. Все примеры работают одинаково - через Microsoft OLE DB provider for ODBC. Все редакторы, которые делают строку подключения, всегда показывают только .mdb файлы в диалоге, в котором задается путь к файлу БД. Что-то тут нечисто, подумал я - а как же тот же самый Access это делает? Ведь явно не через ODBC, стало быть, есть какая-то хитрость. После примерно недельных поисков в Интернете решение было найдено. Да, действительно можно использовать 'Microsoft Jet 4.0 OLE DB Provider'. Чтобы не рассказывать долго, представим, что у нас на диске D в корне лежит файл Test.dbf формата dBase 5.0. Строка коннекта для этого случая будет выглядеть так: 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\; Extended Properties=dBase 5.0; Mode=Read|Write|Share Deny None; Persist Security Info=True'; После опытов над форматом .dbf оказалось, что все выше сказанное для формата mdb совершенно не относится к этому формату - и все требования про первую форму можно и не соблюдать. Формат Paradox Хорошо, запускаем справку по MS Jet SQL и ищем раздел создания индексов или первичных ключей. Находим следующее: CREATEINDEX имя_индекса ON название_таблицы (название_поля) WITHPRIMARY. ALTERTABLE название_таблицы ADDCONSTRAINT имя_ограничения PRIMARYKEY (название_поля) Все далее сказанное абсолютно одинаково для обоих вариантов. Предположим, что таблица называется ExpTbl.db и поле, на которое хотим наложить первичный ключ, называется IntrernalID. Подключаемся к таблице и задаем такую строку SQL для исполнения: CREATEINDEX ExpTable ON ExpTable (InternalID) WITHPRIMARY Значащие ограничения для драйвера PARADOX: для того, чтобы имели возможность производить действия по добавлению, удалению записей или редактированию данных в таблице, таблица должна иметь первичный ключ; первичный ключ должен быть определен для первых 'n' полей таблицы; нельзя создавать для таблицы индексы, если не определен первичный ключ; первый создаваемый для таблицы уникальный индекс будет создан как первичный ключ; первичный ключ может быть создан для таблицы только в том случае, если в ней нет ни одной записи; действия по добавлению или удаления полей в таблице должны быть произведены до того, как для нее создан первичный ключ. Для работы через ADO с файлами xBase или Paradox, необходимо указывать нужный драйвер в секции Extended Properties и в секции Data Source только путь до файла. Для xBase на этом все трудности закончены, а вот для Paradox необходимо задание первичного ключа как для формата MS Access, при этом есть определенные ограничения при задании названий ключей, так же, как и возможных индексов. Для добавления данных в таблицы можем вставлять по одной (Table.Append (Insert); Table.Post), а можем воспользоваться вариантом SELECT … INTO, INSERT … INTO. Работа с ADO в Delphi на примере БД MS Excel Как использовать в своем приложении (программе) на Delphi БД в виде MS Excel. Для начала давайте заполним лист в MS Excel. Первая строка в каждом столбце всегда будет брать приложение как название столбцов, то есть не берет название столбцов такое - A, B, C и так далее. Так что в первой строке столбца А и столбца B написаны ФИО и Оценка соответственно для каждого столбца. Это и будут заголовки, затем ниже заполнены данные, которые будут в БД. Теперь создадим подключение. создается подключение похоже, как и в MS Access. На форме компоненты: TDBGrid TADOQuery TADOConnection TDataSource Как связывать компоненты: TADOQuery c TADOConnection в свойстве - Connection TDataSource с TADOQuery в свойстве DataSet TDBGrid c TDataSource в свойстве DataSource В TADOConnection установим свойство LongPromt в False. Теперь приходим к подключению. В свойстве TADOConnection – ConnectionString нажимаем на кнопку «…», далее появляется окно вида (рис. 30). ![]() Рис. 30. Окно подключения Нажимаем на кнопку «Build…» и появляется следующее окно (рис. 31). ![]() Рис. 31. Окно выриантов подключений В данном окне выбираем следующего провайдера: Microsoft OLE DB Provider for ODBC Drivers и нажимаем кнопку Далее и видим следующее окно (рис. 32). ![]() Рис. 32. Окно настроек подключения В этом окне сразу ставим указатель на Использовать строку подключения и нажимаем на кнопку Сборка, после чего появляется окно (рис. 33). ![]() Рис. 33. Окно свойств подключения В окне переходим на вкладку Источник данных компьютера, в появившемся списке выбираем – Файлы Excel, а точнее жмем левой кнопкой мыши по сроке двойным щелчком и в появившемся окне указываем путь к Excel-книги, которую создавали. После этого нажимаем на пноку Ok. Если файл Excel, где таблица находится лежит в одном каталоге с программой, то в свойстве компонента TADOConnection – ConnectionString будет прописан путь к Excel-файлу, сотрите путь, а оставьте только имя Excel файла с расширением, а в свойстве DefaultDataBase этого же компонента, напишите имя Excel-файла с расширением. Тогда при запуске приложения, не будет возникать ошибок с неправильно заданым путем к вашей БД. Далее в TDBGrid нажмем по нему двойным щелчком и в появившемся окне создаим 2 строки, это столбцы. Создаются путем нжатия в данном окне на кнопку Add New (Ins). Далее выделив кажду строку в свойстве FieldName для первой строки напишем - ФИО, так как в Excel-файле написал в первую строку название столбца (для ячейки A1), а выделив вторую строку, что создали в TDBGrid, в свойстве FieldName напишем - Оценка, так как именно такое название столбца написано (в ячейке А2). Теперь можно активировать данные. Для этого на событие главной формы – OnCreate напишем следующее: begin try ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM [Лист1$]'); ADOQuery1.Active:=True; except on e:Exception do end; Все тот же запрос, только вместо имя таблицы, указываем имя листа в Excel, заключив в квадратные скобки и поставив в конце знак $. Рассмотрим добавление и редактирование данных. Необходимо еще одно поле в Excel-книги - id, и придется вручную заполнять, при инициализации данных получаем количество записей, а затем при добавлении добавляем значение в поле id. Будет получаться уникальное значение, что поможет при редактировании. Необходимо получить количество записей в БД, что делаем с помощью RecordCount. Смотрим код события OnCreate формы ниже: procedure TForm1.FormCreate(Sender:TObject); begin try id:=1; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM [Лист1$]'); ADOQuery1.Active:=True; id_count:=ADOQuery1.RecordCount+1; except on e:Exception do end; end; Для добавления данных все тоже самое, что и было в ADO с MS Access, только здесь повторюсь надо учитывать id вручную, в MS Access все было подругому, там был счетчик, что упрощало работу. Код добавления смотрим ниже: begin try ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('INSERTINTO [Лист1$] (ФИО,Оценка,id) VALUES(''Иванов Иван Иванович'',5,'+IntToStr(id_count)+')'); ADOQuery1.ExecSQL; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM [Лист1$]'); ADOQuery1.Active:=True; except on e:Exception do end; Дополнительный запрос, для обновления данных в TDBGrid. Для редактирования данных надо получить сначала id, для этого на событие компонента TDBGrid – OnCellClick напишем: procedure TForm1.DBGrid1CellClick(Column: TColumn); begin id:=ADOQuery1.Fields.Fields[2].AsInteger; end; id поле находится в книге Excel в 3 столбце, но так как нумерация в ADO столбцов начинается с 0, то указываем Fields[2]. Для редактирования данных применим туже технологию, что и в случае с MS Access: begin try ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('UPDATE [Лист1$] SETФИО=''ПетровПетрПетрович'',Оценка=10 WHERE id=:pid'); ADOQuery1.Parameters.ParamByName('pid').Value:=id; ADOQuery1.ExecSQL; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM [Лист1$]'); ADOQuery1.Active:=True; except on e:Exception do end; Дополнительный запрос на обновления данных, id уже получен. В комоненте TADOQuery задайте в свойстве Parameters новый параметр – pid с типом данных ftInteger. Попробуем какой-нибудь не большой поиск организовать, здесь используем параметр SQL-запроса - LIKE, то есть найдет все записи с совпадениями: begin try ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('SELECT * FROM [Лист1$] WHEREФИО LIKE ''%Иванов%'''); ADOQuery1.Active:=True; except on e:Exception do end; Можно организовать поиск по полному совпадению через WHERE. Теперь понимаете, что использовать MS Excel в качестве БД тут не логично, много чего вручную контролировать нужно, ограниченное количество записей, да и с удалением проблемы, но зато отлично тут можно написать конвертацией данных, а также экспорт в Excel. Контрольное задание Индивидуально (согласно заданию преподавателя) разаработать однотабличную базу данных с использованием инструментов MSAccess и MSExcel. Подключить базы к BorlandDelphi. Прописать функциональные кнопки аналогично приведенным формам и алгоритмам. |