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