Форум: "Базы";
Текущий архив: 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