Имя: Пароль:
1C
 
Формирование печатной формы в Ворд
,
0 K1RSAN
 
22.10.18
08:19
Не могу понять небольшой момент. Внешняя печатная форма (зарегистрирована как обычная внешняя печатная форма с макетом), НО вместо документа типа "табличный документ" формирую документ Word через процедуру
ОбъектВорд = Новый COMОбъект("Word.Application");

И там его заполняю, использую закладки для вставки параметров. Документ создается и корректно открывается, НО программа после этого пытается сформировать так же обычную печатную форму, что приводит либо к появлению пустой печатной формы (если создаю пустую), либо пишет ошибку, дескать для такого макета не был создан печатный документ. Как правильно организовать вывод внешней печатной формы, чтобы не появлялась эта ошибка при каждом формировании формы?
1 K1RSAN
 
22.10.18
08:20
Платформа 8.3, код

Попытка
            ОбъектВорд = Новый COMОбъект("Word.Application");
        Исключение
            Сообщить("Ошибка при запуске Microsoft Word: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
            Возврат Неопределено;
        КонецПопытки;
        
        Запрос = Новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ
            |    РеализацияТоваровУслуг.Ссылка КАК Ссылка,
            |    РеализацияТоваровУслуг.Номер КАК НомерЗаказа,
            |    РеализацияТоваровУслуг.Дата КАК Дата,
            |    РеализацияТоваровУслуг.Товары.(
            |        Номенклатура КАК Номенклатура,
            |        Количество КАК Количество,
            |        Цена КАК Цена,
            |        Сумма КАК Сумма
            |    ) КАК Товары,
            |    РеализацияТоваровУслуг.ДоговорКонтрагента КАК ДоговорКонтрагента,
            |    РеализацияТоваровУслуг.Контрагент КАК Контрагент,
            |    РеализацияТоваровУслуг.СуммаДокумента КАК СуммаДокумента,
            |    РеализацияТоваровУслуг.ДоговорКонтрагента.НомерДоговора КАК НомерДоговора,
            |    РеализацияТоваровУслуг.ДоговорКонтрагента.ДатаДоговора КАК ДатаДоговора,
            |    КонтактныеЛица.Представление КАК Представление
            |ИЗ
            |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
            |        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.КонтактныеЛица КАК КонтактныеЛица
            |        ПО РеализацияТоваровУслуг.Контрагент = КонтактныеЛица.ОбъектВладелец
            |ГДЕ
            |    РеализацияТоваровУслуг.Ссылка = &Ссылка
            |    И КонтактныеЛица.Роль = &Роль";                          
            Запрос.Параметры.Вставить("Роль", Справочники.РолиКонтактныхЛиц.НайтиПоНаименованию("Директор"));
            Запрос.Параметры.Вставить("Ссылка", ТекущийДокумент.Ссылка);

        Выборка = Запрос.Выполнить().Выбрать();
        Выборка.Следующий();
            
        СсылкаМакет = ПолучитьМакет("Макет");
        Word = СсылкаМакет.Получить();

        СсылкаМакет = Word.Application.Documents(1);
        СсылкаМакет.Activate();

        Word.Bookmarks("Контрагент").Select();
        Word.Application.Selection.TypeText(Строка(Выборка.Контрагент));
                
        Word.Bookmarks("ДатаДокумента").Select();
        Word.Application.Selection.TypeText(Формат(Выборка.ДатаДоговора,"ДЛФ=DD"));
        
        Word.Bookmarks("НомерПоставки").Select();
        Word.Application.Selection.TypeText("ВставьтеНомерПоставки");
        
        Word.Bookmarks("ИмяДиректора").Select();
        Word.Application.Selection.TypeText(Строка(Выборка.Представление));
        
        Word.Bookmarks("Товар").Select();
        ВыборкаТовары = Выборка.Товары.Выбрать();
        ТекстТовар = "";
        Пока ВыборкаТовары.Следующий() Цикл
            ТекстТовар = ТекстТовар + ВыборкаТовары.Номенклатура + " , ";                
        КонецЦикла;
        Изменение = 1;
        Пока Изменение > 0 Цикл
            Изменение = 0;
            ТекстНовый = СтрЗаменить(ТекстТовар, "ая ", "ую ");
            ТекстНовый = СтрЗаменить(ТекстНовый, "а ", "у ");
            ТекстНовый = СтрЗаменить(ТекстНовый, "я ", "ю ");
            Если ТекстНовый <> ТекстТовар Тогда
                Изменение = 1;
            КонецЕсли;
            ТекстТовар = ТекстНовый;    
        КонецЦикла;
        Word.Application.Selection.TypeText(ТекстТовар);
        СсылкаМакет.Application.Visible = Истина;
2 Cool_Profi
 
22.10.18
09:04
Ошибка неформирования появляется, если ты что-то левое из функции отдаёшь
3 K1RSAN
 
22.10.18
09:23
(2) Ну я просто взял старую обработку получения внешней печатной формы, и сделал вставил свою процедуру туда. Просто в первый раз решил реализовать именно через договор, потому не знаю, что делаю не так.

Функция СведенияОВнешнейОбработке() Экспорт
    
    ПараметрыРегистрации = Новый Структура;
    МассивНазначений = Новый Массив;
    МассивНазначений.Добавить("Документ.РеализацияТоваровУслуг");
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.Наименование = НСтр("ru = 'Договор'");    
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    ПараметрыРегистрации.Информация = НСтр("ru = 'Договор'");
    ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
    
    ТаблицаКоманд = ПолучитьТаблицуКоманд();
    ДобавитьКоманду(ТаблицаКоманд, "Договор", "Договор", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
    ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
    
    Возврат ПараметрыРегистрации;
    
КонецФункции

Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));//как будет выглядеть описание печ.формы для пользователя
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка")); //имя макета печ.формы
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка")); //ВызовСерверногоМетода
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции

Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")

НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;

КонецПроцедуры

Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
        
    СформироватьТабДокументДоговорВорд(МассивОбъектов, ОбъектыПечати, "Договор");
    КоллекцияПечатныхФорм.Очистить();
            
КонецПроцедуры // Печать()
4 gantonio
 
22.10.18
09:26
хотя вообще не в курсе, что там , но я бы
посмотрел параметр
ДобавитьКоманду(ТаблицаКоманд, "Договор", "Договор", "ВызовСерверногоМетода", Истина, "ПечатьMXL");
5 K1RSAN
 
22.10.18
09:31
(4) Ну этот момент тупо из всяких "гайдов" брал по созданию внешних печатных форм
6 gantonio
 
22.10.18
09:35
ну, так у тебя создается вордовый объект из макеты и ты его видишь, а вот эта команда (скорее всего !) какую то еще печать запускает.
7 K1RSAN
 
22.10.18
10:06
(6) Просто из этой процедуры типовой код ожидает получить документ типа "ТабличныйДокумент", а если не получает - то выдает сообщение о том, что печатная форма не было сформирована. Вот и не могу понять, как тогда привязать форму к конфигурации.
8 dk
 
22.10.18
10:44
как то ты сложно с букмарками общаешься

    Попытка
        Скрипт=СоздатьОбъект("MSScriptControl.ScriptControl");
        Скрипт.language="javascript";
        Ворд = Скрипт.Eval("new ActiveXObject('Word.Application.14')");
    Исключение
        Попытка
            Ворд = СоздатьОбъект("Word.Application.15");
        Исключение
            Сообщить("Не удалось открыть Word 2010");
            Возврат;
        КонецПопытки;
    КонецПопытки;    
    
    Ворд.DisplayAlerts = ексНет;

    //[*] ((( dk 16/03/2018
    //Ворд.Visible = ексДа;
    Ворд.Visible = ексНет;
    //[*] dk )))
    
    Док = Ворд.Documents.Add(ФайлШаблона);
    
    // Заполним пустышками
    Попытка
        Док.Bookmarks("НомерДоговора").Range.Text                = НомерДоговора;//"__________";
    Исключение
    КонецПопытки;
    Попытка
        Док.Bookmarks("НомерДоговора1").Range.Text                = НомерДоговора;//"__________";
    Исключение
    КонецПопытки;
    Попытка
        Док.Bookmarks("НомерДоговора2").Range.Text                = НомерДоговора;//"__________";
    Исключение
    КонецПопытки;    
    Попытка
        Док.Bookmarks("НомерДоговора3").Range.Text                = НомерДоговора;//"__________";
    Исключение
    КонецПопытки;
    
    Зн = СокрЛП(Элем.Емэйл);
    Если ПустоеЗначение(Зн) = 0 Тогда
        Попытка
            Док.Bookmarks("ЭлПочта").Range.Text                    = Зн;
        Исключение
        КонецПопытки;
        Попытка
            Док.Bookmarks("ЭлПочта1").Range.Text                = Зн;
        Исключение
        КонецПопытки;
        Попытка
            Док.Bookmarks("ЭлПочта2").Range.Text                = Зн;
        Исключение
        КонецПопытки;
    Иначе
        Попытка
            Док.Bookmarks("ЭлПочта").Range.Text                    = "__________________________";
        Исключение
        КонецПопытки;
        Попытка
            Док.Bookmarks("ЭлПочта1").Range.Text                = "__________________________";
        Исключение
        КонецПопытки;
        Попытка
            Док.Bookmarks("ЭлПочта2").Range.Text                = "__________________________";
        Исключение
        КонецПопытки;
    КонецЕсли;
    
    Зн = СокрЛП(Элем.ПолнНаименование);
    Если ПустоеЗначение(Зн) = 0 Тогда
        Попытка
            Док.Bookmarks("ПокНаименование").Range.Text            = Зн;
        Исключение
        КонецПопытки;
    КонецЕсли;
9 Alexandr_U1982
 
22.10.18
10:47
(7)Попробуй вместо "ВызовСерверногоМетода" использовать "ВызовКлиентскогоМетода".
В этом случае тебе нужно будет в обработке создать форму, и в нее поместить процедуру Печать().

&НаКлиенте
Процедура Печать(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
    // Реализация логики команды.
КонецПроцедуры

И уже в этой процедуре формировать документ Word.
10 Alexandr_U1982
 
22.10.18
10:54
(7)При формировании печатной формы с помощью серверного метода БСП ожидает, что будет сформирован табличный документ.
Т.к. ты не создаешь табличного документа, то БСП ругается на ошибку.
Чтобы БСП не ругалась нужно использовать вызов клиентского метода.
11 K1RSAN
 
22.10.18
11:09
(9) Главное, чтобы это не привело к дополнительным лишним действиям клиентов.
12 K1RSAN
 
22.10.18
11:14
(11)+ блин, это же надо будет тогда передавать документ в новую форму, ведь обработка не знает, из какого документа ее вызвали
13 K1RSAN
 
22.10.18
11:16
(8) То есть ваш вариант легче моего?
14 dk
 
22.10.18
11:18
Selection - зло
15 Alexandr_U1982
 
22.10.18
11:20
(12) В параметре ОбъектыНазначенияМассив передается массив ссылок на документы, из которых была вызвана печатная форма.
16 Alexandr_U1982
 
22.10.18
11:22
+(15) Запрос нужно будет выполнять в серверной функции, результат выполнения запроса на клиент можно передать через массив структуру.
17 K1RSAN
 
22.10.18
11:24
(16) Ну это понятно, просто считай половину обработки переделывать не охота
18 K1RSAN
 
22.10.18
11:25
(14) В первый раз работаю с этим объектом)
19 Alexandr_U1982
 
22.10.18
11:26
По поводу заполнения самого документа Word:
В БСП содержится общий модуль "УправлениеПечатьюКлиент", в котором уже есть готовые процедуры/функции для заполнения офисного документа.

#Область РаботаСМакетамиОфисныхДокументов

////////////////////////////////////////////////////////////////////////////////
// Работа с макетами офисных документов.
//    Секция содержит интерфейсные функции (API), используемые при создании
//    печатных форм основанных на офисных документах. На данный момент поддерживается
//    два офисных пакета MS Office (шаблоны MS Word) и Open Office (шаблоны OO Writer).
//
////////////////////////////////////////////////////////////////////////////////
//    Типы используемых данных (определяется конкретными реализациями).
//    СсылкаПечатнаяФорма    - ссылка на печатную форму.
//    СсылкаМакет            - ссылка на макет.
//    Область                - ссылка на область в печатной форме или макете (структура)
//                        доопределяется в интерфейсном модуле служебной информацией
//                        об области.
//    ОписаниеОбласти            - описание области макета (см. ниже).
//    ДанныеЗаполнения        - либо структура, либо массив структур (для случая
//                            списков и таблиц.
////////////////////////////////////////////////////////////////////////////////
//    ОписаниеОбласти - структура, описывающая подготовленные пользователем области макета
//    ключ ИмяОбласти - имя области
//    ключ ТипТипОбласти -     ВерхнийКолонтитул.
//                            НижнийКолонтитул
//                            Общая
//                            СтрокаТаблицы
//                            Список
//
20 Alexandr_U1982
 
22.10.18
11:27
(17) Ну раз "не охота", то это уже другое дело))
21 K1RSAN
 
22.10.18
11:29
(20) Просто придется потратить больше времени, чем уже ушло) При этом такое количество часов будет нечем оправдать)
22 K1RSAN
 
22.10.18
11:41
(20) Чет не работает ваш вариант с вызовом клиентского метода. Не открывается форма и ничего не вызывается
23 Alexandr_U1982
 
22.10.18
12:03
(22)
(22) Пример.
В модуле объекта

Функция СведенияОВнешнейОбработке() Экспорт

    ПараметрыРегистрации                 = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    ПараметрыРегистрации.Вид             = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия          = "1";
    ПараметрыРегистрации.Информация      = "Печатная форма трудового договора (СТГ)";
    
    ПараметрыРегистрации.Назначение.Добавить("Документ.ПриемНаРаботу");
    ПараметрыРегистрации.Назначение.Добавить("Документ.ПриемНаРаботуСписком");

    НоваяКоманда               = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = НСтр("ru = 'Трудовой договор (СТГ)'");
    НоваяКоманда.Идентификатор = "ПФ_DOC_ТрудовойДоговор";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
    НоваяКоманда.Модификатор   = "ПечатьDOC";
    
    Возврат ПараметрыРегистрации;
    
КонецФункции


В модуле формы:

&НаКлиенте
Процедура Печать(ИдентификаторКоманды, МассивОбъектов) Экспорт
    
    Попытка
        Word = Новый COMОбъект("Word.Application");
    Исключение
        ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
        Возврат;
    КонецПопытки;
    
    Макет              = ПолучитьМакетСервер();
    ИмяВременногоФайла = КаталогВременныхФайлов() + "Трудовой договор.docx";
    Макет.Записать(ИмяВременногоФайла);
    
    ДанныеДляПечати = ПолучитьДанныеДляПечати(МассивОбъектов);
    Для Каждого СтрокаДанных Из ДанныеДляПечати Цикл
        
        Попытка

            ДокументWord  = Word.Documents.Add(ИмяВременногоФайла);
            Область       = ДокументWord.Application.Selection;
            wdReplaceNone = 00000000;
            wdReplaceOne  = 00000001;
            wdReplaceAll  = 00000002;
            
            Контент = ДокументWord.Content;
            Контент.Find.ClearFormatting();
            Контент.Find.Replacement.ClearFormatting();
            Контент.Find.Forward           = Истина;
            Контент.Find.Format            = Ложь;
            Контент.Find.MatchCase         = Ложь;
            Контент.Find.MatchWholeWord    = Ложь;
            Контент.Find.MatchWildcards    = Ложь;
            Контент.Find.MatchSoundsLike   = Ложь;
            Контент.Find.MatchAllWordForms = Ложь;
            
            Для Каждого Элемент Из СтрокаДанных Цикл
                
                Если Элемент.Ключ = "ТрудовойДоговор_ОбстоятельстваСрочностиДоговора" Или
                     Элемент.Ключ = "ТрудовойДоговор_УсловияОкончанияДоговора"        Тогда
                    Продолжить;
                КонецЕсли;
                
                Контент.Find.Text             = "<"+Элемент.Ключ+">";
                Контент.Find.Replacement.Text = Элемент.Значение;
                Контент.Find.Execute(,,,,,,,,,, wdReplaceAll);
                
            КонецЦикла;
            
            Контент.Find.Text             = "";
            Контент.Find.Replacement.Text = "";
            Контент.Find.ClearFormatting();
            Контент.Find.Replacement.ClearFormatting();
            ДокументWord.Application.Selection.GoTo(3,, 1, "").Select();
            
            Word.Visible = Истина;
            Word.Activate();
            
        Исключение
            ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
        КонецПопытки;
            
    КонецЦикла;

КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьДанныеДляПечати(МассивОбъектов)
    // Здесь извелкаются данные из базы
КонецФункции

&НаСервере
Функция ПолучитьМакетСервер()
    Возврат РеквизитФормыВЗначение("Объект").ПолучитьМакет("ПФ_DOC_ТрудовойДоговор");
КонецФункции
24 Alexandr_U1982
 
22.10.18
12:04
(22)Рассказывайте как делали. Какая форма не открывается?
И вообще, какая у вас конфигурация?
25 K1RSAN
 
22.10.18
12:17
(24) ПараметрыРегистрации = Новый Структура;
    МассивНазначений = Новый Массив;
    МассивНазначений.Добавить("Документ.РеализацияТоваровУслуг");
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.Наименование = НСтр("ru = 'Договор'");    
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    ПараметрыРегистрации.Информация = НСтр("ru = 'Договор'");
    ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
    
    НоваяКоманда               = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = НСтр("ru = 'Договор'");
    НоваяКоманда.Идентификатор = "Договор";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();
    НоваяКоманда.Модификатор   = "ПечатьDOC";
Возврат ПараметрыРегистрации;

Но при вызове требует процедуру Печать именно в модуле объекта, а не в модуле формы
26 Alexandr_U1982
 
22.10.18
12:22
(25) Хм... Либо у вас БСП старая (2.2.2.1), либо особенности работы в толстом клиенте...
А какая конфигурация?
27 K1RSAN
 
22.10.18
12:23
(26) Бухгалтерия для Казахстана 3.0
Версия БСП вроде как указана 2.2.5.31
28 Alexandr_U1982
 
22.10.18
12:27
(27) Мой пример был из ЗУП 3.1.7, там БСП вроде как 2.4.6.

Может быть вам помогут статьи с ИТС (подсистемы "Дополнительные отчеты и обработки" и "Печать")
https://its.1c.ru/db/bsp246doc#content:31:hdoc
https://its.1c.ru/db/bsp246doc/content/52/hdoc
29 K1RSAN
 
22.10.18
12:27
(28) Спасибо, посмотрю
30 K1RSAN
 
23.10.18
11:50
(28) Занятно, ничего не менял, сегодня запускаю - идет как надо код.
Глупец, лишенный способности посмеяться над собой вместе с другими, не сможет долго выносить программирование. Фредерик Брукс-младший