Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];

Вниз

Содержимое 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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.03 c
3-1086873031
Sirruf
2004-06-10 17:10
2004.07.04
DBSumList


1-1087313747
SPArk
2004-06-15 19:35
2004.07.04
Эмуляция нажатий кнопки мыши


1-1087198507
Yakudza
2004-06-14 11:35
2004.07.04
Ошибка при закрытии программы


3-1086792518
alex_pv
2004-06-09 18:48
2004.07.04
Помогите с документацией


14-1087046409
juiceman
2004-06-12 17:20
2004.07.04
что такое...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский