HelpF.pro

Как заполнить табличную часть на основании документа

В форме документа счет-фактура выданный аванс заполнить табличную часть Авансы на основании документа поступление безналичных денежных средств.
Условия:
1) Перед заполнением табличной части документа получить от пользователя подтверждение на это действие;
2) Обработку создания документа сделать внешней и подключаемой к форме документа счет-фактура на аванс выданный;
3) После заполнения табличной части не записывать документ, а разрешить пользователю продолжить редактирование изменной табличной части или самостоятельно записать документ.
Решение:
Пункты 1 и 2 не представляют особой сложности, но пункт 3 заставил меня задуматься и написать, по-моему мнению, топорный, но исправно действующий код.

Понятно, что от нас требуется создать внешнюю обработку вида "ЗаполнениеОбъекта" и подключить её в информационную базу.
Приведу код в модуле обработки:
Код 1C v 8.2 УП
 Функция СведенияОВнешнейОбработке() Экспорт

ПараметрыРегистрации = Новый Структура;
МассивНазначений = Новый Массив;
МассивНазначений.Добавить("Документ.СчетФактураВыданныйАванс");

ПараметрыРегистрации.Вставить("Вид", "ЗаполнениеОбъекта");
ПараметрыРегистрации.Вставить("Назначение", МассивНазначений);
ПараметрыРегистрации.Вставить("Наименование", "Заполнить документ");
ПараметрыРегистрации.Вставить("Версия", "1.0");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Истина);
ПараметрыРегистрации.Вставить("Информация", "Дополнительная обработка табличной части к документу счет-фактура выданный аванс");

ТаблицаКоманд = ПолучитьТаблицуКоманд();

ДобавитьКоманду(ТаблицаКоманд,
"Заполнить документ",
"Заполнить документ",
"ВызовКлиентскогоМетода",
Истина);

ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);

Возврат ПараметрыРегистрации;
КонецФункции

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

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

Так как нам придется работать с формами объектов мы просто вынуждены использовать метод ВызовКлиентскогоМетода для вызова команды внешней обработки.

Напомню, при использовании ВызовСерверногоМетода с формами объектов работать не получится.

Так как мы использовали ВызовКлиентскогоМетода, то обязательную процедуру, для внешней подключаемой обработки заполнения объектов, ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт, необходимо выполнять &НаКлиенте в модуле формы обработки, а значит создадим любую форму обработки, пользователь её всеравно не увидит, и поместим внутрь модуля формы следующий код:
Код 1C v 8.2 УП
 &НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт
//Спросим у пользователя разрешение на продолжение обработки
Режим = РежимДиалогаВопрос.ДаНет;
Текст = "Текущие данные документа будут заменены новыми без возможности восстановления.
|Продолжить?";
Ответ = Вопрос(Текст, Режим, 0);
Если Ответ = КодВозвратаДиалога.Да Тогда

//Если пользователь дал разрешение на продолжение, то начнем перебирать все
//документы, у которых мы планируем заполнить табличную часть
Для каждого Элемент из ОбъектыНазначенияМассив Цикл

//Зададим ключ поиска документа, из которого вызвана данная обработка,
//чтобы получить ссылку на редактирумый документ в удобном виде для
//функции ОткрытьФорму()
КлючПоиска = Новый Структура("Ключ", Элемент);

//Но нам не надо открывать новую форму (окно) для изменяемого документа, а
//Нам надо все изменения показать в уже открытых у клиента окнах
Окна = ПолучитьОкна();
Для каждого Окно из Окна Цикл

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

//Далее мы получаем объект только, что повторно открытой формы и помещаем её в переменную
//В объекте содержатся все реквизиты (элементы) формы
НовыйОбъект = Форма.Объект;

//Мы помещаем объект формы в переменную,
//так как должны передать её в процедуру на сервере,
//где нельзя изменять объект формы, зато можно править переменную содержащую его
ЗаполнитьОбъект(НовыйОбъект);

//После выполнения процедуры на сервере мы получаем изменную переменную НовыйОбъект,
//которую необходимо передать в уже полученную нами форму
КопироватьДанныеФормы(НовыйОбъект, Форма.Объект);
КонецЕсли;
КонецЦикла;

КонецЦикла;
КонецЕсли;
КонецПроцедуры

Ниже приведу код, который у вас может быть совершенно другим и делать, какие-либо другие манипуляции с объектом формы:
Код 1C v 8.2 УП
 &НаСервере
Функция ЗаполнитьОбъект(НовыйОбъект)

Если ТипЗнч(НовыйОбъект.ДокументОснование) = Тип("ДокументСсылка.ПоступлениеБезналичныхДенежныхСредств") Тогда

Если НовыйОбъект.ДокументОснование.РасшифровкаПлатежа.Количество() > 0 Тогда
НовыйОбъект.Авансы.Очистить();
КонецЕсли;

Для каждого СтрокаТЧ из НовыйОбъект.ДокументОснование.РасшифровкаПлатежа Цикл
НоваяСтрока = НовыйОбъект.Авансы.Добавить();
Если ЗначениеЗаполнено(СтрокаТЧ.СчетНаОплату) Тогда
НоваяСтрока.Содержание = "Предварительная оплата" + ФормированиеПечатныхФорм.СформироватьЗаголовокДокумента(СтрокаТЧ.СчетНаОплату, НСтр("ru=' по счету на оплату'"));
КонецЕсли;
НоваяСтрока.Сумма = СтрокаТЧ.Сумма;
НоваяСтрока.СтавкаНДС = Перечисления.СтавкиНДС.НДС18_118;
ТекПроцентНДС = ЦенообразованиеКлиентСервер.ПолучитьСтавкуНДСЧислом(НоваяСтрока.СтавкаНДС);
НоваяСтрока.СуммаНДС = ЦенообразованиеКлиентСервер.РассчитатьСуммуНДС(НоваяСтрока.Сумма, ТекПроцентНДС);
КонецЦикла;
КонецЕсли;

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

Автор ApocalypseNTC
Опубликовано на сайте: https://HelpF.pro
Прямая ссылка: https://HelpF.pro/faq82/view/1168.html