В практике работы с конфигурациями на базе 1С:Предприятие 8.3 часто возникает ситуация, когда в уже настроенном и работающем учете меняются правила игры. Типичный пример — включение партионного учета на счетах учета материальных запасов (например, 105.31 или 10.01), когда деятельность уже велась. После добавления субконто Партии все накопленные остатки и движения оказываются «пустыми» в разрезе нового аналитического разреза. Рассмотрим, как программно исправить эту ситуацию, не прибегая к ручной корректировке каждой операции.
Когда мы добавляем новое субконто на счет, 1С не заполняет его ретроспективно. Это приводит к тому, что при попытке списать ТМЦ программа выдает ошибку: «Дебет партии не заполнен» или не находит остатков по конкретной партии. Если документов в базе много, единственный выход — написать обработку, которая переберет движения документов и проставит в них нужные значения. В случае с поступлениями (Партиями), как правило, значением субконто является сама ссылка на документ поступления.
Прежде чем приступать к написанию кода, разберем, как хранятся субконто. В конфигурациях БГУ 2.0 и Бухгалтерия предприятия 3.0 работа с субконто в регистре бухгалтерии (ЖурналПроводокЕПСБУ или Хозрасчетный) реализована через специальную коллекцию. Обращаться к ней напрямую через индексы не всегда удобно, поэтому в типовых решениях предусмотрены вспомогательные функции в общих модулях.
Рассмотрим пошагово процесс изменения движений уже проведенного документа. Нам необходимо получить набор записей регистра, прочитать его, модифицировать нужные строки и записать обратно. Проанализируем пример кода, который решает эту задачу.
// Предположим, у нас есть переменная ДокСсылка — ссылка на документ поступления
Сч105_31 = ПланыСчетов.ЕПСБУ.НайтиПоКоду("105.31");
ДокОбъект = ДокСсылка.ПолучитьОбъект();
// Обращаемся к движениям документа по конкретному регистру
// Для БГУ это ЖурналПроводокЕПСБУ, для БП — Хозрасчетный
Проводки = ДокОбъект.Движения.ЖурналПроводокЕПСБУ;
Проводки.Прочитать();
Для каждого Проводка Из Проводки Цикл
// Проверяем, что счет в дебете соответствует нашему целевому счету
Если Проводка.СчетДт = Сч105_31 Тогда
// Используем типовую процедуру для установки значения субконто
// Важно правильно передать параметры: Проводка, сторона (Дт/Кт), имя или номер субконто, значение
БухгалтерскийУчет.УстановитьСубконто(Проводка, "Дт", "Партии", ДокСсылка);
КонецЕсли;
КонецЦикла;
// Записываем только движения, не перепроводя сам документ
Проводки.Записать();
Важный нюанс: Обратите внимание на метод УстановитьСубконто. В сообщениях форума часто встречается ошибка, когда программисты пытаются передать в эту функцию Проводка.СчетДт или Проводка.СубконтоДт как первый параметр. Это неверно. Первым параметром должна выступать сама строка проводки (объект записи регистра), а вторым — строковый идентификатор стороны "Дт" или "Кт". Проанализируем это подробнее ниже.
При использовании функции БухгалтерскийУчет.УстановитьСубконто часто возникает ошибка: Поле объекта не обнаружено (СчетРегистрБухгалтерииСубконто.ЖурналПроводокЕПСБУ). Выясним причину: она кроется в том, что функция внутри себя пытается динамически обращаться к свойствам переданного объекта. Если вы передали не строку набора записей, а что-то иное, или ошиблись в написании стороны («Дт» вместо «Дт»), система не сможет корректно вычислить путь к данным.
Правильный синтаксис функции в типовых БГУ/БП выглядит так:
БухгалтерскийУчет.УстановитьСубконто(СтрокаПроводки, Сторона, ВидСубконто, Значение)
Движения.ВашРегистр."Дт" или "Кт".ПланыВидовХарактеристик.ВидыСубконто..., либо строковое имя, либо порядковый номер (1, 2, 3).ДокСсылка).Для документов типа «Операция (бухгалтерская)» или «Ввод начальных остатков» логика будет схожей, но с одним отличием: в них партии не всегда совпадают с самим документом. Рассмотрим ситуацию:
В конфигурации БГУ 2.0 (Бухгалтерия государственного учреждения) учет материальных запасов имеет свои тонкости. Проанализируем ситуацию, описанную в теме: использование счета 105.31. Чтобы партии начали «работать» правильно при списании, недостаточно просто заполнить их в проводках. Нужно проверить настройки учетной политики. Если в настройках метода оценки стоимости материальных запасов стоит «По средней стоимости», то программа может игнорировать заполненные партии при проведении документов списания.
Для полноценного партионного учета (например, для медикаментов, где важна цена каждой закупки) необходимо установить метод «По ФИФО». Только в этом случае система будет требовать указания партии в кредитовых оборотах и корректно рассчитывать стоимость списания.
Программное изменение проводок — это серьезное вмешательство в базу данных. Рассмотрим меры предосторожности:
Проводки.Записать().Сведем все знания в единый алгоритм, который можно использовать в консоли запросов или простой внешней обработке:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеМЗ.Ссылка КАК Ссылка
|ИЗ
| Документ.ПоступлениеМЗ КАК ПоступлениеМЗ
|ГДЕ
| ПоступлениеМЗ.Проведен = ИСТИНА
| И ПоступлениеМЗ.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
Запрос.УстановитьПараметр("НачалоПериода", НачалоГода(ТекущаяДата()));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(ТекущаяДата()));
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Сч105_31 = ПланыСчетов.ЕПСБУ.НайтиПоКоду("105.31");
Пока Выборка.Следующий() Цикл
ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
ДвиженияБухгалтерии = ДокОбъект.Движения.ЖурналПроводокЕПСБУ;
ДвиженияБухгалтерии.Прочитать();
БылиИзменения = Ложь;
Для каждого Запись Из ДвиженияБухгалтерии Цикл
Если Запись.СчетДт = Сч105_31 Тогда
// Проверяем, не заполнено ли уже субконто, чтобы не перезаписывать лишний раз
// Обычно Партии — это субконто №3
БухгалтерскийУчет.УстановитьСубконто(Запись, "Дт", 3, Выборка.Ссылка);
БылиИзменения = Истина;
КонецЕсли;
КонецЦикла;
Если БылиИзменения Тогда
// Записываем набор записей с флагом истина, чтобы не пересчитывать итоги при каждой записи
ДвиженияБухгалтерии.Записать(Истина);
Сообщить("Обработан документ: " + Выборка.Ссылка);
КонецЕсли;
КонецЦикла;
Используя данный подход, мы эффективно решаем задачу заполнения аналитики без необходимости полной отмены проведения и повторного ввода документов, что особенно важно в базах с большим объемом данных или закрытыми периодами (при наличии прав на редактирование проводок).