Главная »Статьи » |
Человеку следует познавать, исходя из правила, что он далек от действительности. Применение локальных баз данных часто чрезвычайно эффективно и использование ADO для работы с базой MS Access представляется весьма неплохим решением. Организация связки Master-Detail с использованием компонентов TADOTable описана в литературе неоднократно, но, к сожалению, это решение не позволяет фильтровать подчиненную таблицу. Поэтому здесь рассматривается вариант с использованием компонентов TADODataSet и SQL-выражений. Создадим приложение, демонстрирующее графики некоторых сигналов: синус, меандр, треугольник, пила. Наименования сигналов хранятся в главной таблице tbMaster, их значения — в подчиненной таблице tbDetail.
Примечания:
Практика
Настраиваем компоненты в соответствии с рисунком выше. Подключаем модули: Series, ComObj, ActiveX. Задаем константы: resourcestring rsConnStrFmt = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s'; rsCreateMasterTable = 'CREATE TABLE tbMaster (' + #13#10 + 'MainID COUNTER CONSTRAINT PrimaryKey PRIMARY KEY,' + #13#10 + '[Name] TEXT(31)' + #13#10 + ')'; rsCreateDetailTable = 'CREATE TABLE tbDetail (' + #13#10 + 'DetailID COUNTER CONSTRAINT PrimaryKey PRIMARY KEY,' + #13#10 + 'MainID INTEGER,' + #13#10 + 'X FLOAT,' + #13#10 + 'Y FLOAT' + #13#10 + ')'; rsCreateConstraint = 'ALTER TABLE tbDetail ADD CONSTRAINT MasterDetail ' + 'FOREIGN KEY (MainID) REFERENCES tbMaster ON UPDATE CASCADE ON DELETE CASCADE'; Функция создания файла новой базы данных: function CreateAccessDatabase(AFileName: String): String; var Catalog: OleVariant; begin Result:= ''; try Catalog:= CreateOleObject('ADOX.Catalog'); Catalog.Create(Format(rsConnStrFmt, [AFileName])); VariantClear(Catalog); except on E: Exception do Result:= E.Message; end; end; Функция форматирования строки подключения: function GetConnStr(AFileName: String): String; begin Result:= Format(rsConnStrFmt, [AFileName]); end; Обработчик нажатия кнопки Create (создание файла новой базы данных, таблиц, добавление данных): procedure TfrmMasterDetail.btnCreateClick(Sender: TObject); begin SaveDlg.InitialDir:= ExtractFilePath(Application.ExeName); if not SaveDlg.Execute then Exit; // Если файл существует - стереть его сначала if FileExists(SaveDlg.FileName) then DeleteFile(SaveDlg.FileName); ADOConnect.Close; // Создаем файл базы CreateAccessDatabase(SaveDlg.FileName); // Создаем таблицы ADOConnect.ConnectionString:= GetConnStr(SaveDlg.FileName); ADOConnect.Execute(rsCreateMasterTable, cmdText); ADOConnect.Execute(rsCreateDetailTable, cmdText); ADOConnect.Execute(rsCreateConstraint, cmdText); // Открываем таблицы ADOConnect.Open; adstMaster.Open; adstDetail.Open; // Добавляем кривые adstDetail.DisableControls; adstMaster.DisableControls; try AddCurves; finally adstDetail.EnableControls; adstMaster.EnableControls; end; Caption:= Format('%s - %s', [Application.Title, SaveDlg.FileName]); end; Остальное см. прилагаемый пример.
При обнаружении сбоев в процессе добавления данных с сообщением "Не удается найти строку для обновления..." следует в начало обработчика события OnDataChange обоих DataSource добавить:
if adstMaster.Active then adstMaster.Properties['Update Resync'].Value:= adResyncAll;для adstMaster и if adstDetail.Active then adstDetail.Properties['Update Resync'].Value:= adResyncAll;для adstDetail. К статье прилагаются файлы с исходным кодом на Delphi 2010. Внимание! Запрещается воспроизведение
данной статьи или ее части без согласования с автором. Если вы желаете разместить
эту статью на своем сайте или издать в печатном виде, свяжитесь с автором. |