Почему добавление поля СуммаОборот делает запрос к Хозрасчетный.ОборотыДтКт пустым?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием Бухгалтерский учет IT и автоматизация бизнеса
← На главную

Каждый разработчик 1С рано или поздно сталкивается со странным поведением запросов: когда мы выбираем только аналитику (например, номенклатуру или контрагента), запрос отрабатывает корректно и выводит строки. Но стоит нам добавить в список выбора числовой ресурс, такой как СуммаОборот, СуммаОборотДт или СуммаОборотКт, как весь результат запроса внезапно становится абсолютно пустым. В этой статье мы подробно разберем, почему так происходит, и рассмотрим все возможные причины — от методологии учета до глубоких технических нюансов платформы "1С:Предприятие".

Причина 1. Особенности партионного учета и отсутствие расчета себестоимости

В современных конфигурациях 1С (таких как 1С:ERP Управление предприятием или 1С:Комплексная автоматизация) учет устроен сложнее, чем в классической "1С:Бухгалтерии". При проведении документов оперативного учета (например, реализаций, отчетов производства, выпусков продукции) в течение месяца система фиксирует только количественные движения и аналитику.

Суммовая оценка (себестоимость) на счетах учета затрат и готовой продукции (например, счета 43 "Готовая продукция", 90 "Продажи", 20 "Основное производство") рассчитывается и записывается в регистры только при выполнении регламентной процедуры "Закрытие месяца" с помощью документа "Расчет себестоимости товаров". Если этот документ за выбранный период еще не проведен или проведен с ошибками:

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

Проверим эту гипотезу. Нам нужно открыть отчет "Ведомость по партиям товаров" или проверить проводки первичных документов. Если суммовые проводки отсутствуют, необходимо запустить процедуру закрытия месяца и рассчитать себестоимость.

Причина 2. Настройка признака «Суммовой» в Плане счетов

Давайте проанализируем настройки плана счетов в вашей конфигурации. Для каждого счета и каждого прикрепленного к нему субконто (вида аналитики) в системе существует специальный признак — флаг "Суммовой". Он определяет, будет ли платформа накапливать и хранить суммовые итоги в разрезе данного субконто.

Если для счета 43 или счета 90 по субконто "Номенклатура" этот признак по какой-то причине снят (или был изменен в процессе кастомизации конфигурации):

  1. Количество и сама ссылка на номенклатуру будут сохраняться в движениях.
  2. Физическая таблица итогов регистра бухгалтерии не будет содержать сумм в разрезе этого субконто.
  3. Виртуальная таблица ОборотыДтКт, оптимизированная для работы с итогами, при попытке "склеить" несуммовое субконто с ресурсом СуммаОборот вернет пустое множество строк.

Чтобы исключить эту проблему, откроем План счетов в конфигураторе или в режиме "1С:Предприятие" и убедимся, что для проверяемых счетов у субконто "Номенклатура" установлена галочка "Суммовой".

Причина 3. Ограничение прав доступа на уровне записей (RLS)

Еще одна неочевидная техническая причина — работа механизма безопасности RLS (Record Level Security). В 1С права доступа могут быть настроены очень гибко: у пользователя могут быть полные права на чтение справочника "Номенклатура", но при этом наложены жесткие ограничения на просмотр финансовых показателей (сумм) по определенным организациям, подразделениям или группам доступа.

Когда мы выполняем запрос без суммовых полей, система безопасности пропускает записи, так как мы запрашиваем только разрешенную аналитику. Но как только в конструкцию ВЫБРАТЬ добавляется поле СуммаОборот, RLS динамически модифицирует SQL-запрос на уровне СУБД, добавляя условия фильтрации. Если у текущего пользователя нет прав на просмотр сумм по данным аналитикам, система безопасности просто отсекает эти строки, делая выборку пустой.

Для проверки запустим этот же запрос под учетной записью с Полными правами (у администратора RLS обычно отключен). Если под полными правами данные успешно выводятся, проблему следует искать в настройках профилей групп доступа.

Причина 4. Проблемы с актуальностью и использованием итогов регистра

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

Выясним состояние итогов регистра. Для этого мы можем воспользоваться встроенной обработкой "Управление итогами" или выполнить пересчет программно:


РегистрыБухгалтерии.Хозрасчетный.УстановитьИспользованиеИтогов(Истина);
РегистрыБухгалтерии.Хозрасчетный.ПересчитатьИтоги();

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

Причина 5. Неверная передача параметров периода (Граница)

Очень часто документы, формирующие окончательную себестоимость (например, регламентные операции закрытия месяца), записываются последней секундой дня или даже последней секундой месяца со временем 23:59:59. Если в параметрах виртуальной таблицы в качестве конечной даты передается просто значение типа Дата (например, &Дата2 со значением 31.12.2023 23:59:59), то документы, записанные ровно в эту секунду, могут не попасть в выборку из-за особенностей сравнения дат на уровне СУБД.

Чтобы гарантированно включить все движения конца периода, рекомендуется использовать объект Граница с типом ВидГраницы.Включая. Рассмотрим пример правильной установки параметров в коде 1С:


КонецПериодаЗапроса = Новый Граница(КонецДня(КонечнаяДата), ВидГраницы.Включая);
Запрос.УстановитьПараметр("Дата1", НачалоПериода);
Запрос.УстановитьПараметр("Дата2", КонецПериодаЗапроса);

Это исключит ситуации, когда "пограничные" регламентные документы себестоимости выпадают из нашего отчета.

Причина 6. Неверное указание номера субконто

Давайте обратим внимание на конструкцию запроса автора из первого сообщения:


ВЫБРАТЬ
    ВЫРАЗИТЬ(ХозрасчетныйОборотыДтКт.СубконтоКт1 КАК Справочник.Номенклатура) КАК Номенклатура,
    ХозрасчетныйОборотыДтКт.СуммаОборот КАК Себестоимость

Здесь используется обращение к СубконтоКт1. Однако в процессе разработки или обновления конфигурации порядок субконто на счетах может измениться. Например, на счете 43 "Номенклатура" может стать вторым субконто (СубконтоКт2), а на первом месте окажется "Склады" или "Организации".

Если мы жестко запрашиваем СубконтоКт1 и пытаемся выразить его как Справочник.Номенклатура, а там фактически находится другой справочник (например, Справочник.Склады):

  1. Функция ВЫРАЗИТЬ вернет значение NULL, так как тип значения субконто не совпадает с целевым типом.
  2. При соединении таблиц на уровне СУБД, если накладываются жесткие условия, или при попытке рассчитать обороты в разрезе несовпадающих типов данных, вся строка может быть исключена из результирующей выборки.

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

Причина 7. Использование функции ЕСТЬNULL

В ходе обсуждения предлагалось использовать функцию ЕСТЬNULL для числовых значений:

ЕСТЬNULL(ХозрасчетныйОборотыДтКт.СуммаОборот, 0) КАК Себестоимость

Проанализируем эту рекомендацию. Функция ЕСТЬNULL заменяет значение NULL на указанное дефолтное значение (в данном случае 0). Но важно понимать природу появления NULL. Данное значение возникает в результате левого или правого соединения таблиц, когда в правой таблице нет соответствующей записи. В случае использования виртуальной таблицы ОборотыДтКт без внешних соединений, если запрос возвращает пустой результат, то применение ЕСТЬNULL никак не поможет вернуть строки. Строк просто нет физически в выборке, и заменять NULL не в чем. Поэтому проблема кроется глубже — в отсутствии самих записей, удовлетворяющих условиям отбора запроса.

Резюме и чеклист для решения проблемы

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

  1. Проверьте проведение регламентных документов. Убедитесь, что за запрашиваемый период выполнено закрытие месяца и рассчитана себестоимость. Зайдите в проводки любого документа выпуска/реализации и посмотрите, заполнен ли ресурс "Сумма".
  2. Проверьте типы и индексы субконто. Убедитесь, что номенклатура действительно является первым субконто (Субконто1) на используемых счетах дебета или кредита.
  3. Запустите запрос под полными правами. Исключите влияние механизма RLS, ограничивающего доступ к финансовым показателям.
  4. Проверьте актуальность итогов. Выполните полный пересчет итогов регистра бухгалтерии через стандартные административные функции.
  5. Используйте объект Граница. Убедитесь, что параметры начала и конца периода передаются корректно, включая крайние секунды периода.
← На главную