Вначале рассмотрим исходные данные задачи. На рисунках 1 и 2 данные документа Авансовый отчет в конфигураторе и в режиме предприятия с тестовыми данными из типовой демобазы УНФ 1.5.3:
Рисунок 1. Документ Авансовый отчет конфигурации Управление небольшой фирмой 1.5.3
Рисунок 2. Документ Авансовый отчет в конфигуработоре
Теперь на рисунках 3 и 4 посмотрим структуру приемника - документа Перемещение запасов:
Рисунок 3. Документ Перемещение запасов конфигурации Управление небольшой фирмой 1.5.3
Рисунок 4. Документ Перемещение запасов в конфигураторе.
Видим, что в документе-основании Авансовом отчете в табличной части запасы Склад (реквизит СтруктурнаяЕдиница) и ячейка могут принимать различные значения, поэтому для упрощения задачи принимаем за исходную информацию первой строки. Конечно, можно усложнить задачу, запрашивая перед созданием формы документа перемещения запасов и склад и (если заполнена) ячейка, но это уже оправдывает себя при очень больших количествах строк документа. Да к тому же тут возможны ошибки. Поэтому проще оприходовать все на склад по умолчанию (возможно введением транзитного "авансового" склада), а уже потом разбираться со спецификой хранения на местах.
Для отладки данной обработки, а также ее возможных модификаций можно воспользоваться одним из отладчиков внешних печатных форм, которые поддерживают управляемых формы по технологии БСП. Здесь может ожидать "подводный камешек" отсутствия в типовой конфигурации УНФ 1.5.3 режима модальности. Можно, конечно поправить данные обработки отладки или все-таки найти нужную, но можно воспользоваться приемом временного снятия корня конфигурации с поддержки и изменением данного признака на "использовать с предупреждением" как показано на рисунке 5.
Рисунок 5. Изменение свойств конфигурации УНФ 1.5.3 для облегчения отладки.
Также конфигуарация УНФ имеет свои "особенности" и из-за них многие стандартные внешние обработки не регистрируются в системе или не запускаются. Для решения подобных проблем приходится лезть в конфигурацию и править обработку под особенности данной конфигурации. Тут нужно смотреть код общего модуля "Дополнительные отчеты и обработки" и сопуствующие объекты метаданных еще на входе (см. рисунок 6):
Рисунок 6. Виды внешних обработок.
Также основная отработка исполняемого кода начинается с нижеприведенного участка кода стандартного общего модуля УНФ "Дополнительные отчеты и обработки" и код модуля управляемой формы, реализующий всю логику решения:
// Выполняет команду обработки и возвращает результат ее выполнения. // // Параметры: // ПараметрыКоманды - Структура - Параметры, с которыми выполняется команда. // * ДополнительнаяОбработкаСсылка - СправочникСсылка.ДополнительныеОтчетыИОбработки - Элемент справочника. // * ИдентификаторКоманды - Строка - Имя выполняемой команды. // * ОбъектыНазначения - Массив - Ссылки объектов, для которых выполняется обработка. Обязательный для // назначаемых обработок. // * РезультатВыполнения - Структура - Необязательный. Дополняет возвращаемое значение. // См. СтандартныеПодсистемыКлиентСервер.НовыйРезультатВыполнения(). // АдресРезультата - Строка - Необязательный. Адрес временного хранилища по которому будет размещен результат // выполнения. // // Возвращаемое значение: // * Структура - Результат выполнения, который далее передается на клиент. // * Неопределено - Если был передан АдресРезультата. // // Важно: // Проверка функциональной опции "ИспользоватьДополнительныеОтчетыИОбработки" // должна выполняться вызывающим кодом. // Функция ВыполнитьКоманду(ПараметрыКоманды, АдресРезультата = Неопределено) Экспорт Если ТипЗнч(ПараметрыКоманды.ДополнительнаяОбработкаСсылка) <> Тип("СправочникСсылка.ДополнительныеОтчетыИОбработки") Или ПараметрыКоманды.ДополнительнаяОбработкаСсылка = Справочники.ДополнительныеОтчетыИОбработки.ПустаяСсылка() Тогда Возврат Неопределено; КонецЕсли; ВнешнийОбъект = ПолучитьОбъектВнешнейОбработки(ПараметрыКоманды.ДополнительнаяОбработкаСсылка); ИдентификаторКоманды = ПараметрыКоманды.ИдентификаторКоманды; РезультатВыполнения = ВыполнитьКомандуВнешнегоОбъекта(ВнешнийОбъект, ИдентификаторКоманды, ПараметрыКоманды, АдресРезультата); Возврат РезультатВыполнения; КонецФункции
//////////////////////////////////// Код управляемой формы обработки ////////////////////////////////////////////
&НаКлиенте Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначенияМассив) Экспорт Если ИдентификаторКоманды = "Создать Перемещение запасов" Тогда Для каждого Элемент из ОбъектыНазначенияМассив Цикл КлючПоиска = Новый Структура("Ключ", Элемент); Окна = ПолучитьОкна(); Для каждого Окно из Окна Цикл Рез = Найти(Окно.Заголовок, СокрЛП(КлючПоиска.Ключ) ); Если Рез > 0 Тогда ФормаИст = ПолучитьФорму("Документ.АвансовыйОтчет.Форма.ФормаДокумента", КлючПоиска ,,,Окно); // Уже открытую форму. ФормаДок = ПолучитьФорму("Документ.ПеремещениеЗапасов.Форма.ФормаДокумента"); ДанныеФормыИст = ФормаИст.Объект; ДанныеФормыДок = ФормаДок.Объект; ////// проверки //////////////////// Отказ1 = Ложь; ЗапасыИст = ДанныеФормыИст.Запасы; Если ЗапасыИст.Количество() = 0 Тогда СказатьПользователю("Табличная часть Заказы у документа-основания ПУСТА!"); Возврат; КонецЕсли; СкладИст = ЗапасыИст[0].СтруктурнаяЕдиница; Если НЕ ЗначениеЗаполнено(СкладИст) Тогда СказатьПользователю("Склад источник пуст!"); Отказ1 = Истина; КонецЕсли; // Ячейка может быть не задана и быть пустой, а вот склад нет! //////ЯчейкаИст = ЗапасыИст[0].Ячейка; ////// //////Если НЕ ЗначениеЗаполнено(ЯчейкаИст) Тогда ////// СказатьПользователю("Ячейка источника пуста!"); ////// Отказ1 = Истина; //////КонецЕсли; Если Отказ1 Тогда Возврат; КонецЕсли; //////// Конец проверки /////////// ЗаполнитьФормуНаСервере(ДанныеФормыДок, ДанныеФормыИст); КопироватьДанныеФормы(ДанныеФормыДок, ФормаДок.Объект); ФормаДок.Открыть(); КонецЕсли; КонецЦикла; КонецЦикла; КонецЕсли; КонецПроцедуры &НаСервереБезКонтекста Процедура ЗаполнитьФормуНаСервере(ДанныеФормыДок, ДанныеФормыИст) ЗапасыИст = ДанныеФормыИст.Запасы; СкладИст = ЗапасыИст[0].СтруктурнаяЕдиница; ЯчейкаИст = ЗапасыИст[0].Ячейка; ДанныеФормыДок.Комментарий = "# Заполнение по основанию Авансовый отчет № "+ДанныеФормыИст.Номер+ " от "+ДанныеФормыДок.Дата; ДанныеФормыДок.Организация = ДанныеФормыИст.Организация; ДанныеФормыДок.СтруктурнаяЕдиница = СкладИст; ДанныеФормыДок.СтруктурнаяЕдиницаПолучатель = ""; // Подставлялся по настройкам пользователя для организации что по умолчанию. По ТЗ пуст - сами принимаем решение. ДанныеФормыДок.Ячейка = ЯчейкаИст; //... Свойства Авансового отчета (если еще что-то надо) Запасы = ДанныеФормыДок.Запасы; Для Каждого СтрИст Из ЗапасыИст Цикл Стр = Запасы.Добавить(); Стр.Номенклатура = СтрИст.Номенклатура; Стр.Характеристика = СтрИст.Характеристика; // Если Есть! Стр.Количество = СтрИст.Количество; Стр.ЕдиницаИзмерения = СтрИст.ЕдиницаИзмерения; // Есть ли Заказ покупателя. Если есть в таб. части перемещение запасов заполняется колонка РЕЗЕРВ // по данным авансового отчета (если вдруг будут расхождния по количеству авансового и заказа) Если ЗначениеЗаполнено(СтрИст.ЗаказПокупателя) Тогда Стр.Резерв = Стр.Количество; Стр.ЗаказПокупателя = СтрИст.ЗаказПокупателя; КонецЕсли; КонецЦикла; КонецПроцедуры &НаКлиентеНаСервереБезКонтекста Процедура СказатьПользователю(текст1) СП = Новый СообщениеПользователю; СП.Текст = текст1; СП.Сообщить(); КонецПроцедуры