|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
||||
|
||||
Сохранение документа MS Word
Честно говоря, уже даже неудобно перед форумчанами за каждодневные темы. Но, я надеюсь, что Вы последуете мудрейшей из философий XXI века: "Понять и простить"...
Проблема: Никак не получается сохранить документ MS Word из Delphi. Уже перепробовал кучу разных вариантов, все время появляются какие-нибудь ошибки (то недостаточное количество параметров, то несоответствие типов). Очень нуждаюсь в помощи, ибо теряю надежду. Вот крайняя версия моих попыток: Код:
var Addr1 : OleVariant; ... WA1.Visible := True; SaveDialog1.DefaultExt := 'doc'; SaveDialog1.Filter := '*.doc|*.doc'; SaveDialog1.FileName := 'Технический_отчет_'+FormatDateTime('ddmmyyyy_hhmm', Now)+'.doc'; Addr1 := SaveDialog1.FileName; WA1.ActiveDocument.SaveAs(Addr1); Получаемая ошибка (для строки WA1.ActiveDocument.SaveAs(Addr1)): [Error] Unit8.pas(416): Not enough actual parameters |
#2
|
||||
|
||||
И, раз уж пошла такая свистопляска, привожу код целиком:
Код:
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Buttons, StdCtrls, ComCtrls, WordXP, OleServer, FileCtrl, ComObj; ... procedure TForm8.Button1Click(Sender: TObject); const // массивные маркеры marker: array[1..19] of string[25] = ('%sotrudnik%', // Маркер выбора сотрудника '%date_in%', // Маркер даты начала командировки '%date_out%', // Маркер даты окончания командировки '%archive_nomer%', // Маркер номера служебной записки о сдаче в архив '%station%', // Маркер трансгаза '%msku%', // Маркер шифра системы '%rez_pnr%', // Маркер блока "Результат ПНР" '%akty%', // Маркер блока "Акты по результатам ПНР" '%ostalos%', // Маркер блока "Оставшиеся работы" '%zamechaniya_pr%', // Маркер блока "Замечания к качеству производства" '%zamechaniya_pr_dok%', // Маркер блока "Основания по замечаниям к качеству производства" '%oborudovanie%', // Маркер блока "Оборудование, необходимое для завершения ПНР" '%oborudovanie_doc%', // Маркер блока "Основания для выписывания оборудования" '%zamechaniya_doc%', // Маркер блока "Замечания к документации" '%zamechaniya_doc_dok%', // Маркер блока "Основания для замечаний к документации" '%zamechaniya_vyav%', // Маркер блока "Выявленные и устраненные замечания" '%zamechaniya_vyav_dok%', // Маркер блока "Основания по выявленным и устраненным замечаниям" '%po_d50_korrekt%', // Маркер блока "Необходимость корректировки ПО и Д50" '%po_d50_korrekt_dok%'); // Маркер блока "Основания для необходимости корректировки ПО и Д50" var FTrue, Ffalse, Template, NewTemplate, ItemIndex, ItemIndex1, T, R, D, DD, Replese_T, Find_T: OleVariant; Tbl, L, col: OleVariant; j: integer; transgaz : String; sau : String; Addr1, Addr2 : OleVariant; begin // Запрет выполнения операции, если не загружен info-файл if (trim(Edit1.Text) = '') Then begin if MessageBox(Handle,PChar('Не указан путь к info-файлу!'#13#10'Операция не может быть выполнена!'),PChar('Недопустимое значение полей'),MB_ICONERROR+MB_OK)= mrOk then exit; end; // Запрет выполнения операции, если не указан каталог с документами if (trim(Edit3.Text) = '') Then begin if MessageBox(Handle,PChar('Не указан каталог с документами!'#13#10'Операция не может быть выполнена!'),PChar('Недопустимое значение полей'),MB_ICONERROR+MB_OK)= mrOk then exit; end; Xlsdoc := CreateOleObject('Excel.Application'); Xlsdoc.Workbooks.Open(Edit1.Text); Xlsdoc.Visible := False; transgaz := Xlsdoc.Range['B3']; sau := Xlsdoc.Range['B2']; Xlsdoc.Workbooks.Close; Xlsdoc.Quit; Xlsdoc:=UnAssigned; Memo1.Clear; Memo1.Lines.Add('Соединение с шаблоном технического отчета...'); Application.ProcessMessages; try WA1.Connect; WA1.Visible := False; Template := EmptyParam; NewTemplate := False; FTrue := true; Ffalse := false; except ShowMessage('Не удалось соедениться с шаблоном технического отчета!'); Memo1.Lines.Add('Не удалось соедениться с шаблоном технического отчета!' ); Application.ProcessMessages; exit; end; Memo1.Lines.Add('Создаем технический отчет...'); Application.ProcessMessages; // Добавляем документ из имеющегося со статусом несохраненного нового документа try T := ExtractFilePath(Application.ExeName)+'\Shablon\Tehotchet.dot'; ItemIndex := WA1.Documents.Add(T, NewTemplate, NewTemplate, Template); WD1.ConnectTo(WA1.Documents.Item(ItemIndex)); except Memo1.Lines.Add('Не удалось соедениться с шаблоном технического отчета (Tehotchet.dot)! Проверьте расположение файла!' ); Application.ProcessMessages; ShowMessage('Не удалось соедениться с шаблоном технического отчета (Tehotchet.dot)! Проверьте расположение файла!'); WD1.Application.Selection.EndOf(Template, Template); WA1.Application.WindowState := wdWindowStateMaximize; WA1.Application.ScreenUpdating := true; WA1.Application.ScreenRefresh; WA1.Visible := true; WA1.Disconnect; WD1.Disconnect; exit; end; try // Количество таблиц в документе и количество строк со столбцами col := WA1.ActiveDocument.Tables.Count; for j := 1 to col do begin Memo1.Lines.Add('Подключаемся к приложению MS Word...'+Inttostr(j)); Application.ProcessMessages; tbl := WA1.ActiveDocument.Tables.Item(j); // Присоеденяемся к таблице end; L := wdStory; // В начало документа WA1.Selection.HomeKey(L, EmptyParam); Memo1.Lines.Add('Заменяем маркеры на текст...' ); Application.ProcessMessages; Find_T := '%sotrudnik%'; // Текст, который меняем D := wdFindStop; // Найти один раз DD := wdReplaceAll; // Замена все Replese_T := ComboBox1.Text; // Заменить на WA1.Selection.Find.Execute(Find_T, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, D, EmptyParam, Replese_T, DD, EmptyParam, EmptyParam, EmptyParam, EmptyParam); Find_T := '%date_in%'; // Текст, который меняем Replese_T := DateToStr(DateTimePicker1.Date); // Заменить на ...... WA1.Selection.Find.Execute(Find_T, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, D, EmptyParam, Replese_T, DD, EmptyParam, EmptyParam, EmptyParam, EmptyParam); WD1.Application.Selection.EndOf(Template, Template); except WA1.Visible := true; WA1.Disconnect; WD1.Disconnect; Memo1.Lines.Add('Ошибка!' ); Application.ProcessMessages; exit; end; Memo1.Lines.Add('Экспорт завершен.' ); Application.ProcessMessages; WA1.Visible := True; SaveDialog1.DefaultExt := 'doc'; SaveDialog1.Filter := '*.doc|*.doc'; SaveDialog1.FileName := 'Технический_отчет_'+FormatDateTime('ddmmyyyy_hhmm', Now)+'.doc'; Addr1 := SaveDialog1.FileName; WA1.ActiveDocument.SaveAs(Addr1); //WD1.SaveAs(ExtractFilePath(Application.ExeName)+'Технический_отчет_'+FormatDateTime('ddmmyyyy_hhmm', Now)+'.doc'); WD1.Disconnect; WA1.Disconnect; |
#3
|
||||
|
||||
Готов к любой конструктивной критике и открыт для советов и предложений!
|
#4
|
||||
|
||||
Цитата:
Код:
var WordApp: Variant; ... WordApp.FileSaveAs(Name:= 'c:\temp.doc', Format:= 11); Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (02.03.2017)
|
#5
|
||||
|
||||
Я получаю: Invalid variant operation
|
#6
|
||||
|
||||
Вопрос ведь про сохранение был, вот попробовал по примеру из базы знаний так
Код:
uses ComObj; ... WordApp := CreateOLEObject('Word.Application'); if not VarIsEmpty(WordApp) then begin WordApp.Text:= 'ddddd'; WordApp.FileSaveAs(Name := 'c:\temp.doc', Format := {11 от балды чтоб был 0} 0 ); WordApp.AppClose; WordApp := Unassigned; end; Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (02.03.2017)
|
#7
|
||||
|
||||
Да, если делать так, то все отлично сохраняется. Но у меня немного по-другому происходит создание документа и работа с ним. За основу взял код "Экспорт текста в Word из Delphi в текстовый шаблон Word, с элементом построения таблиц, используя маркеры" с VR-Online (http://www.vr-online.ru/forum/ekspor...a-tablic-ispol) и, затем, модифицировал его под свои нужды.
Конечно же, если не будет других вариантов, то придется переделывать код под создание WordApp через CreateOLEObject. |
#8
|
||||
|
||||
А без .Documents.Add пустышка сохраняться будет? Может что в шаблоне не так
Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (02.03.2017)
|
#9
|
||||
|
||||
Цитата:
С шаблоном точно все в порядке. Если делаю: Код:
Memo1.Lines.Add('Экспорт завершен.' ); Application.ProcessMessages; WA1.Visible := True; WA1.ActiveDocument.Save; WD1.Disconnect; WA1.Disconnect; |
#10
|
||||
|
||||
Оффтоп: хорош пасибки так усердно тратить ) помощи от ентого меньше всёравно не станет
Вроде допетрил - спасибо за "кошечек" - пример в статье, параметры ведь у .SaveAs "заварены" как OleVariant, вот и нужно завести такую, имя положить в неё, а затем уж сохранять документ, у меня так заработало З.Ы. В смысле Код:
var fname: OleVariant; ... fname := ExtractFilePath(Application.ExeName)+ 'Технический_отчет_'+ FormatDateTime('ddmmyyyy_hhmm', Now)+'.doc'; WD1.SaveAs(fname); З.Ы.З.Ы. Ничего не понимаю, у вас оказывается так и есть, Addr1: OleVariant... Я не понял Вашего вопроса, но всё же Вам на него отвечу! Последний раз редактировалось Alegun, 02.03.2017 в 14:31. |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (02.03.2017)
|
#11
|
||||
|
||||
От "Спасибо" с меня не убудет, тем более что я не просто так их раздаю, а за дельные советы.
Когда я делаю через OleVariant, то получаю такую ошибку: Тьфу ты! Хотел написать про ошибку и понял какую ошибку сам совершил! Ларчик просто открывался! Я пытался сохранить через WordApplication, а все заработало как только я сохранился через WordDocument! Дурья моя башка! P.S. Вот! И спасибо оказалось кстати! Если бы не Ваш код, я бы не сразу обратил внимание! |
#12
|
||||
|
||||
Хотя все равно немного непонятно, почему конструкция:
Код:
WA1.ActiveDocument.SaveAs(Addr1); Код:
WD1.SaveAs(Addr1); |
#13
|
||||
|
||||
Да нет, и через WA1.ActiveDocument.SaveAs тоже работает, просто нужно было до одури пустышки туда подсовывать
Код:
WA1.ActiveDocument.SaveAs(Addr1, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam); Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
Этот пользователь сказал Спасибо Alegun за это полезное сообщение: | ||
ffpereverzev (02.03.2017)
|
#14
|
||||
|
||||
Полностью с Вами согласен. Спасибо большое за помощь!
Постараюсь пару дней Вас не беспокоить. |
#15
|
||||
|
||||
Цитата:
Судя по всему, не получится у меня сдержать слово. Проблема: записываю текст из RichEdit в файл *.doc. Если в RichEdit у меня были переносы (то есть были нажатия кнопки Enter), то в самом поле RichEdit перенос каретки осуществляется, а в файл текст записывается в одну строку да еще и с квадратиками какими-то. Код:
// Поиск маркера и определение текстового блока для замены WA1.Selection.Find.Execute(Find_T, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, EmptyParam, D, EmptyParam, Replese_T, DD, EmptyParam, EmptyParam, EmptyParam, EmptyParam); Find_T := '%rez_pnr%'; // Текст, который меняем Replese_T := RichEdit1.Text; // Заменить на А это крайняя попытка произвести что-то вразумительное для поиска решения данной проблемы: Код:
procedure TForm8.RichEdit1KeyPress(Sender: TObject; var Key: Char); begin If key=#13 then RichEdit1.Lines.Add(''); end; Я так понимаю, что единственный вариант что-либо придумать - это сделать какую-нибудь обработку по событию, но...шел 3 час поиска...безрезультатного поиска! Руки опускаются и надежда угасает. P.S. Попытка сохранить конечный файл не в формат *.doc, а в формат *.rtf положительного результата не принесла (была мысль, что раз RichEdit работает c форматом RTF, то в этом может быть корень зла, но нет. Фокус не удался) Последний раз редактировалось ffpereverzev, 03.03.2017 в 01:52. |