Почему БухгалтерскиеИтоги возвращают неверный дебетовый оборот в 1С 7.7?

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

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

Анализ проблемы: неявное приведение типов в параметрах запроса

Рассмотрим пример кода, в котором возникает ошибка расчета дебетового оборота по конкретному счету и контрагенту:


Ит = СоздатьОбъект("БухгалтерскиеИтоги");
Ит.ИспользоватьСубконто(ВидыСубконто.Контрагенты, ВыбОрг, 1);
Ит.ВыполнитьЗапрос(НачДата, КонДата, 63.1,,, 1,, "С");
Ит.ВыбратьСубконто(ВидыСубконто.Контрагенты);
Пока Ит.ПолучитьСубконто(ВидыСубконто.Контрагенты) = 1 Цикл
    Контрагент = Ит.Субконто();
    Сумма = Ит.ДО();
    Сообщить("Сумма оборота " + Сумма);
КонецЦикла;

В приведенном коде в метод ВыполнитьЗапрос счет передан как число с плавающей точкой — 63.1. Выясним причину, почему это приводит к неверным результатам:

  1. Ожидаемые типы параметра счета: Третий параметр метода ВыполнитьЗапрос() платформы 1С 7.7 ожидает значение типа Счет, Строка (код счета или маска) либо СписокЗначений (содержащий список счетов или кодов).
  2. «Проглатывание» некорректного типа: Если передать число (например, 63.1), платформа не вызывает синтаксическую ошибку или исключение времени выполнения, а неявно воспринимает данный параметр как пустой (незаданный).
  3. Смешивание оборотов по плану счетов: Когда фильтр по счету не сработал, расчет итогов строится по всему плану счетов в целом. В результате метод Ит.ДО() возвращает суммарный дебетовый оборот по выбранному контрагенту со всех счетов, где прикреплен данный вид субконто (например, счетов учета расчетов с поставщиками, покупателями, авансов или учета НДС). Это создает иллюзию того, что в дебетовый оборот попали чужие или кредитовые проводки.

Способы исправления ошибки

Для корректного расчета итогов по конкретному счету необходимо явно указать код счета в виде строки или передать объект счета. Разберем правильные варианты синтаксиса.

Вариант 1: Передача кода счета строкой в кавычках

Самое простое и надежное исправление — взять код счета в двойные кавычки:


Ит = СоздатьОбъект("БухгалтерскиеИтоги");
Ит.ИспользоватьСубконто(ВидыСубконто.Контрагенты, ВыбОрг, 1);
Ит.ВыполнитьЗапрос(НачДата, КонДата, "63.1",,, 1,, "С");
Ит.ВыбратьСубконто(ВидыСубконто.Контрагенты);
Пока Ит.ПолучитьСубконто(ВидыСубконто.Контрагенты) = 1 Цикл
    Контрагент = Ит.Субконто();
    Сумма = Ит.ДО();
    Сообщить("Сумма оборота " + Сумма);
КонецЦикла;

Вариант 2: Получение объекта счета через функцию СчетПоКоду()

Если план счетов формируется динамически или требуется дополнительная проверка существования счета в конфигурации, рекомендуется использовать функцию СчетПоКоду():


СчетУчета = СчетПоКоду("63.1");
Если ПустоеЗначение(СчетУчета) = 0 Тогда
    Ит = СоздатьОбъект("БухгалтерскиеИтоги");
    Ит.ИспользоватьСубконто(ВидыСубконто.Контрагенты, ВыбОрг, 1);
    Ит.ВыполнитьЗапрос(НачДата, КонДата, СчетУчета,,, 1,, "С");
    // Обработка результатов запроса
КонецЕсли;

Оптимизация отбора по субконто

Проанализируем еще одну частую неточность при работе с методом ИспользоватьСубконто(). Если требуется получить оборот по одному конкретному контрагенту (значение ВыбОрг уже известно), нет необходимости разворачивать итоги и обходить их в цикле.

Рассмотрим значения третьего параметра метода ИспользоватьСубконто(<ВидСубконто>, <Значение>, <ТипОтбора>):

  1. Значение 1: Выполняется разворот по субконто (выборка всех элементов и групп). Требует последующего вызова методов ВыбратьСубконто() и ПолучитьСубконто().
  2. Значение 2: Устанавливается жесткий фильтр только по переданному значению субконто. Это ускоряет выполнение запроса и позволяет сразу обращаться к итогам без открытия выборки и цикла.

Посмотрим на пример оптимального кода для получения дебетового оборота по конкретному объекту:


Ит = СоздатьОбъект("БухгалтерскиеИтоги");
// Устанавливаем фильтр по конкретному субконто (тип отбора = 2)
Ит.ИспользоватьСубконто(ВидыСубконто.Контрагенты, ВыбОрг, 2);
Ит.ВыполнитьЗапрос(НачДата, КонДата, "63.1",,, 1,, "С");

// Обороты доступны сразу без выборки по субконто
СуммаДебета = Ит.ДО();
Сообщить("Дебетовый оборот по контрагенту: " + СуммаДебета);

Таким образом, для получения корректных данных в объекте БухгалтерскиеИтоги всегда проверяйте тип передаваемого счета (он должен быть строкой "63.1" или объектом типа Счет) и корректно задавайте режим отбора субконто.

← На главную