![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
||||
|
||||
|
Честно говоря, уже даже неудобно перед форумчанами за каждодневные темы. Но, я надеюсь, что Вы последуете мудрейшей из философий 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. |