Почему запрос к виртуальной таблице оборотов в 1С возвращает пустой результат?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Сфера услуг, туризм и социальный сектор
← На главную

При разработке отчетов или обработок на платформе 1С:Предприятие 8 часто возникает задача выборки данных из виртуальных таблиц накопления, таких как Обороты. Иногда разработчики сталкиваются с ситуацией, когда запрос, логически построенный верно, возвращает пустой результат. Давайте разберем, почему это происходит и как правильно настроить запрос для получения списка «новых» клиентов.

Причины некорректной работы запроса

Основная причина, по которой виртуальная таблица может возвращать пустое поле, заключается в особенностях оптимизации платформы 1С. Когда вы выбираете из таблицы только Измерения (например, Контрагент) и не выбираете ни одного Ресурса (например, КоличествоОборот или СуммаОборот), система может исключить записи из выборки. Это происходит потому, что без наличия числового показателя механизм трансляции запроса в SQL-код может ошибочно интерпретировать наличие данных, «схлопывая» записи или фильтруя их как пустые.

Разбор решения: добавление ресурсов в запрос

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

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

Шаг 1: Получаем список клиентов за прошлый период

Сначала сформируем список «старых» клиентов, которые уже получали услуги до начала интересующего нас периода. Для этого используем ВТ_СтарыеПациенты.


ВЫБРАТЬ
    Обороты.Контрагент КАК Контр,
    Обороты.КоличествоОборот КАК Количество -- Добавляем ресурс для корректной работы
ПОМЕСТИТЬ ВТ_СтарыеПациенты
ИЗ
    РегистрНакопления.ОказанныеУслуги.Обороты(, &НачалоПериода, , ) КАК Обороты
;

Шаг 2: Выявляем новых клиентов через левое соединение

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


ВЫБРАТЬ
    НовыеПац.Контрагент КАК Контрагент,
    ВЫБОР
        КОГДА СтарыеПациенты.Контр ЕСТЬ NULL
            ТОГДА 1
        ИНАЧЕ 0
    КОНЕЦ КАК НовыеКлиенты
ИЗ
    РегистрНакопления.ОказанныеУслуги.Обороты(&НачалоПериода, &КонецПериода, , ) КАК НовыеПац
        ЛЕВОЕ СОЕДИНЕНИЕ ВТ_СтарыеПациенты КАК СтарыеПациенты
        ПО НовыеПац.Контрагент = СтарыеПациенты.Контр
ГДЕ
    СтарыеПациенты.Контр ЕСТЬ NULL

Важные советы по отладке

Чтобы работа с запросами в 1С была предсказуемой и эффективной, рекомендуем придерживаться следующих правил:

  1. Используйте консоль запросов: Если запрос в СКД не дает данных, первым делом переносите код в консоль запросов. Если в консоли результат есть, значит, проблема кроется в настройках СКД (например, в параметрах периодов или связях наборов данных).
  2. Проверяйте параметры: В СКД система может автоматически накладывать НачалоПериода и КонецПериода на все наборы данных. Если вам нужно, чтобы один набор данных охватывал всю историю, а другой — только часть, возможно, потребуется отключить авто-периоды в настройках набора данных.
  3. Используйте функцию ЕСТЬNULL: Для чистоты кода и повышения производительности вместо конструкции ВЫБОР КОГДА ... ЕСТЬ NULL ТОГДА 1 ИНАЧЕ 0 применяйте встроенную функцию ЕСТЬNULL(Поле, Значение).
  4. Оптимизация: Если задача поиска «новичков» стоит часто и данных очень много, рассмотрите вариант использования РегистрСведений, куда записывается дата первой услуги для каждого клиента. Это избавит вас от тяжелых вычислений оборотов при каждом формировании отчета.

Следуя этим рекомендациям, вы сможете эффективно выявлять новых клиентов и избегать распространенных ошибок при работе с виртуальными таблицами 1С.

← На главную