Почему в 1С 7.7 не выбирается КорСубконто через объект БухгалтерскиеИтоги и как это исправить

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

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

Анализ исходной проблемы в коде

Рассмотрим типовой фрагмент кода, в котором возникает ошибка обхода корреспондирующей аналитики:


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

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

Ключевые причины, почему не работает выборка корсубконто

  1. Несоответствие понятий сальдо и корреспонденции. Корреспондирующие счета и корреспондирующие субконто существуют только внутри проводок, то есть описывают обороты за период. Понятия «сальдо по корсубконто» или «остаток в разрезе корреспондирующего счета» в бухгалтерском учете и в структуре базы 1С 7.7 не существует. Если проверяется условие БИ.СКК() = 0, разработчик рассчитывает распределить остаток по счету на аналитику счета расчетов (например, расчетного счета). Но если за указанную дату (в примере с ДатаКон по ДатаКон) реальных проводок между дебетом 631 и кредитом 311 не было, оборот равен нулю, и выборка по корреспондирующим субконто всегда будет пустой.
  2. Неверный параметр типа итогов в методе ВыполнитьЗапрос. Сигнатура метода выглядит следующим образом: ВыполнитьЗапрос(<НачалоПериода>, <КонецПериода>, <Счет>, <КоррСчет>, <Валюта>, <ТипИтогов>, <Периодичность>, <ТипСуммы>). По умолчанию шестой параметр <ТипИтогов> равен 1 (расчет остатков и оборотов по счету в целом). В этом режиме платформа не рассчитывает матрицу перекрестных оборотов между счетами и субконто. Чтобы получить доступ к корреспонденциям, этот параметр обязательно должен принимать значение:
    • 2 — рассчитывать только обороты между счетами и субконто;
    • 3 — рассчитывать одновременно остатки, общие обороты по счету и развернутые обороты между счетами.
  3. Пропущен корреспондирующий счет в запросе. Переменная СчКт была определена в модуле, но четвертый параметр метода ВыполнитьЗапрос остался пустым. Если корсчет не зафиксирован на этапе запроса, для обхода корреспонденций платформа требует строгого соблюдения иерархии: сначала необходимо открыть выборку по корреспондирующим счетам через ВыбратьКорСчета() и ПолучитьКорСчет(), и только внутри нее обращаться к ВыбратьКорСубконто().
  4. Вызов ИспользоватьКорСубконто без параметров. В отличие от основного субконто, для корреспондирующей аналитики крайне рекомендуется явно передавать вид субконто: ИспользоватьКорСубконто(<ВидСубконто>, <Значение>, <ТипФильтра>). Вызов без параметров часто сбивает внутреннее позиционирование колонок выборки.
  5. Попытка получить сальдо на уровне корреспонденции. Внутри вложенного цикла выполняется вызов БИ.СКД(). На уровне корсчетов и корсубконто сальдовые функции не работают. Для считывания сумм оборотов необходимо использовать методы КорДО() (дебетовый оборот с корреспонденцией) или КорКО() (кредитовый оборот с корреспонденцией).

Способ 1. Корректная настройка объекта БухгалтерскиеИтоги

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


БИ = СоздатьОбъект("БухгалтерскиеИтоги");

// Явно задаем виды аналитики основного счета и признак разворота (1)
БИ.ИспользоватьСубконто(ВидыСубконто.Контрагенты, , 1);
БИ.ИспользоватьСубконто(ВидыСубконто.Договоры, , 1);

// Явно объявляем аналитику корреспондирующего счета
БИ.ИспользоватьКорСубконто(ВидыСубконто.БанковскиеСчета, , 1);

СчДт = СчетПоКоду("631");
СчКт = СчетПоКоду("311");

// Передаем СчКт (4-й параметр) и ТипИтогов = 3 (6-й параметр)
БИ.ВыполнитьЗапрос(ДатаНач, ДатаКон, СчДт, СчКт, , 3);

БИ.ВыбратьСубконто(1);
Пока БИ.ПолучитьСубконто(1) = 1 Цикл
    
    БИ.ВыбратьСубконто(2);
    Пока БИ.ПолучитьСубконто(2) = 1 Цикл
        
        // Переходим к корреспондирующей аналитике
        БИ.ВыбратьКорСубконто(1);
        Пока БИ.ПолучитьКорСубконто(1) = 1 Цикл
            
            // На уровне корсубконто получаем оборот корреспонденции:
            СуммаПроводки = БИ.КорДО();
            Если СуммаПроводки = 0 Тогда
                Продолжить;
            КонецЕсли;
            
            Опер.НоваяПроводка();
            Опер.Кредит.Счет = СчКт;
            Опер.Кредит.НашиДенежныеСчета = БИ.КорСубконто(1);
            
            Опер.Дебет.Счет = СчДт;
            Опер.Дебет.Контрагенты = БИ.Субконто(1);
            Опер.Дебет.Заказы = БИ.Субконто(2);
            Опер.Сумма = СуммаПроводки;
            
        КонецЦикла;
    КонецЦикла;
КонецЦикла;

Способ 2. Использование объекта Операция для прямого чтения проводок

Если требуется проанализировать движения за конкретный день или сформировать корректирующие проводки на основе уже существующих записей в журнале, гораздо проще и надежнее использовать объект Операция с методом ВыбратьОперацииСПроводками. Это избавляет от сложностей настройки матрицы итогов:


ОперВыборка = СоздатьОбъект("Операция");

// Отбираем все проводки между заданными счетами за период
ОперВыборка.ВыбратьОперацииСПроводками(ДатаКон, ДатаКон, СчДт, СчКт);

Пока ОперВыборка.ПолучитьПроводку() = 1 Цикл
    // Доступны значения аналитики напрямую из проводки
    ТекСубконтоДт1 = ОперВыборка.Дебет.Субконто(1);
    ТекСубконтоДт2 = ОперВыборка.Дебет.Субконто(2);
    ТекКорСубконто = ОперВыборка.Кредит.Субконто(1);
    СуммаОперации   = ОперВыборка.Сумма;
    
    // Выполняем требуемые действия с полученными значениями
КонецЦикла;

Такой подход исключает ошибки позиционирования в объекте БухгалтерскиеИтоги и дает прямой доступ ко всем реквизитам операции и проводки.

← На главную