В практике автоматизации 1С часто возникает задача добавить возможность ввода одного типового документа на основании другого, если такая связь не предусмотрена разработчиками фирмы «1С». Одной из типичных задач в конфигурации Бухгалтерия предприятия 3.0 является создание документа Счет от поставщика на базе Счета на оплату покупателю. Это необходимо, например, в схемах перепродажи, когда менеджер выставляет счет клиенту, а затем на его основе формирует заказ (счет) поставщику.
Основная сложность здесь заключается в желании сохранить конфигурацию на поддержке и обеспечить корректное отображение документов в отчете «Структура подчиненности» (Связанные документы). Рассмотрим по шагам, как реализовать эту задачу, используя механизм расширений и возможности Библиотеки стандартных подсистем (БСП).
Если мы просто добавим кнопку на форму через расширение, мы столкнемся с двумя проблемами. Во-первых, кнопка не будет находиться в стандартном подменю «Создать на основании», что нарушит единообразие интерфейса. Во-вторых, при нажатии на такую кнопку и создании документа связь между ними не зафиксируется в системе. Если вы откроете «Связанные документы», вы не увидите цепочку. Это происходит потому, что в типовом документе СчетОтПоставщика нет реквизита, хранящего ссылку на СчетНаОплатуПокупателю, и этот реквизит не включен в специальный объект метаданных — Критерий отбора.
Проанализируем самый надежный способ, который сделает нашу доработку неотличимой от типового функционала. Нам потребуется выполнить три основных этапа: модификация данных, реализация логики заполнения и регистрация команды в интерфейсе.
Шаг 1. Добавление реквизита и настройка связи
Для начала создадим расширение и добавим в него документ СчетОтПоставщика. Чтобы система «видела» связь, нам нужен «крючок» внутри целевого документа.
СчетОтПоставщика (в расширении) новый реквизит, например, ДокументОснование_СчетПокупателю с типом ДокументСсылка.СчетНаОплатуПокупателю.СвязанныеДокументы.Шаг 2. Программное заполнение данных
Теперь нам нужно научить новый счет «понимать» данные из старого. Для этого используем обработчик ОбработкаЗаполнения в модуле объекта документа СчетОтПоставщика. В расширении используем аннотацию &После.
&После("ОбработкаЗаполнения")
Процедура Расш1_ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.СчетНаОплатуПокупателю") Тогда
// Заполняем наш новый реквизит для связи
ЭтотОбъект.ДокументОснование_СчетПокупателю = ДанныеЗаполнения;
// Переносим основные реквизиты
ЭтотОбъект.Организация = ДанныеЗаполнения.Организация;
ЭтотОбъект.ВалютаДокумента = ДанныеЗаполнения.ВалютаДокумента;
ЭтотОбъект.КурсВзаиморасчетов = ДанныеЗаполнения.КурсВзаиморасчетов;
ЭтотОбъект.КратностьВзаиморасчетов = ДанныеЗаполнения.КратностьВзаиморасчетов;
// Переносим табличную часть Товары
Для Каждого СтрокаИсточника Из ДанныеЗаполнения.Товары Цикл
НоваяСтрока = ЭтотОбъект.Товары.Добавить();
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаИсточника);
// Здесь можно добавить логику поиска цен поставщика, если они отличаются от цен продажи
КонецЦикла;
// Аналогично для услуг, если требуется
КонецЕсли;
КонецПроцедуры
Шаг 3. Регистрация в меню «Создать на основании»
В современных версиях БП 3.0 меню формируется динамически через БСП. Чтобы наш вариант появился в типовом списке, нужно обратиться к модулю менеджера документа-источника (СчетНаОплатуПокупателю).
В расширении для модуля менеджера перехватываем процедуру ПриОпределенииКомандПодключенныхКОбъекту. Выясним причину популярности этого метода: он позволяет добавлять команды без изменения форм самого документа.
&После("ПриОпределенииКомандПодключенныхКОбъекту")
Процедура Расш1_ПриОпределенииКомандПодключенныхКОбъекту(НастройкиРегистрации, ПараметрыРегистрации)
Команда = НастройкиРегистрации.Команды.Добавить();
Команда.Тип = "ЗаполнитьОбъект"; // Тип команды для ввода на основании
Команда.Идентификатор = "СоздатьСчетОтПоставщикаНаОсновании";
Команда.Представление = НСтр("ru = 'Счет от поставщика'");
Команда.ПроверкаПроведенности = Истина;
Команда.Порядок = 100;
// Указываем целевой документ
Команда.ИмяОбъекта = "Документ.СчетОтПоставщика";
КонецПроцедуры
Рассмотрим альтернативный вариант, упомянутый в обсуждении. Если вы по каким-то причинам не хотите использовать расширение для логики (хотя для БП 3.0 это менее удобно), можно воспользоваться механизмом Дополнительных отчетов и обработок.
СведенияОВнешнейОбработке.СозданиеСвязанныхОбъектов.ВыполнитьКоманду прописываем код открытия формы нового документа с заполнением.Важный нюанс: Как справедливо заметили участники форума, использование только внешней обработки не решит проблему «Связанных документов». Даже если обработка создаст новый документ и заполнит его, типовой критерий отбора не узнает об этой связи, пока вы не добавите реквизит в расширение. Поэтому внешняя обработка здесь может выступать лишь как дополнение к расширению, но не как полная замена.
При реализации заполнения Счета от поставщика важно помнить о специфике учета:
ЦеныНоменклатурыПоставщиков или оставить их пустыми для ручного ввода.Поставщик останется пустым, так как в исходном счете указан Покупатель. Можно реализовать алгоритм автоматического подбора основного поставщика для первой позиции номенклатуры в списке.Таким образом, комбинируя механизм расширения метаданных (для хранения связи) и подключаемых команд БСП (для интерфейса), мы получаем чистое, обновляемое решение, которое полностью соответствует логике типовой конфигурации.