При разработке сложных отчетов на платформе 1С:Предприятие программисты часто сталкиваются с ситуацией, когда результаты запроса, полученные напрямую из виртуальных таблиц регистра бухгалтерии, отличаются от результатов, полученных через промежуточное сохранение данных во временную таблицу. Особенно остро эта проблема проявляется при использовании конструкции ИТОГИ. Давайте подробно разберем, почему «плывут» цифры, куда исчезает дебетовый остаток и как правильно организовать выборку данных, чтобы избежать ошибок в бухгалтерской отчетности.
Проанализируем механизм работы виртуальных таблиц, таких как ОстаткиИОбороты. Когда мы обращаемся к ним напрямую, платформа 1С задействует внутренние оптимизированные алгоритмы расчета. Эти алгоритмы «знают» о природе бухгалтерских счетов: является ли счет активным, пассивным или активно-пассивным. Система автоматически выполняет сворачивание сальдо на уровне итогов.
Как только мы помещаем результат выборки во временную таблицу (ВТ), данные превращаются в обычный «плоский» набор записей. Для системы это теперь просто числа в колонках СуммаНачальныйОстатокДт и СуммаНачальныйОстатокКт. При выполнении команды ИТОГИ во втором запросе (из ВТ), платформа применяет обычное математическое суммирование. Рассмотрим ситуацию на примере:
Представим, что у нас есть две записи по одному счету в разных аналитиках:
В виртуальной таблице регистра при группировке по счету система выдаст итог: Дебет 20 руб.. Однако, если эти записи попали в ВТ как две строки, то при расчете итогов из ВТ система просто сложит колонки и выдаст: Дебет 100 руб. и Кредит 80 руб. одновременно. Это методически неверно для бухгалтерского учета, где сальдо должно быть свернутым.
Выясним причину изменения знака и «перетекания» сумм из Дебета в Кредит. На активно-пассивных счетах остаток определяется разницей между дебетовыми и кредитовыми оборотами. В виртуальных таблицах 1С гарантирует, что остаток будет положительным и окажется в правильной колонке. Во временной таблице механизм автоматического «переброса» суммы из одной колонки в другую при смене знака отсутствует.
Если в результате математического сложения в колонке СуммаНачальныйОстатокДт получается отрицательное число, платформа в блоке ИТОГИ не перенесет его в Кредит с положительным знаком. Это и приводит к эффекту «плывущих» цифр, когда бухгалтер видит отрицательные остатки там, где их быть не должно.
Рассмотрим самый простой способ решения проблемы — получение итогов непосредственно из первоисточника. Если логика формирования отчета позволяет, старайтесь рассчитывать ИТОГИ в том же запросе, который обращается к виртуальной таблице ОстаткиИОбороты или Остатки.
Если же промежуточная таблица необходима для расчетов (например, для вычитания сумм по определенным условиям), попробуйте заменить временную таблицу на вложенный запрос внутри основного запроса. В некоторых случаях это позволяет платформе лучше оптимизировать план запроса и сохранить контекст расчета итогов.
Если использование временной таблицы неизбежно, нам необходимо самостоятельно эмулировать поведение бухгалтерского регистра. Разберем по шагам, как это сделать:
ВЫБОР.Посмотрим на пример кода, который решает проблему математического сложения:
// Первый этап: помещаем данные в ВТ, превращая Дт и Кт в единое число
ВЫБРАТЬ
Счет,
Субконто1,
СуммаНачальныйОстатокДт - СуммаНачальныйОстатокКт КАК СальдоНачальноеРазвернутое
ПОМЕСТИТЬ ВТ_БухДанные
ИЗ
РегистрБухгалтерии.Хозрасчетный.ОстаткиИОбороты(&Период, , , , , , ) КАК ОстаткиИОбороты;
// Второй этап: правильно рассчитываем итоги с проверкой знака
ВЫБРАТЬ
Счет,
СУММА(СальдоНачальноеРазвернутое) КАК ОбщееСальдо,
ВЫБОР
КОГДА СУММА(СальдоНачальноеРазвернутое) > 0 ТОГДА СУММА(СальдоНачальноеРазвернутое)
ИНАЧЕ 0
КОНЕЦ КАК СуммаНачальныйОстатокДт,
ВЫБОР
КОГДА СУММА(СальдоНачальноеРазвернутое) < 0 ТОГДА -СУММА(СальдоНачальноеРазвернутое)
ИНАЧЕ 0
КОНЕЦ КАК СуммаНачальныйОстатокКт
ИЗ
ВТ_БухДанные КАК Данные
СГРУППИРОВАТЬ ПО
Счет
ИТОГИ
СУММА(СуммаНачальныйОстатокДт),
СУММА(СуммаНачальныйОстатокКт)
ПО
ОБЩИЕ,
Счет;
В данном примере мы гарантируем, что на уровне группировки Счет суммы будут корректно распределены между колонками Дт и Кт в зависимости от итогового знака разницы.
Проанализируем ситуацию с точки зрения использования СКД. Система компоновки данных гораздо эффективнее справляется с расчетом итогов по бухгалтерским регистрам, даже если данные получены из временных таблиц.
Чтобы итоги не «плыли» в СКД, выполните следующие настройки:
В этом случае СКД сама применит бухгалтерские алгоритмы сворачивания сальдо при расчете итогов по группировкам и иерархии, что избавит вас от необходимости писать сложные конструкции ВЫБОР в тексте запроса.
Стоит отметить, что в старых релизах платформы (например, ветка 8.3.10) наблюдались специфические ошибки при работе механизма ИТОГИ с индексированными временными таблицами. Если вы столкнулись с тем, что данные удваиваются или пропадают при наличии индекса в ВТ, попробуйте временно отказаться от индексации или обновить платформу до актуальной версии (рекомендуется 8.3.20+).
Также важно всегда использовать функцию ЕСТЬNULL(Поле, 0) при выполнении арифметических операций во временных таблицах. Наличие NULL в числовых полях может привести к тому, что агрегатные функции в блоке ИТОГИ вернут пустой результат вместо суммы.
Подводя итог, можно сказать: основная проблема «плывущих» цифр — это потеря интеллектуальных механизмов виртуальных таблиц регистра при переходе к плоским временным таблицам. Используйте ручное вычисление развернутого сальдо или возможности СКД, чтобы ваши отчеты всегда показывали достоверные данные.