Вначале рассмотрим исходные данные задачи. На рисунках 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;
СП.Сообщить();
КонецПроцедуры