Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.04;
Скачать: CL | DM;

Вниз

Содержимое Blob поля надо поместить в MS Word (TwordApplication)   Найти похожие ветки 

 
Shade   (2004-06-04 15:15) [0]

Приветствую всех, уважаемые Дамы и Господа программисты.
Задача такая: Есть таблица в базе данных MSSQL 2000. Там 2 поля: одно - идентификатор, другое поле типа Blob (Image в терминах MSSQL 2000). Коннект происходит при помощи ADOConnection, все запросы выполняются при помощи ADOQuery. Кждая запись в таблице представляет собой файл вордовского формата (Хранилище файлов ворд). Так вот: надо вытащить файл из базы запросом и поместить его в ворд напрямую, не создавая на диске никаких временных файлов. Для соединения с вордом надо использовать twordapplication и только его. Вот мой фрагмент кода:

sql.Clear;
   sql.Add("select preddiag from recived where pereid = :per_par");
   Parameters.ParamByName("per_par").Value := SG_pat.Cells[7,SG_pat.row];
   open;
   msword := TWordApplication.Create(nil);
   try
     msword.ConnectKind := ckRunningOrNew;
     msword.Connect;
     msword.Visible := true;
     msword.Activate;

{Вот тут должно стоять что-то, что бы считало данные из открытой квери из поля "preddiag" и поместило бы в ворд (twordapplication) только вот что ?}

   Finally
     msword.Disconnect;
     msword.Free;
   end;
   close;
   sql.Clear;

Сталкивался ли кто-то из вас с подобной задачей ? Очень жду ваших ответов.


 
Курдль   (2004-06-04 15:18) [1]


> Сталкивался ли кто-то из вас с подобной задачей ? Очень
> жду ваших ответов.

Я сталкивался. Конечно же не с MSSQL 2000. У меня была нужда сразу отображать в OLE Container. Ща гляну в исходниках.


 
Курдль   (2004-06-04 15:27) [2]

Сам разберись. Может я и выгружал на диск...

function TfrmPrintDocument.CallWord: Boolean;
var mstr: TMemoryStream;  WrdDoc, WrdApp, tmpApp: OLEVariant;
   SourceFileName, SaveFileName: String;
   i: Integer;
begin
 Result := false;
 try
   tmpApp := GetActiveOleObject("Word.Application");
   if tmpApp.Documents.Count > 0 then tmpApp.Documents.Close(True);
   tmpApp := Unassigned;
 except
   //При запуске из под среды Delphi будет выдавать закономерную ошибку, если Word не запущен.
   //Не обращать внимания!
 end;

 try
   mstr := TMemoryStream.Create;
   sdqTemplatesTEM_DATA.SaveToStream(mstr);
   mstr.Seek(0, soFromBeginning);

   OleContainer1.LoadFromStream(mstr);
   OleContainer1.DoVerb(ovPrimary);
   WrdDoc := OleContainer1.OleObject;
   WrdApp := WrdDoc.Application;

   case sdqTemplatesTEM_TYPE.AsInteger of
     1: SourceFileName := frmMain.ContractSourceFile;
     2: SourceFileName := frmMain.PoliceSourceFile;
     3: SourceFileName := frmMain.PaymentSourceFile;
   end;

   If WrdApp.ActiveDocument.MailMerge.MainDocumentType = wdNotAMergeDocument
     then  EFileIsNotMailMerge.Create(sFileNotMerge);
   WrdApp.ActiveDocument.MailMerge.OpenDataSource(SourceFileName, wdOpenFormatRTF);
   if WrdApp.ActiveDocument.MailMerge.State = wdMainAndDataSource
      then WrdApp.ActiveDocument.MailMerge.Execute;

   SaveFileName := ExtractFilePath(Application.ExeName) + "TempDoc.doc";
   WrdApp.ActiveDocument.SaveAs(SaveFileName);

   Result := true;
 finally
   OleContainer1.DestroyObject;
   FreeAndNil(mstr);
 end;
end;


 
Shade   (2004-06-04 15:43) [3]

2 Курдль
Спасибо за ответ. Этот способ классный, если использовать олеконтейнер и в нём отображать. Мне к сожелению нельзя его использовать. Я должен запустить ворд, достать файл из базы и поместить туда...


 
Hooch ©   (2004-06-04 15:44) [4]

сохраняй файл на диск и открывай его, дешево и сердито


 
Shade   (2004-06-04 15:46) [5]

2 Hooch
Это самый простой способ, но использовать мне его ни в коем случае нельзя.


 
Hooch ©   (2004-06-04 15:46) [6]

почему ?


 
Shade   (2004-06-04 15:54) [7]

2 Hooch

Ну во-первых это некрасиво, использовать временные файлы, а во-вторых надо соблюдать элементарную безопасность. В дальнейшем я их буду передавать через модем, шифруя на одном конце, и расшифровывая на другом, но это потом. Сейчас же меня интересует именно эта задача.


 
NAlexey ©   (2004-06-04 17:05) [8]


procedure TForm1.Button1Click(Sender: TObject);
var
 MsWord: Variant;
 BlobStream: TADOBlobStream;
 BufStr: PChar;
 Value: string;
begin
 MsWord := CreateOleObject("Word.Basic");
 with TADOQuery.Create(nil) do
 try
   Connection := ADOConnection1;
   SQL.Text := "select * from Table1";
   Active := True;
   if IsEmpty then
     Exit;
   MSWord.AppShow;
   MSWord.FileNew;
   First;
   while not EOF do
   begin
     BlobStream := TADOBlobStream.Create(TBlobField(Fields[1]), bmRead);
     try
       BufStr := StrAlloc(BlobStream.Size - BlobStream.Position);
       BlobStream.ReadBuffer(BufStr^, BlobStream.Size - BlobStream.Position);
       MSWord.Insert(string(BufStr));
       StrDispose(BufStr);
     finally
       BlobStream.Free;
     end;
     Next;
   end;
 finally
   Free;
 end;
end;


 
Shade   (2004-06-04 17:58) [9]

2 NAlexey
Через буфер ? Хорошая идея. Спассибо. Щас буду пытаться.


 
Shade   (2004-06-04 20:46) [10]

2 NAlexey
Всё сделал как у тебя - не работает. Если быть точнее, то оно в ворд вставляет зюзюки, причём зюзюк этих всего 8 байт. Я проверял, проблем с блобами точно нет, тоесть после выполнения например BlobStream.savetofile("d:\aa.doc"); я спокойно в ворде открываю этот сохранённый из базы файл. Что это может быть за глюк ?


 
Курдль   (2004-06-04 21:51) [11]


> Через буфер ? Хорошая идея. Спассибо. Щас буду пытаться.

Не получится :(
Т.е. получится в лучшем случае передать текст.
Я пробовал с Ёкселем. Копирование региона сопровождается заполнением более, чем 30 форматов буффера обмена. Т.е. требуется распределять не одну область, а 30.


 
Shade   (2004-06-04 22:24) [12]

2 Курдль
Да, я в этом уже убедился. :)))

Какие ещё идеи будут ?


 
Курдль   (2004-06-04 22:32) [13]

Еще рюмку текилы и идеи так и посыпются! :)
Ну, например, создать драйвер виртуального диска и писать секретный файл в него! :) Изучить формат ворда и сэмулировать его работу в своем приложении.

Слушай, а почему нельзя через ОЛЕ-контейнер? Ну спрятать его, на крайняк - шоб не видно было!


 
Ломброзо ©   (2004-06-04 22:47) [14]

Рискну предложить вот что: в WebBrowser можно загрузить HTML из потока, примерно так:

procedure TFrmWeekly.LoadWebBrowserFromStream(pWebBrowser: IWebBrowser;
 pStream: IStream);
var
 hr: HRESULT;
 pHtmlDoc: IDispatch;
 pPersistStreamInit: IPersistStreamInit;
begin
 pHTMLDoc := pWebBrowser.Document;
 pPersistStreamInit := pHTMLDoc as IPersistStreamInit;
 pPersistStreamInit.InitNew();
 pPersistStreamInit.Load( pStream );
 pPersistStreamInit := nil;
end;

если очень повезёт, MS соблюдает единообразие и удастся получить IPersistStreamInit и для Word.Document, тогда дело проще пареной репы: TBlobField.SaveToStream в TOleStream, а затем загрузить в Word.Document из IStream, которым обёрнут TOleStream. Попробуйте сами, у меня к сожалению времени нету.


 
Shade   (2004-06-04 23:08) [15]

2 Курдль
Драйвер виртуального диска, во сказанул. :))) Оле-контейнер - это я напоследок оставил, если уж совсем ничего не получится.

2 Ломброзо
Интересная идея, но попробовать я её смогу только завтра. О результатах непременно доложу здесь.


 
Курдль   (2004-06-04 23:19) [16]


> Драйвер виртуального диска, во сказанул.

А чё? Я когда-то делал! Надо было какую-то секретную прогу в виде RAM держать на "втыкаемом модуле".
MASM -> 1000 строк кода -> 500 байт исполняемого кода и вперед! :)


 
Ломброзо ©   (2004-06-04 23:22) [17]

Посидел 5 минуток. IPersistStreamInit Word.Document не поддерживает, но IPersistStorage - да. См. MSDN на предмет IStorage, StgCreateDocFile и т.п. Сдаётся мне, без создания временного файла не обойтись. Другое дело, что создавать их можно стандартными средствами COM, блокировать их в момент работы с ними флагом STGM_SHARE_DENY_NONE (см.StgCreateDocFile) и надёжно уничтожать после пересылки.


 
Курдль   (2004-06-04 23:34) [18]


> Сдаётся мне, без создания временного файла не обойтись.

Я в [2] привел код, который давно успешно работает!
Если выбросить WrdApp.ActiveDocument.SaveAs(SaveFileName); - то он ничего писать и не будет.
Shade! Однако, мне не понятно, зачем вообще нужен Ворд?
Тебе просто файл надо передать?



Страницы: 1 вся ветка

Текущий архив: 2004.07.04;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.024 c
14-1087051685
vajo
2004-06-12 18:48
2004.07.04
Экзамен по Windows XP


14-1087451954
arbin
2004-06-17 09:59
2004.07.04
Россия-Португалия - 0:2


1-1087471661
Top100
2004-06-17 15:27
2004.07.04
Закрытие MDIChilde окна


4-1085243332
Master Paleva
2004-05-22 20:28
2004.07.04
Как переставить системное время


6-1083668390
Checist [root]
2004-05-04 14:59
2004.07.04
Как вытащить Url-адресс из файла типа Ярлык Интернета?