Search
Write a publication
Pull to refresh

Delphi и новый тип данных в MS Access 2007 — Attachments

Предистория


Как известно прогресс не стоит на месте, все течет и развивается. Вот так в очередной раз прогресс стукнул по лбу в виде задачи перевести текущий проект на новую базу данных MS Access 2007 и обязательно нужно использовать его новые возможности в виде полей типа «Attachments».

История

Волею судеб я с самого начала писал программы на Delphi, так мне казалось и быстрее и удобнее. Так что портировать проект мне тоже пришлось на Delphi. Для начала я решил выяснить что ж это за такой тип данных и как с ним бороться. После недолгих поисков, ковыряния во встроенном в Access Basicа выяснилось, что это новый тип данных, который представляет собой что-то вроде вложенной в поле таблицы данных (в ней такие поля: айдишник строки, имя файла, и собственно сам файл и еще что-то, кому интересно открываете Access и смотрите). Например: пользователь добавляет строку в таблицу с именем автора книг, его данными и добавляет поле Attachment, и в этом поле загружает 25 книг автора и одно его видео ну и парочке аудиокниг.
И суть задачи в том, чтобы для конкретного автора вытащить и сохранить на диск вот эти парочку аудиокниг и одно видео.
Книг и информации про это маловато, поэтому собрав на основе всего найденного свое решение я остался доволен.
Итак что нам понадобится:
  • Delphi;
  • Импортированный файл DAO_TLB.pas;
  • Прямые руки;

Начнемс.

Подключение к базе данных через DAO

Декларируем такие переменные, они нам потребуются для наших операций. Я их подключал в разделе public
Также не забываем подключить наш юнит DAO_TLB.pas.
public
att : Recordset2;
DAO: _DBEngine;
db: DAO_TLB.Database;
MyTable: Recordset2;


Далее функция подключения к базе:
procedure TForm1.ConnectviaDAO;
begin
if (length(databasename)=0) or not FileExists(databasename) then
if OpenDialog1.Execute then
databaseName := OpenDialog1.FileName;
TableName := 'Table1';
//указываем файл базы данных и имя нашей таблицы. У меня в таблице было всего два поля, айдишник и атачментс.

V120 := 'DAO.DBEngine.120'; // указываем версию движка, который будем использовать
SetCurrentDir(ExtractFileDir(Application.ExeName));
try
try
ClassID := ProgIDToClassID(v120);
except
end;
DAO := CreateComObject(ClassID) as _DBEngine; // создаем COM объект с указанием его типа
db := DAO.OpenDatabase(DatabaseName, true, false, ''); // открываем базу данных
MyTable :=Recordset2(db.OpenRecordset(TableName,EmptyParam,EmptyParam,EmptyParam)); // открываем нашу таблицу
MyTable.MoveFirst; // идем на первую запись так как иногда наблюдается открытие таблице с курсором не на первой строке
if MyTable.Fields['Files'].type_=dbAttachment then // проверяем тип поля, чтоб не делать лишних движений
begin
att := Recordset2(TVarData(MyTable.Fields[1].Value).VDispatch); открываем наше поле как вложенную таблицу типа Recordset2
att.MoveFirst;
while not att.EOF do
begin
ListBox1.Items.Add(att.Fields['FileName'].Value); //здесь читаем имена вложенных файлов для отображения, внимание имя поля здесь статичное.
att.MoveNext;
end;
end;
except
on E: Exception do
begin

ShowMessage(e.message);
end;
end;
end;


В результате у нас есть подключенная таблица приложений, дальше у нас есть несколько вариантов действий:
  • Сохранить файл из списка вложенных файлов
  • Заменить файл в списке
  • Добавить файл в списке
  • Удалить файл

Итак начнем по-порядку:
Сохраняем файл

procedure TForm1.SaveFile(Filename:string);
begin
att.MoveFirst;
while not att.EOF do
begin
if att.Fields['FileName'].Value=Filename then //перебираем строки в таблице вложений, пока не найдем наш файл, берем его из поля FileData в виде Field2 и сохраняем на диск
begin
(att.Fields['FileData'] as Field2).savetofile('c:\'+filename);
break;
end
else
att.MoveNext;
end;
end;


Добавляем файл

procedure TForm1.Button2Click(Sender: TObject);
var
atField:Field2;
begin
if addDialog.Execute then // диалог куда сохранять
begin
MyTable.Edit; // перевод таблицы в режим редактирования обязателен
att.MoveFirst;
att.AddNew; // добавляем новый атачмент, указатель автоматически перейдет на него
atField := Field2(att.Fields['FileData']); // получаем указатель на поле данных файла
atField.LoadFromFile(addDialog.FileName); // загружаем туда файл
att.Update(dbUpdateRegular,False); // сохраняем изменения в таблице вложений
MyTable.Update(dbUpdateRegular,False);// сохраняем изменения в главной таблице
end;

end;

Удаление файла

filename:= listbox1.Items[listbox1.ItemIndex]; // имя файла который надо удалить
att.MoveFirst;
while not att.EOF do// перебираем имена пока не найдем
begin
if att.Fields['FileName'].Value=filename then
begin
att.Delete; //удаляем вложение
break;
end
else
att.MoveNext;

end;


Ну вот собственно и все, как оказалось ничего страшного.
Спасибо за внимание
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.