В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача автоматического формирования бухгалтерских проводок. Одной из наиболее распространенных проблем является ситуация, когда сам документ ОперацияБух создается, строки в нем появляются, но аналитика (субконто) остается пустой. Рассмотрим подробно, почему это происходит и как правильно реализовать заполнение движений по регистру бухгалтерии Хозрасчетный.
Проанализируем ситуацию: когда мы работаем с документом ОперацияБух, мы фактически работаем с регистратором для регистра бухгалтерии. Ошибка часто кроется не в самой функции УстановитьСубконто, а в логике работы с объектами метаданных. Выясним основные причины неудачи.
Первая и самая критичная ошибка — отсутствие фактической записи данных в базу. Создание набора записей и добавление в него строк происходит в оперативной памяти. Если в конце процедуры не вызвать метод Записать() для объекта НаборЗаписей, все изменения будут потеряны после завершения работы программного кода. Посмотрим на правильную структуру записи:
РегХозрасчетный = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
РегХозрасчетный.Отбор.Регистратор.Установить(БухСпрСсылка);
// ... цикл заполнения записей ...
РегХозрасчетный.Записать(Истина); // Параметр Истина перезаписывает существующие движения
Функция БухгалтерскийУчет.УстановитьСубконто является стандартным инструментом во многих типовых конфигурациях (например, в 1С:Бухгалтерия 3.0). Однако она требует строгого соблюдения порядка аргументов. Проанализируем типичную ошибку из практики:
Часто программисты путают счета дебета и кредита при вызове функции. Если вы передаете в функцию СчетКт, но пытаетесь записать значение в коллекцию СубконтоДт, система не сможет сопоставить виды субконто, так как на счете кредита могут быть совершенно другие настройки аналитики.
Рассмотрим правильный пример заполнения:
// Заполнение субконто для Дебета
БухгалтерскийУчет.УстановитьСубконто(РегЗапись.СчетДт, РегЗапись.SubkontoDt, "Номенклатура", Выборка.Номенклатура);
// Заполнение субконто для Кредита
БухгалтерскийУчет.УстановитьСубконто(РегЗапись.СчетКт, РегЗапись.SubkontoKt, "ПрочиеДоходыИРасходы", Справочники.ПрочиеДоходыИРасходы.ПрочиеРасходы);
Важно помнить: метод УстановитьСубконто ищет вид субконто по его строковому имени или ссылке на ПланВидовХарактеристик. Если на указанном в проводке счете нет вида субконто с таким именем, значение просто не будет установлено, и система не выдаст никакой ошибки в процессе выполнения.
Если стандартный метод УстановитьСубконто по каким-то причинам не срабатывает, или вы хотите иметь полный контроль над процессом, рекомендуется обращаться к коллекции субконто напрямую через ПланВидовХарактеристик. Этот метод считается более надежным, так как исключает ошибки типизации.
Разберем по шагам, как это реализовать:
СчетДт или СчетКт). Это критически важно, так как коллекция субконто инициализируется на основании настроек счета.
РегЗапись.СчетДт = ПланыСчетов.Хозрасчетный.ИнвентарьИХозяйственныеПринадлежности;
// Прямая установка значения субконто "Номенклатура"
ВидСубкНоменклатура = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура;
РегЗапись.СубконтоДт[ВидСубкНоменклатура] = Выборка.Номенклатура;
// Прямая установка значения субконто "Склады"
ВидСубкСклады = ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады;
РегЗапись.СубконтоДт[ВидСубкСклады] = Выборка.Склад;
Вместо того чтобы создавать отдельный объект НаборЗаписей и вручную устанавливать отбор по регистратору, правильнее использовать свойство Движения самого объекта документа. Рассмотрим, почему это лучше:
Регистратор = Ссылка для каждой строки.БухСпр.Записать(), если установлен флаг Записывать = Истина.Посмотрим на пример правильной реализации через коллекцию Движения:
БухСпр = Документы.ОперацияБух.СоздатьДокумент();
БухСпр.Дата = ТекущаяДата();
БухСпр.Организация = Справочники.Организации.НайтиПоКоду("00-000001");
// Записываем документ, чтобы получить ссылку
БухСпр.Записать();
// Работаем напрямую с движениями документа
ДвиженияХозрасчетный = БухСпр.Движения.Хозрасчетный;
ДвиженияХозрасчетный.Очистить(); // Очищаем старые записи, если нужно
Пока Выборка.Следующий() Цикл
НоваяЗапись = ДвиженияХозрасчетный.Добавить();
НоваяЗапись.Период = БухСпр.Дата;
НоваяЗапись.Организация = БухСпр.Организация;
НоваяЗапись.СчетДт = ПланыСчетов.Хозрасчетный.ПрочиеРасходы;
НоваяЗапись.СчетКт = Выборка.Счет;
// Заполняем аналитику
БухгалтерскийУчет.УстановитьСубконто(НоваяЗапись.СчетДт, НоваяЗапись.СубконтоДт, "ПрочиеДоходыИРасходы", Выборка.ПрочийРасход);
НоваяЗапись.Сумма = Выборка.Сумма;
КонецЦикла;
// Устанавливаем флаг необходимости записи движений
ДвиженияХозрасчетный.Записывать = Истина;
БухСпр.Записать();
При программном заполнении ОперацииБух в современных конфигурациях типа БП 3.0, важно учитывать еще несколько факторов, которые часто упускают из виду:
СуммаНУ_Дт, СуммаНУ_Кт, а также при необходимости ПР и ВР. Если их не заполнить, отчетность по налогу на прибыль будет некорректной, а в самой форме операции данные по НУ будут пустыми.Активность = Истина. Если это свойство случайно установится в Ложь, проводки будут видны в документе, но не попадут в оборотно-сальдовую ведомость.ОперацияБух есть реквизит СуммаОперации. Его нужно заполнять итоговой суммой всех созданных проводок. Это нужно для корректного отображения документа в списках (журналах).Проанализировав все вышеперечисленное, можно сделать вывод: успех программного создания проводок зависит от последовательности действий (Счет -> Субконто), правильности указания коллекции (Дт или Кт) и обязательного вызова метода записи набора. Использование коллекции Движения объекта документа является наиболее современным и безопасным способом решения данной задачи.