Как правильно сформировать сложную проводку в 1С:Предприятие 7.7?

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При разработке собственных документов и алгоритмов проведения в платформе 1С:Предприятие 7.7 нередко возникает необходимость отразить списание нескольких различных материалов (или затрат) на себестоимость одной единицы готовой продукции. В типовых конфигурациях для этого часто применяется механизм сложной проводки. Однако при изменении последовательности вызова процедур проведения можно столкнуться с критической ошибкой:

{Документ.СобственнаяПродукция.Модуль Документа}: В корреспонденции не выбран счет!(проводка 1/2)

Разберем детально, как устроен механизм сложных проводок в платформе 1С 7.7, выясним причину возникновения ошибки и рассмотрим несколько надежных способов правильной организации проводок.

Причина возникновения ошибки и механизм сложной проводки

Проанализируем структуру бухгалтерского регистра 1С 7.7. В отличие от платформы 1С:Предприятие 8, где в каждой проводке присутствуют независимые поля КоличествоДт и КоличествоКт, в версии 7.7 в рамках одной стандартной проводки предусмотрено только одно общее поле Количество. Если на счетах дебета и кредита единицы измерения или объемы отличаются (например, выпуск готовой продукции в штуках со списанием ингредиентов в килограммах и литрах), простая проводка приводит к искажению количественного учета.

Для решения этой проблемы платформа предоставляет механизм сложной проводки. Его принципы работы следующие:

  1. Главная (базовая) проводка создается первой: вызывается метод Операция.НоваяПроводка(). В ней заполняется одна сторона (например, дебет выпуска готовой продукции), общее количество выпуска и суммарная себестоимость.
  2. Подчиненные корреспонденции добавляются к главной: вызывается метод Операция.НоваяКорреспонденция(). В каждой такой строке указывается только корреспондирующий счет (например, кредит материалов), количество конкретного материала и его сумма.
  3. Контроль баланса: платформа автоматически считает сложную проводку закрытой, когда суммарная величина всех подчиненных строк становится строго равна сумме базовой проводки.

Если разработчик пытается сначала обойти строки табличной части и вызвать процедуры формирования корреспонденций, а итоговую проводку по дебету сформировать в конце («в подвале» документа), платформа пытается прикрепить подчиненные корреспонденции к еще не созданной или не полностью инициализированной базовой проводке. В результате счет корреспонденции не определяется, и при выполнении метода Операция.Записать() возникает системная ошибка.

Решение 1: Предварительный сбор данных в Таблицу Значений

Рассмотрим основной способ решения проблемы, когда необходимо сформировать именно сложную проводку. Поскольку для инициализации главной проводки требуется знать итоговую сумму списания и общее количество выпуска, сначала накапливаем данные строк табличной части во временную структуру, после чего формируем проводки в строгой последовательности.

Разберем по шагам реализацию данного алгоритма:

  1. Создаем объект ТаблицаЗначений и выгружаем (или построчно заполняем) в него реквизиты списания: счет, субконто, количество и рассчитанную сумму.
  2. Вычисляем общую сумму всех затрат с помощью метода Итог().
  3. Формируем базовую проводку выпуска продукции с итоговой суммой и общим количеством.
  4. Обходим строки подготовленной таблицы значений и последовательно добавляем корреспонденции списания затрат.

Посмотрим на пример программного кода:


// Создаем таблицу для накопления строк списания
ТЗ_Затраты = СоздатьОбъект("ТаблицаЗначений");
ТЗ_Затраты.НоваяКолонка("СчетЗатрат");
ТЗ_Затраты.НоваяКолонка("Субконто1");
ТЗ_Затраты.НоваяКолонка("Субконто2");
ТЗ_Затраты.НоваяКолонка("Субконто3");
ТЗ_Затраты.НоваяКолонка("Количество");
ТЗ_Затраты.НоваяКолонка("Сумма");

// Заполняем таблицу по строкам документа
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
    ТЗ_Затраты.НоваяСтрока();
    ТЗ_Затраты.СчетЗатрат = СчетЗатрат;
    ТЗ_Затраты.Субконто1  = МестоХранения;
    ТЗ_Затраты.Субконто2  = Затрата;
    ТЗ_Затраты.Субконто3  = Партия;
    ТЗ_Затраты.Количество = Кво;
    ТЗ_Затраты.Сумма      = Сумма;
КонецЦикла;

// Получаем общую себестоимость выпуска
ИтогоСебестоимость = ТЗ_Затраты.Итог("Сумма");

// 1. Создаем базовую проводку (выпуск продукции)
Операция.НоваяПроводка();
Операция.Дебет.Счет = СчетВыпуска;
Операция.Дебет.Субконто(1, МестоХраненияПродукции);
Операция.Дебет.Субконто(2, Продукция);
Операция.Дебет.Субконто(3, ПартияПродукции);
Операция.Количество = ИтогоКоличествоПродукции;
Операция.Сумма = ИтогоСебестоимость;
Операция.Содержание = "Выпуск готовой продукции";

// 2. Добавляем подчиненные корреспонденции списания материалов
ТЗ_Затраты.ВыбратьСтроки();
Пока ТЗ_Затраты.ПолучитьСтроку() = 1 Цикл
    Операция.НоваяКорреспонденция();
    Операция.Кредит.Счет = ТЗ_Затраты.СчетЗатрат;
    Операция.Кредит.Субконто(1, ТЗ_Затраты.Субконто1);
    Операция.Кредит.Субконто(2, ТЗ_Затраты.Субконто2);
    Операция.Кредит.Субконто(3, ТЗ_Затраты.Субконто3);
    Операция.Количество = ТЗ_Затраты.Количество;
    Операция.Сумма = ТЗ_Затраты.Сумма;
    Операция.Содержание = "Списаны затраты (" + СокрЛП(ТЗ_Затраты.Субконто2) + ")";
КонецЦикла;

Операция.Записать();

Решение 2: Отказ от сложных проводок в пользу промежуточного счета

Рассмотрим альтернативный архитектурный подход. Механизм сложных проводок в 1С 7.7 чувствителен к округлениям копеек и усложняет выборку данных объектом БухгалтерскиеИтоги при анализе корреспонденций. Во многих типовых конфигурациях и прикладных решениях рекомендуется разделять списание и оприходование на простые проводки с использованием счета учета затрат или вспомогательного транзитного счета.

Разберем классическую производственную схему:

  1. Списание сырья и материалов в производство: формируются стандартные простые проводки вида Дт 20 (23) — Кт 10 (28) на каждый материал отдельно. При этом корректно списывается количество каждого материала и формируются затраты на производственном счете.
  2. Оприходование готовой продукции: отдельной простой проводкой отражается выпуск вида Дт 40 (26, 28) — Кт 20 (23) на итоговое количество продукции по плановой или фактической себестоимости.

Посмотрим на схему через вспомогательный транзитный счет (если учет ведется в рамках одного документа без использования 20 счета):


// Списание компонентов на промежуточный транзитный счет (например, 00)
ВыбратьСтроки();
Пока ПолучитьСтроку() = 1 Цикл
    Операция.НоваяПроводка();
    Операция.Дебет.Счет = СчетТранзитный;
    Операция.Кредит.Счет = СчетЗатрат;
    Операция.Кредит.Субконто(1, МестоХранения);
    Операция.Кредит.Субконто(2, Затрата);
    Операция.Кредит.Субконто(3, Партия);
    Операция.Количество = Кво;
    Операция.Сумма = Сумма;
    Операция.Содержание = "Списание компонента: " + СокрЛП(Затрата);
КонецЦикла;

// Оприходование готовой продукции с закрытием транзитного счета в ноль
Операция.НоваяПроводка();
Операция.Дебет.Счет = СчетВыпуска;
Операция.Дебет.Субконто(1, МестоХраненияПродукции);
Операция.Дебет.Субконто(2, Продукция);
Операция.Дебет.Субконто(3, ПартияПродукции);
Операция.Кредит.Счет = СчетТранзитный;
Операция.Количество = ИтогоКоличествоПродукции;
Операция.Сумма = Итог("Сумма");
Операция.Содержание = "Оприходование готовой продукции";

Операция.Записать();

Такой подход исключает ошибки формирования сложной структуры операций и гарантирует корректный расчет количественных остатков на складах.

← На главную