powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Хранение документов в БД
9 сообщений из 9, страница 1 из 1
Хранение документов в БД
    #32653561
Dr_Mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Не знаю, может быть стоило поместить этот вопрос в другой форум? :-(

В своей БД храню документы (для простоты возьмем, например, тот же MS OFFICE). Для их редактирования выдираюих из БД во временный файл, и запускаю нужное приложение с параметром-именем файла. После внесения изменений пользователь сохраняет документ. Как отследить и обновить БД?

Интересует сам принцип, язык любой, система - Windows.
...
Рейтинг: 0 / 0
Хранение документов в БД
    #32653569
Фотография Dnico
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Енто действительно скорее в другой форум.

авторКак отследить и обновить БД?
Надо пользовать OLE.
...
Рейтинг: 0 / 0
Хранение документов в БД
    #32653586
Dr_Mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
DnicoНадо пользовать OLE.

Согласен, это в случае если есть клиент как отдельное приложение.

Но, предположим, существует еще и сайт, на котором по поисковому запросу выдается ссылка на документ. При клике на ссылке документ выдирается из БД, и помещается в тмп-файл скриптом на сервере.

В ходе раздумий во время написания поста пришел к тому, что необходимо там же на сервере неким скриптом проверять дату изменения тмп-файла, и в случае отличия ее от предыдущей, обновлять БД.

Никакой событийной модели взаимодействия с сервером БД похоже просто не может существовать в принципе. А как хотелось бы :-(((.
PS. Подарите мне губозакаточную машинку
...
Рейтинг: 0 / 0
Хранение документов в БД
    #32653591
Фотография Dnico
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну тут можно в PHP или Perl обрабатывать события скорее всего и запихивать все обратно. Точно не скажу - не занимался ...

Best regards,
Dnico.
...
Рейтинг: 0 / 0
Хранение документов в БД
    #32654083
Лентяй
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dr_MikeНе знаю, может быть стоило поместить этот вопрос в другой форум? :-(

В своей БД храню документы (для простоты возьмем, например, тот же MS OFFICE). Для их редактирования выдираюих из БД во временный файл, и запускаю нужное приложение с параметром-именем файла. После внесения изменений пользователь сохраняет документ. Как отследить и обновить БД?

Интересует сам принцип, язык любой, система - Windows.

У меня все просто - программа спрашивает у ползателя заносить ли измененный документ обратно в базу. Потому как вполне реальна такая ситуация: ползатель может вытащить документ, подправить его и отправить кому-нибудь по почте, но при этом изменения в базу вносить не надо. Следовательно, даже если отследиш, что документ был изменен - это еще не значит, что его необходимо изменять в базе. А изменения можно отследить по дате создания/последнего изменения, к примеру, или при помощи функции WIN API ReadDirectoryChanges ...
...
Рейтинг: 0 / 0
Хранение документов в БД
    #32654091
alex_k
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
мне кажется, документы в бд должны состоять из объектов бд, тоесть записей в таблицах. тогда штатные средства работы с бд, позволят эффективную работу с такими документами, иначе ваша система будет сильно зависеть от разработчиков третьего софта.

в оффисные форматы можно выводить документы только в виде копии, ни к чему не обязывающей саму бд.
а все изменения в бд, делать через соответствующие интерфейсы разработанные не какой-то малоизвестной майкрософт, а уважаемым васей пупкиным, как бы нелепо это не звучало :-)
...
Рейтинг: 0 / 0
Хранение документов в БД
    #32655035
Фотография mv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну а вот как я, великий и ужасный, делаю. После экспериментов c MS Word + TOleContainer, а потом c MS Word + OLE я остановился на след. схеме:

Использую компонент TWordApplication. Документы можно:
Код: plaintext
1.
2.
3.
4.
- создавать:
   - из MS Word шаблонов;
   - загрузить из файла.
- редактировать
- удалять

Схема такая:

Чтобы отредактировать документ в табличке ATableName в поле AFieldName (идентификатор записи (Integer) AId), я вызываю процедуру:

Код: plaintext
1.
   procedure EditDoc(ATableName, AFieldName : String;
      AId : Integer);

Таким образом, можно окрывать для редактирования любое число документов, не зависимо от состояния текущего курсора в рабочей базе.

Все открытые документы фиксируются в специальном объекте типа TWordDocumentsCortage.


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
procedure TForm1.wdAppDocumentBeforeSave(ASender: TObject;
  const Doc: _Document; var SaveAsUI, Cancel: WordBool);
var i : integer;
  Found : Boolean;
  tmpFileName1,
  tmpFileName2 : string;
  PDoc : PWordDocCortage;

begin
  if Doc.Path = '' then exit;
  PDoc := wdCortage.Doc('TBL', Doc.FullName); // Смотрим в кортеже
  if not Assigned(PDoc) then exit;
  Cancel := True;
  if Doc.Saved then exit;
  // Ну, все. Этот документ  - точно наш, его нужно сохранить в базе.
  tmpFileName1 := Doc.FullName;
  SaveToFile(Doc, tmpFileName1);
  tmpFileName2 := SaveToTmpFile(Doc);
  with PDoc^ do begin
    SaveFileToBlob(tmpFileName1, TableName, FieldName, Id);
    DeleteFile(tmpFileName1);
    FileName := tmpFileName2;
  end;
end;


Ну так вот, в компоненте TWordApplication обработчики OnDocumentBeforeClose и OnDocumentBeforeSave выполняют сохранение документов в базу.

Вот:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
procedure TForm1.wdAppDocumentBeforeClose(ASender: TObject;
  const Doc: _Document; var Cancel: WordBool);
var i, fidx : integer;
  Found : Boolean;
  tmpFileName1,
  tmpFileName2 : string;
  PDoc : PWordDocCortage;

  SaveChanges,
  OriginalFormat,
  RouteDocument : OleVariant;


begin
  if Doc.Path = '' then exit;
 // Сначала смотрим в кортеже 
  Found := False;
  for i :=  0  to pred(wdCortage.wdDocsList.Count) do
    if PWordDocCortage(wdCortage.wdDocsList.Items)^.FileName =
      Doc.FullName then
      begin
        Found := True;
        PDoc := wdCortage.wdDocsList.Items[i];
        fidx := i;
        Break
      end;
  if not Found then exit;  [i]// "Чужой" документ  
   // Ну, все. Этот документ  - точно наш, его нужно сохранить в базе. 
  if not Doc.Saved then begin
    Doc.Save;

    Cancel := True;

    SaveChanges := wdDoNotSaveChanges;
    OriginalFormat := wdWordDocument;
    RouteDocument := False;

    tmpFileName1 := Doc.FullName;

    Doc.Close(SaveChanges, OriginalFormat, RouteDocument);

    with PDoc^ do begin
      SaveFileToBlob(tmpFileName1, TableName, FieldName, Id);
      DeleteFile(tmpFileName1);
    end;
  end;

  Dispose(PDoc);
  wdCortage.wdDocsList.Delete(fidx);

end;


И вот:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
procedure TForm1.NewDoc(TemplateName : OleVariant);  // Создание из шаблона 
var // ItemIndex, 
 NewTemplate, TemplateFileName, DocumentType,
 VisibleDoc : OleVariant;
 tmpFileName1,
 tmpFileName2  : String;
 ADoc : WordDocument;
begin
  try  // Сеанс добавления документа 
    try  // Попытка коннекта 
      wdApp.Disconnect;
      if wdApp.Application <> nil then
        wdApp.Connect;

      wdApp.Options.CheckSpellingAsYouType:=False;  // Ускоряем работу 
      wdApp.Options.CheckGrammarAsYouType:=False;

 //      ItemIndex := %af_src_comm_0 + 1; 
 //      Application.ProcessMessages; 

       // Создаем документ по шаблону 
      TemplateFileName := ExtractFilePath(Application.ExeName)+ TemplateName;
      NewTemplate := False;
      DocumentType := wdTypeDocument;
      VisibleDoc := True;
      ADoc := wdApp.Documents.Add(TemplateFileName, NewTemplate, DocumentType, VisibleDoc );

    except
      on E : Exception do begin
        ShowMessage('Ошибка активизации приложения Microsoft Word. '+
         E.Message);
        if Assigned(wdApp) then
          if (wdApp.Documents.Count >  0 ) then begin
            wdApp.AutoQuit := True;  // Пусть не зависает фигня в системе! 
            Application.ProcessMessages;
          end;
        exit
      end;  // on E: 
    end;  // Попытка коннекта 

    try  // Построение отчета (преобразования шаблона) 

      ADoc.Activate;
      BuildReport(ADoc);  // Ну, тут происходит обработка шаблона. Сам сделаешь. 
      tmpFileName1 := SaveToTmpFile(wdApp.ActiveDocument); // Два раза сохраняем - 
 //      tmpFileName1 := SaveToTmpFile(wdApp.ActiveDocument);// почему-то с первого 
      tmpFileName2 := SaveToTmpFile(wdApp.ActiveDocument); // раза не разблокируется 

      SaveFileToBlob(tmpFileName1, 'TBL', 'FBL',
        dtMain.FieldByName('TBL_ID').AsInteger);
      DeleteFile(tmpFileName1);
      wdCortage.Add('TBL', 'FBL', tmpFileName2,
        dtMain.FieldByName('TBL_ID').AsInteger);
    except
      on E : Exception do begin
        ShowMessage('Ошибка создания отчета в Microsoft Word. '+
         E.Message);
        if Assigned(wdApp) then
          if (wdApp.Documents.Count >  0 ) then
            wdApp.AutoQuit := True;  // Пусть не зависает фигня в системе! 
       exit
      end;
    end  // Построение отчета 

  finally
    Application.ProcessMessages;
  end;  // Сеанс добавления документа 

end;


Вот, в общем, и все.

Ну, вот еще мелочи - создание документа из шаблона:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
procedure TForm1.EditDoc(ATableName, AFieldName : String;
      AId : Integer);
var i : integer;
    DQry  : TpFIBQuery;
    PDoc  : PWordDocCortage;
    tmpFileName : String;
    FileName : OleVariant;


begin
  PDoc := wdCortage.Doc('TBL', AId);  // Смотрим в кортеже 
  DQry := TpFIBQuery.Create(Self);
  try
   wdApp.Disconnect;
   if wdApp.Application <> nil then
     wdApp.Connect;

    DQry.Database := dbMain;
    DQry.Transaction := trWrite;
    if not DQry.Transaction.InTransaction then
      DQry.Transaction.StartTransaction;
    if not Assigned(PDoc) then  // В кортеже нет, загружаем из базы 
      try
          tmpFileName := NewTmpFile();
          DQry.SQL.Text := 'Select ' + AFieldName +
          ' from ' + ATableName + ' Where ' + ATableName + '_ID = :ID';
          DQry.Prepare;
          DQry.ParamByName('ID').AsInteger := AId;
          DQry.ExecQuery;
          DQry.FieldByName(AFieldName).SaveToFile(tmpFileName);
          if DQry.Transaction.InTransaction then
            DQry.Transaction.Commit;
      except
        on E : Exception  do begin
          if DQry.Transaction.InTransaction then
            DQry.Transaction.Rollback;
          raise Exception.Create('Ошибка при загрузке документа из бызы'+
            # 13  + E.Message);
        end;
      end
    else  // Found! - есть в кортеже, открываем существующий 
       tmpFileName := PDoc^.FileName;
    if not FileExists(tmpFileName) then
      raise Exception.Create('Файл с документом не был создан!');

    FileName := tmpFileName;
    OpenDoc(tmpFileName);  // Открываем документ по имени файла 
    wdApp.Visible := False;
    wdApp.Visible := True;
    wdApp.ActiveWindow.WindowState := wdWindowStateMinimize;
    wdApp.Documents.Item(FileName).Activate;
    wdApp.ActiveWindow.SetFocus;
    wdApp.ActiveWindow.WindowState := wdWindowStateMaximize;

    if not Assigned(PDoc) then  // Отсутствует 
      wdCortage.Add(ATableName, AFieldName, tmpFileName,
        dtMain.FieldByName(ATableName+'_Id').AsInteger)
  finally
    DQry.Free;
  end
end;


А вот функция редактирования:

[SRC Delphi]
procedure TForm1.EditDoc(ATableName, AFieldName : String;
AId : Integer);
var i : integer;
DQry : TpFIBQuery;
PDoc : PWordDocCortage;
tmpFileName : String;
FileName : OleVariant;


begin
PDoc := wdCortage.Doc('TBL', AId); // Смотрим в кортеже
DQry := TpFIBQuery.Create(Self);
try
wdApp.Disconnect;
if wdApp.Application <> nil then
wdApp.Connect;

DQry.Database := dbMain;
DQry.Transaction := trWrite;
if not DQry.Transaction.InTransaction then
DQry.Transaction.StartTransaction;
if not Assigned(PDoc) then // В кортеже нет, загружаем из базы
try
tmpFileName := NewTmpFile();
DQry.SQL.Text := 'Select ' + AFieldName +
' from ' + ATableName + ' Where ' + ATableName + '_ID = :ID';
DQry.Prepare;
DQry.ParamByName('ID').AsInteger := AId;
DQry.ExecQuery;
DQry.FieldByName(AFieldName).SaveToFile(tmpFileName);
if DQry.Transaction.InTransaction then
DQry.Transaction.Commit;
except
on E : Exception do begin
if DQry.Transaction.InTransaction then
DQry.Transaction.Rollback;
raise Exception.Create('Ошибка при загрузке документа из бызы'+
#13 + E.Message);
end;
end
else // Found! - есть в кортеже, открываем существующий
tmpFileName := PDoc^.FileName;
if not FileExists(tmpFileName) then
raise Exception.Create('Файл с документом не был создан!');

FileName := tmpFileName;
OpenDoc(tmpFileName); // Открываем документ по имени файла
wdApp.Visible := False;
wdApp.Visible := True;
wdApp.ActiveWindow.WindowState := wdWindowStateMinimize;
wdApp.Documents.Item(FileName).Activate;
wdApp.ActiveWindow.SetFocus;
wdApp.ActiveWindow.WindowState := wdWindowStateMaximize;

if not Assigned(PDoc) then // Отсутствует
wdCortage.Add(ATableName, AFieldName, tmpFileName,
dtMain.FieldByName(ATableName+'_Id').AsInteger)
finally
DQry.Free;
end
end;

[/src]
Удачи.
...
Рейтинг: 0 / 0
Хранение документов в БД
    #32655044
Фотография mv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вах, функция редактирования не отформатировалась:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
procedure TForm1.EditDoc(ATableName, AFieldName : String;
      AId : Integer);
var i : integer;
    DQry  : TpFIBQuery;
    PDoc  : PWordDocCortage;
    tmpFileName : String;
    FileName : OleVariant;


begin
  PDoc := wdCortage.Doc('TBL', AId);  // Смотрим в кортеже 
  DQry := TpFIBQuery.Create(Self);
  try
   wdApp.Disconnect;
   if wdApp.Application <> nil then
     wdApp.Connect;

    DQry.Database := dbMain;
    DQry.Transaction := trWrite;
    if not DQry.Transaction.InTransaction then
      DQry.Transaction.StartTransaction;
    if not Assigned(PDoc) then  // В кортеже нет, загружаем из базы 
      try
          tmpFileName := NewTmpFile();
          DQry.SQL.Text := 'Select ' + AFieldName +
          ' from ' + ATableName + ' Where ' + ATableName + '_ID = :ID';
          DQry.Prepare;
          DQry.ParamByName('ID').AsInteger := AId;
          DQry.ExecQuery;
          DQry.FieldByName(AFieldName).SaveToFile(tmpFileName);
          if DQry.Transaction.InTransaction then
            DQry.Transaction.Commit;
      except
        on E : Exception  do begin
          if DQry.Transaction.InTransaction then
            DQry.Transaction.Rollback;
          raise Exception.Create('Ошибка при загрузке документа из бызы'+
            # 13  + E.Message);
        end;
      end
    else  // Found! - есть в кортеже, открываем существующий 
       tmpFileName := PDoc^.FileName;
    if not FileExists(tmpFileName) then
      raise Exception.Create('Файл с документом не был создан!');

    FileName := tmpFileName;
    OpenDoc(tmpFileName);  // Открываем документ по имени файла 
    wdApp.Visible := False;
    wdApp.Visible := True;
    wdApp.ActiveWindow.WindowState := wdWindowStateMinimize;
    wdApp.Documents.Item(FileName).Activate;
    wdApp.ActiveWindow.SetFocus;
    wdApp.ActiveWindow.WindowState := wdWindowStateMaximize;

    if not Assigned(PDoc) then  // Отсутствует 
      wdCortage.Add(ATableName, AFieldName, tmpFileName,
        dtMain.FieldByName(ATableName+'_Id').AsInteger)
  finally
    DQry.Free;
  end
end;

...
Рейтинг: 0 / 0
Хранение документов в БД
    #32655140
Dr_Mike
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем за содержательные и весьма познавательные ответы.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Хранение документов в БД
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]