При автоматизации бухгалтерского учета в решениях на платформе 1С:Предприятие 8.3 разработчики часто сталкиваются с задачей автоматического или полуавтоматического заполнения документов. Если для стандартных документов (таких как «Поступление товаров и услуг» или «Реализация») эта задача решается простым заполнением табличной части, то с документом ОперацияБух (в интерфейсе — «Операция, введенная вручную») все обстоит иначе.
В этой статье мы подробно разберем архитектурные особенности этого документа, выясним причину сложностей при его заполнении и пошагово рассмотрим несколько эффективных способов реализации заполнения «табличной части» напрямую из формы или с помощью внешних инструментов.
Прежде чем переходить к написанию кода, проанализируем ситуацию с технической стороны. Главная особенность документа ОперацияБух заключается в том, что у него физически отсутствует табличная часть для хранения проводок в привычном понимании.
Та таблица, которую бухгалтер видит на экране при открытии формы операции, является динамическим отображением набора записей регистра бухгалтерии Хозрасчетный. Когда пользователь открывает документ, платформа считывает движения по этому документу из базы данных и выводит их в виде таблицы. Соответственно, при записи документа изменения транслируются напрямую в движения регистра.
Поэтому стандартный подход «получить объект -> заполнить табличную часть -> записать» здесь не сработает. Нам необходимо работать непосредственно с коллекциями движений документа (Движения.Хозрасчетный) или с отображаемыми на форме данными.
Рассмотрим подробнее три основных способа решения этой задачи: через внешнюю обработку заполнения БСП, через расширение конфигурации и с использованием встроенного механизма типовых операций.
Если ваша конфигурация находится на поддержке (например, типовая 1С:Бухгалтерия предприятия) и вы не хотите вносить изменения в основную конфигурацию, лучшим решением будет использование механизма дополнительных отчетов и обработок Библиотеки стандартных подсистем (БСП).
Мы создадим обработку с видом «Заполнение объекта». Чтобы заполнение происходило интерактивно (прямо на форме, открытой у пользователя), мы настроим команду с типом запуска ВызовКлиентскогоМетода. Это позволит модифицировать данные формы без немедленной записи документа в базу данных, давая пользователю возможность проверить результат перед сохранением.
Разберем по шагам создание такой обработки:
СведенияОВнешнейОбработке().Посмотрим на пример кода в модуле объекта внешней обработки:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработкеКопия("2.2.2.1");
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиЗаполнениеОбъекта();
ПараметрыРегистрации.Назначение.Добавить("Документ.ОперацияБух");
ПараметрыРегистрации.Наименование = "Заполнение проводок операции вручную";
ПараметрыРегистрации.Версия = "1.0";
ПараметрыРегистрации.БезопасныйРежим = Ложь;
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = "Заполнить проводки по шаблону";
НоваяКоманда.Идентификатор = "ЗаполнитьПроводки";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипЗапускаВызовКлиентскогоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
Возврат ПараметрыРегистрации;
КонецФункции
Теперь создадим форму обработки. В модуле формы пропишем логику заполнения, которая будет выполняться на клиенте и сервере:
&НаКлиенте
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ОбъектыНазначения, ПараметрыВыполнения) Экспорт
// Получаем форму документа-владельца, из которой была вызвана команда
ФормаДокумента = ПараметрыВыполнения.ЭтаФорма;
// Вызываем серверный метод для заполнения движений непосредственно в контексте формы
ЗаполнитьДвиженияНаСервере(ФормаДокумента.Объект);
// Обязательно взводим флаг модифицированности формы, чтобы платформа поняла, что данные изменились
ФормаДокумента.Модифицированность = Истина;
ПоказатьОповещениеПользователя("Успешно", , "Табличная часть проводок заполнена!", КартинкаОповещения.Информация);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ЗаполнитьДвиженияНаСервере(ДанныеФормыДокумента)
// Очищаем существующие проводки, если это необходимо по бизнес-логике
ДанныеФормыДокумента.Движения.Хозрасчетный.Очистить();
// Добавляем новую проводку в коллекцию движений формы
НоваяПроводка = ДанныеФормыДокумента.Движения.Хозрасчетный.Добавить();
// Заполняем базовые реквизиты проводки
НоваяПроводка.Период = ДанныеФормыДокумента.Дата;
НоваяПроводка.Организация = ДанныеФормыДокумента.Организация;
НоваяПроводка.Активность = Истина;
// Устанавливаем счета учета
НоваяПроводка.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("60.01");
НоваяПроводка.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("51");
// Пример заполнения субконто для Дебета (Контрагенты и Договоры)
// Важно: субконто заполняется по типам, привязанным к плану счетов
ВидСубконтоКонтрагент = НоваяПроводка.СчетДт.ВидыСубконто[0].ВидСубконто;
НоваяПроводка.СубконтоДт[ВидСубконтоКонтрагент] = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7701234567");
// Заполняем сумму операции
НоваяПроводка.Сумма = 250000;
НоваяПроводка.СуммаНУДт = 250000; // Налоговый учет по дебету, если применимо
КонецПроцедуры
Благодаря использованию типа запуска ВызовКлиентскогоМетода пользователь мгновенно увидит новые строки на экране своего монитора, сможет скорректировать их вручную и нажать стандартную кнопку «Записать».
Если бизнес-требования диктуют необходимость наличия кнопки «Заполнить» непосредственно на самой форме документа ОперацияБух, идеальным инструментом станет расширение конфигурации.
Разберем алгоритм реализации этого метода:
ОперацияБух и его основную форму (обычно это ФормаДокумента).Расш_ЗаполнитьОперацию, и перетащите её на командную панель формы.Пример кода обработчика в модуле заимствованной формы:
&НаКлиенте
Процедура Расш_ЗаполнитьОперацию(Команда)
// Передаем объект формы на сервер для модификации движений
Расш_ЗаполнитьПроводкиНаСервере();
// Уведомляем форму об изменениях
ЭтаФорма.Модифицированность = Истина;
КонецПроцедуры
&НаСервере
Процедура Расш_ЗаполнитьПроводкиНаСервере()
// Получаем объект документа из реквизита формы "Объект"
ДокументОбъект = РеквизитФормыВЗначение("Объект");
// Пример заполнения движений на сервере
ДвиженияХозрасчетный = Объект.Движения.Хозрасчетный;
ДвиженияХозрасчетный.Очистить();
НоваяСтрока = ДвиженияХозрасчетный.Добавить();
НоваяСтрока.Период = Объект.Дата;
НоваяСтрока.Организация = Объект.Организация;
НоваяСтрока.СчетДт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("20.01");
НоваяСтрока.СчетКт = ПланыСчетов.Хозрасчетный.НайтиПоКоду("10.01");
НоваяСтрока.Сумма = 50000;
// Для демонстрации обновим реквизит формы из измененного объекта
ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
КонецПроцедуры
При таком подходе кнопка гармонично вписывается в интерфейс программы, выглядит как типовой функционал и обеспечивает быструю работу без вызова внешних файлов обработок.
Прежде чем приступать к конфигурированию и написанию кода, обязательно проанализируйте, знают ли конечные пользователи и руководство о существовании стандартного мощного механизма под названием «Типовые операции».
Этот функционал уже встроен в типовую 1С:Бухгалтерию и предназначен именно для решения задачи быстрого заполнения ручных операций по заранее определенному шаблону. Работает это следующим образом:
ОперацияБух пользователь выбирает созданную типовую операцию. Программа выводит удобную форму для заполнения параметров (например, предлагает выбрать контрагента и указать сумму).Использование механизма «Типовых операций» экономит время разработчика и дает бухгалтерам гибкий инструмент, который они могут настраивать самостоятельно без привлечения программистов при малейшем изменении законодательства или учетной политики.
Таким образом, выбор метода зависит от конкретных задач бизнеса: для простых статичных шаблонов идеально подойдут встроенные Типовые операции; для динамического заполнения на основе сложных внешних данных (например, загрузка из Excel) лучшим выбором станет внешняя обработка БСП или реализация кнопки через расширение конфигурации.