При разработке отчетов и обработок в среде «1С:Предприятие 7.7» разработчики нередко сталкиваются с ситуацией, когда объект БухгалтерскиеИтоги возвращает нулевые или пустые суммы по отдельным субконто. Типичный пример: на счете ведется количественный учет (например, счет 41 «Товары»), где первое субконто «Номенклатура» ведется по сумме и количеству, а второе субконто «Места хранения» (Склады) — только по количеству без флага учета по сумме. Другой частый случай — использование на субконто признака «Только обороты».
Попытки получить сальдо с помощью стандартных методов СКД(), СНК() или управление выборкой через БИ.Опции() в таких случаях не дают результата. Разберем внутренние механизмы платформы «1С 7.7» и выясним, как программно получить нужные данные без изменения структуры плана счетов.
Выясним причину, почему стандартные методы не возвращают значения:
СКД("С"), СНД("С"), СКК("С") возвращают 0, так как этих записей нет в базе данных.БИ.Опции() предназначен для управления группировками, сортировкой и включением счетов без движений, но он не может принудительно восстановить отсутствующие в регистрах агрегированные итоги.Рассмотрим распространенную задачу: на счете 41 первое субконто («Номенклатура») имеет признак «Учет по сумме», а второе («Склады») — только количественный. Нам требуется узнать оценочную стоимость остатка номенклатуры на конкретном складе.
Поскольку суммовой остаток по складу не ведется, его можно рассчитать расчетным путем через среднюю себестоимость позиции по организации в целом:
Посмотрим на пример реализации алгоритма на встроенном языке «1С 7.7»:
БИ = СоздатьОбъект("БухгалтерскиеИтоги");
БИ.ИспользоватьСубконто(ВидыСубконто.Номенклатура, ВыбНоменклатура, 2);
БИ.ИспользоватьСубконто(ВидыСубконто.МестаХранения, ВыбСклад, 2);
Если БИ.ВыполнитьЗапрос(ДатаНачала, ДатаКонца, "41.1") = 1 Тогда
Пока БИ.ПолучитьСубконто(1) = 1 Цикл
// Получаем общие остатки по номенклатуре в целом
КолВсего = БИ.СКД("К");
СуммаВсего = БИ.СКД("С");
СредняяЦена = 0;
Если КолВсего <> 0 Тогда
СредняяЦена = СуммаВсего / КолВсего;
КонецЕсли;
Пока БИ.ПолучитьСубконто(2) = 1 Цикл
// По второму субконто доступно только количество
КолНаСкладе = БИ.СКД("К");
// Рассчитываем сумму по складу программно
СуммаНаСкладе = Окр(КолНаСкладе * СредняяЦена, 2);
Сообщить("Склад: " + БИ.Субконто(2) + " | Остаток: " + КолНаСкладе + " | Сумма: " + СуммаНаСкладе);
КонецЦикла;
КонецЦикла;
КонецЕсли;
Проанализируем ситуацию, когда по субконто включен признак «Только обороты». В этом случае сальдо на начало и конец периода отсутствует, но в базе хранятся обороты (дебетовые и кредитовые движения).
Чтобы рассчитать виртуальный остаток на нужную дату без изменения настроек метаданных, выполним запрос по оборотам с самой ранней даты учета (даты ввода начальных остатков) по целевую дату:
БИ = СоздатьОбъект("БухгалтерскиеИтоги");
БИ.ИспользоватьСубконто(ВидыСубконто.СтатьиЗатрат, ВыбСтатья, 2);
// Выполняем запрос с даты старта базы по дату расчета
Если БИ.ВыполнитьЗапрос('01.01.1980', ДатаРасчета, СчетУчета) = 1 Тогда
Пока БИ.ПолучитьСубконто(1) = 1 Цикл
// Для активного счета сальдо рассчитывается как разница оборотов
РасчетныйОстаток = БИ.ДО("С") - БИ.КО("С");
Сообщить("Субконто: " + БИ.Субконто(1) + " | Расчетный остаток: " + РасчетныйОстаток);
КонецЦикла;
КонецЕсли;
Важный момент: Выборка оборотов за весь период существования информационной базы создает существенную нагрузку на СУБД при больших объемах данных, поэтому данный способ рекомендуется применять только для точечных отчетов или регламентных процедур.
Если требуется получить детализацию по суммам первичных документов, в которых участвовало конкретное аналитическое субконто, можно использовать обход проводок:
Операция или выборку проводок через ВыбратьПроводки().Сумма проводки в переменные расчетных итогов.Если в будущем конфигурация будет дорабатываться и в плане счетов будут включены флаги «Учет по сумме» или сняты признаки «Только обороты», помните важное системное правило платформы «1С 7.7»:
Обязательно выполните полный пересчет итогов: После изменения структуры учета в конфигураторе необходимо запустить «1С:Предприятие» в монопольном режиме, открыть меню Операции -> Управление бухгалтерскими итогами и запустить полный Пересчет бухгалтерских итогов. Без этого действия остатки прошлых периодов по новым аналитическим разрезам останутся нулевыми.