В конфигурации УТ 10.3 реализована пакетная печать документов с выбором руководителя. После выбора печатаются Торг 12 и Счет-Фактура. Последняя счет-фактура присоединена в виде внешней печатной формы. Задача - передать туда руководителя для подписи. Прошу помогите с идеями.
---
А в чем проблема? Сделать какой-нить параметр сеанса, да юзать его.
Некошерно, но быстро.
---
https://helpf.pro/faq/view/1307.html
---
Вот я так и сделал сначала. Но руководитель выбирается при каждой печати и приходится каждый раз перезаписывать дополнительные параметры в справочнике. А это не есть хорошо. Еще и на сети с десятком пользователей.
---
вас никто не заставляет переписывать дополнительные параметры в справочнике, достаточно пользоваться структурой в которой они хранятся в виде одного из параметров функции Печать()
---
С этого места поподробнее. Как вы предлагаете загнать структуру в ДополнительныеПараметры?
Там могут храниться только примитивные типы насколько я знаю.
---
Строка вполне себе примитивный тип.
---
Как вы предлагаете загнать структуру в ДополнительныеПараметры?
Она туда уже будет загнана на момент вызова функции Печать() модуля внешней обработки типовым кодом вызова доп. обработки
(8) Там могут храниться только примитивные типы насколько я знаю.
кто вам такое сказал? там может хранится все то же, что и в обычной структуре в качестве значения элемента.
---
Дополнительные параметры - это ХранилищеЗначения. Поместить туда можно все что угодно, но для того, чтобы прочитать оттуда значения, нужно записать элемент. Или я не прав?
---
нет, если там ничего не будет, то оно просто будет пустым, ничего не мешает заполнить его самостоятельно нужными данными.
---
Заполнить можно, при каждой печати они могут меняться. Что с этим делать?
---
Вы наверно не дочитали задачу. Есть обработка в которой выбирается реализация при отправке на печать выбирается руководитель для подписи. Печатается Торг12 и счет-фактура из документов. Т.к. Ут 10.3 снята с поддержки (если вы об этом не знали) обновления для новой счет-фактуры нет, и она прикрепляется в виде внешней печатной формы. Изменять конфигурацию из-за этого желания нет (в частности добавлять новые параметры сеанса). Могу переписать обработку и внешнюю печатную форму.
Т.е. не нужно постоянно измененное имя руководителя. Его можно изменить и в другом месте, а не в дополнительных параметрах. Нужно менять подписанта при каждой печати.
---
при отправке на печать выбирается руководитель для подписи.....
Нужно менять подписанта при каждой печати

Каким образом это делается сейчас в обработке печати, можете показать код?
---
ДополнительныеПараметры имеет произвольный тип данных. Типовой алгоритм вызова внешней обработки формирует структуру.

```1c
    Функция Печать() Экспорт

    ТабДок = Новый ТабличныйДокумент;

    //Ничто не мешает сделать так в другой форме обработки:
    Руководитель = ОткрытьМодальноФормуВыбораФизЛица();
    ДополнительныеПараметры.Вставить("Руководитель", Руководитель);

    .........
    КонецФункции
```
---
Да нет. Список выбора руководителя выводится до печати. И его (руководителя) надо передать во внешнюю форму счет-фактуры. Печатается также и Торг-12.
---
Это я понимаю, каким образом это у вас реализовано на данный момент в коде?

Так понимаю, что-то вроде:

```1c
    РуководительДляПодписи = ОткрытьМодальноФормуВыборавФизЛица();

    ДопОбработка = Справочники.ДополнительныеОбработки.Найти("НаименованиеОбработки");
    ОбработкаОбъект = ВнешниеОбработки.Подключить(ИмяВременногоФайла, ИмяРегистрацииОбработки);

    ВПФ = ВнешниеОбработки.ИмяРегистрацииОбработки.Создать();
    ВПФ.СсылкаНаОбъект = СсылкНаСчетФактура;
    ТабДок = ВПФ.Печать();
```
---
После того, как я сделал все через Дополнительные параметры. Понял, что перезаписывать при каждой печати элемент справочника ВнешниеОбработки - это не выход. И просто передаю руководителя через ХранилищеОбщихНастроек. Думаю - это оптимально.
Перед печатью внешней формы сохраняю руководителя в хранилище, при печати достаю, после печати удаляю.
---
зачем вообще тогда спрашиваете как сделать лучше?
делайте как умеете
---
Если бы мне здесь не посоветовали воспользоваться параметрами сеанса, я бы про это хранилище и не вспомнил бы. Так бы и оставил перезапись дополнительных параметров.
Может есть еще какие способы?
---
я вам уже битые стопицот сообщений пытаюсь донести мысль о том, что не нужно вообще ничего никуда записывать и потом еще стирать - все работает через ДополнительныеПараметры дополнительной обработки.

От вас хочу увидеть реализацию в коде получения нужного руководителя и формирования печатной формы нужного документа, чтобы показать каким образом можно использовать ДополнительныеПараметры, но так понимаю, ваша реализация кодом сильно секретная.
Не буду настаивать, ваш вариант с помощью хранилища настроек рабочий.
---
Нет ничего секретного. Хотите увидеть код с Дополнительными Параметрами - пожалуйста

```1c
    Руководители = Новый Структура;
    Руководители.Вставить("Руководитель", ВыбРуководитель);
    Руководители.Вставить("ГлавныйБухгалтер", ВыбРуководитель);
    СсылкаВнОбработки = Справочники.ВнешниеОбработки.НайтиПоНаименованию("Счет-фактура1096");
    ОбъектВнОбработки = СсылкаВнОбработки.ПолучитьОбъект();
    ОбъектВнОбработки.Принадлежность[0].ДополнительныеПараметрыОбработки = Руководители;
    ОбъектВнОбработки.Записать();
    ДеревоМакетовПечати = УниверсальныеМеханизмы.ПолучитьДеревоМакетовПечати(СсылкаНаДокумент, Неопределено);
    СтрокаКнопки = ДеревоМакетовПечати.Строки.Найти("Счет-фактура1096","Текст");
    Расшифровка = СтрокаКнопки.Расшифровка;
    Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
    ТабДокумент = УниверсальныеМеханизмы.НапечататьВнешнююФорму(СсылкаНаДокумент, Расшифровка);
    Если ТабДокумент <> Неопределено Тогда
    УниверсальныеМеханизмы.НапечататьДокумент(ТабДокумент);
    КонецЕсли;
    КонецЕсли;
    ОбъектВнОбработки.Принадлежность[0].ДополнительныеПараметрыОбработки = ";
    ОбъектВнОбработки.Записать();
```

Соответственно во внешней форме я сначала проверяю есть ли что в дополнительных параметрах

```1c
    Если Не ДополнительныеПараметры.Свойство("Руководитель") = Неопределено Тогда
    Макет.Параметры.Руководитель = ДополнительныеПараметры.Руководитель;
    КонецЕсли;
```

Вот такой код
---
А теперь следите за руками, как говорится:

```1c
    Руководители = Новый Структура;
    Руководители.Вставить("Руководитель", ВыбРуководитель);
    Руководители.Вставить("ГлавныйБухгалтер", ВыбРуководитель);

    ДеревоМакетовПечати = УниверсальныеМеханизмы.ПолучитьДеревоМакетовПечати(СсылкаНаДокумент, Неопределено);
    СтрокаКнопки = ДеревоМакетовПечати.Строки.Найти("Счет-фактура1096","Текст");
    Расшифровка = СтрокаКнопки.Расшифровка;

    Расшифровка.ДополнительныеПараметрыОбработки = Руководители;

    Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
    ТабДокумент = УниверсальныеМеханизмы.НапечататьВнешнююФорму(СсылкаНаДокумент, Расшифровка);
    Если ТабДокумент <> Неопределено Тогда
    УниверсальныеМеханизмы.НапечататьДокумент(ТабДокумент);
    КонецЕсли;
    КонецЕсли;
```

Просто я не уверен, что ДополнительныеПараметрыОбработки находятся "в корне" структуры Расшифровка.
---
Да наподобие. Только через УниверсальныеМеханизмы.НапечататьВнешнююФорму.
---
как именно вызывается метод? какие параметры используются?
---
Метод так и называется УниверсальныеМеханизмы.НапечататьВнешнююФорму.

```1c
    ДеревоМакетовПечати = УниверсальныеМеханизмы.ПолучитьДеревоМакетовПечати(СсылкаНаДокумент, Неопределено);
    СтрокаКнопки = ДеревоМакетовПечати.Строки.Найти("Счет-фактура1096","Текст");
    Расшифровка = СтрокаКнопки.Расшифровка;
    Если ТипЗнч(Расшифровка) = Тип("Структура") Тогда
    ТабДокумент = УниверсальныеМеханизмы.НапечататьВнешнююФорму(СсылкаНаДокумент, Расшифровка);
    Если ТабДокумент <> Неопределено Тогда
    УниверсальныеМеханизмы.НапечататьДокумент(ТабДокумент);
    КонецЕсли;
    КонецЕсли;
```
---
хорошо, разбираемся дальше.
Что внутри Расшифровка? Какие ключи и их значения есть у структуры?
---
Это стандартная структура дерева значений для выбранного макета. У вас что Ут 10 нет? Ладно. Вот вам стандартная функция из Ут 10

```1c
    Функция НапечататьВнешнююФорму(Ссылка, ИсточникМакета) Экспорт

    ДвоичныеДанные = ИсточникМакета.СсылкаНаВнешнююОбработку.Принадлежность[ИсточникМакета.НомерСтроки - 1].ХранилищеВнешнейОбработки.Получить();
    Если ДвоичныеДанные = Неопределено Тогда
    ДвоичныеДанные = ИсточникМакета.СсылкаНаВнешнююОбработку.ХранилищеВнешнейОбработки.Получить();
    КонецЕсли;
    ДополнительныеПараметры = ИсточникМакета.СсылкаНаВнешнююОбработку.Принадлежность[ИсточникМакета.НомерСтроки - 1].ДополнительныеПараметрыОбработки.Получить();

    Если ДвоичныеДанные = Неопределено Тогда
    Возврат Неопределено;
    КонецЕсли;

    ТабДокумент = Неопределено;

    ИмяФайла = ПолучитьИмяВременногоФайла("epf");
    Попытка
    ДвоичныеДанные.Записать(ИмяФайла);
    Обработка = ВнешниеОбработки.Создать(ИмяФайла);
    Обработка.СсылкаНаОбъект = Ссылка;

    // Передать внешней обработке дополнительные параметры
    Если ДополнительныеПараметры <> Неопределено Тогда
    // Если у внешней обработки есть реквизит для дополнительных параметров, присвоить ему значение
    Если НЕ Обработка.Метаданные().Реквизиты.Найти("ДополнительныеПараметры") = Неопределено Тогда
    Обработка.ДополнительныеПараметры = ДополнительныеПараметры;
    КонецЕсли;
    КонецЕсли;

    ТабДокумент = Обработка.Печать();
    УдалитьФайлы(ИмяФайла);

    Если ТипЗнч(ТабДокумент) = Тип("ТабличныйДокумент") И (ПустаяСтрока(ТабДокумент.ИмяПараметровПечати)) Тогда
    Попытка
    ИдентификаторОбработки = Строка(ИсточникМакета.СсылкаНаВнешнююОбработку.УникальныйИдентификатор());
    ТабДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_" + СтрЗаменить(ИдентификаторОбработки, "-", "_");
    ТабДокумент.ИмяПараметровПечати = ТабДокумент.ИмяПараметровПечати + "_" + Ссылка.Метаданные().Имя;
    Исключение

    КонецПопытки;
    КонецЕсли;
    Исключение
    ОбщегоНазначения.СообщитьОбОшибке(ОписаниеОшибки(),, "Не удалось сформировать внешнюю печатную форму!");
    КонецПопытки;

    Возврат ТабДокумент;

    КонецФункции
```
---
Если УТ10 настолько старая, что оперирует ДополнительныеПараметры в виде ХЗ, то заверните свою структуру с руководителями в ХЗ, делов-то.

```1c
    Расшифровка.СсылкаНаВнешнююОбработку.Принадлежность[ИсточникМакета.НомерСтроки - 1].ДополнительныеПараметрыОбработки = Новый ХранилищеЗначений(Руководители, Новый СжатиеДанных(9));
```

Не нужно ее при этом в сам элемент справочника пихать и перезаписывать.
---
Ут 10 Самая новая 10.3.88.3. И новее, дорогой мой, уже похоже не будет. Что поделаешь, что дополнительные параметры у них сделаны как ХЗ. Но это один из способов перенести во внешнюю печатную форму свои параметры. Согласитесь, что через ОХЗ получается менее геморойно.
---
Согласитесь, что через ОХЗ получается менее геморойно. Ага. Ты же их потом за собой очищаешь? Или они продолжают храниться в разрезе пользователей?
Как бы намек на то, а что будет, если несколько человек одновременно будут печатать свои комплекты с разными подписантами?
---
Конечно. Мало того, что записываются для каждого пользователя, чтобы они лбами не сталкивались, но и после печати удаляются. Внешнюю форму ведь можно и просто из счет-фактуры распечатать (без обработки). Тогда там заполняются стандартные руководитель и главный бухгалтер. Если не удалю такая свистопляска пойдет.
---
А если один пользюк в разных сеансах начнет печатать? )) Или в несколько потоков? )) Или несколько челов ходят под одним корпоративным пользюком?
---
Обработка не настолько продвинутая. Потоковая печать не предусмотрена. Печатается 1 комплект за раз. С одним подписантом.
---
Ут 10 Самая новая 10.3.88.3.
У меня есть ЗУП КОРП 2.5 последней доступной версии, там выглядит несколько иначе:

```1c
    Функция НапечататьВнешнююФорму(Ссылка, ИсточникМакета) Экспорт

    Перем ДополнительныеПараметры;

    ДвоичныеДанные = ИсточникМакета.СсылкаНаВнешнююОбработку.Принадлежность[ИсточникМакета.НомерСтроки - 1].ХранилищеВнешнейОбработки.Получить();

    // Получить дополнительные параметры внешней обработки
    ИсточникМакета.Свойство("ДополнительныеПараметрыОбработки", ДополнительныеПараметры);

    Если ДвоичныеДанные = Неопределено Тогда
    ДвоичныеДанные = ИсточникМакета.СсылкаНаВнешнююОбработку.ХранилищеВнешнейОбработки.Получить();
    КонецЕсли;

    Если ДвоичныеДанные = Неопределено Тогда
    Возврат Неопределено;
    КонецЕсли;

    ТабДокумент = Неопределено;

    ИмяФайла = ПолучитьИмяВременногоФайла("epf");
    Попытка
    ДвоичныеДанные.Записать(ИмяФайла);
    Обработка = ВнешниеОбработки.Создать(ИмяФайла);
    Обработка.СсылкаНаОбъект = Ссылка;

    // Передать внешней обработке дополнительные параметры
    Если ДополнительныеПараметры <> Неопределено Тогда

    // Если у внешней обработки есть реквизит для дополнительных параметров, присвоить ему значение
    Если НЕ Обработка.Метаданные().Реквизиты.Найти("ДополнительныеПараметры") = Неопределено Тогда
    Обработка.ДополнительныеПараметры = ДополнительныеПараметры;
    КонецЕсли;

    КонецЕсли;

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

    Возврат ТабДокумент;

    КонецФункции
```

Согласитесь, что через ОХЗ получается менее геморойно.
Нет, хотя бы тем, что это еще очищать нужно, если пользователь отправит подряд несколько комплектов на печать с разными подписантами, то что в итоге получится - одному ктулху известно.
---
Так очищается сразу после печати комплекта. Я не жду пока сеанс закончится.
Кроме того через дополнительные параметры нет возможности разделить пользователей. Здесь больше вероятность, что напечатаются документы не с теми подписантами.
---
А в чем проблема? Сделать какой-нить параметр сеанса, да юзать его.
Некошерно, но быстро.
---
Интересная идея. У меня пока более некошерное решения. Через дополнительные параметры. Постоянная перезапись элемента справочника - вещь более жуткая.
---
Параметры сеанса немного слишком. Решил сделать через ХранилищеОбщихНастроек. Думаю так будет кошернее.
---
я так понимаю, непосредственной перед печатью, открывается некая своя форма для выбора или просто происходит выбор нужного значения типовым методом, используйте это значение для добавления в "ДополнительныеПараметры" и дальше используйте в коде.
---
Спасибо Всем! Похоже лучшее решение нашлось. Тема закрыта.