Как в СКД скрыть расчет по пустой строке, оптимизировать условия ИЛИ и настроить заголовки колонок со спецсимволами

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

При разработке отчетов на схеме компоновки данных (СКД) программисты часто сталкиваются с необходимостью тонкой настройки вывода строк и оформления таблиц. Типичная задача — исключить проведение расчетов по строкам, в которых ключевые показатели не заполнены, а также сделать так, чтобы вместо некрасивых нулей или пустых значений в отчете оставалась аккуратная пустая ячейка. При этом важно не перегружать СУБД тяжелыми и неоптимальными запросами с обилием условий.

В этой статье мы подробно разберем, как решить проблему обнуления строк в СКД, проанализируем, почему стандартный оператор ИЛИ замедляет работу системы, и рассмотрим профессиональные методы обхода этой проблемы. Также мы выясним, как правильно присваивать колонкам произвольные имена, содержащие цифры и спецсимволы (например, знак процента «%»).

Способ 1. Исключение расчета пустых строк через конструкцию ВЫБОР КОГДА в запросе

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

Для того чтобы обойти эту проблему непосредственно в тексте запроса, мы можем использовать развернутое ветвление логики. Проанализируем пример кода, который решает эту задачу «в лоб»:


ВЫБОР
    КОГДА СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам = НЕОПРЕДЕЛЕНО
        ИЛИ СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам ЕСТЬ NULL
        ИЛИ СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам = 0
        ИЛИ СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам = ""
    ТОГДА 0
    ИНАЧЕ "Расчет"
КОНЕЦ КАК ДоплатаШахтерам

Этот код успешно работает и решает задачу: если поле не заполнено или равно нулю, система вернет 0 (или пустую строку в зависимости от бизнес-логики), иначе будет произведен требуемый алгоритм расчета. Однако такое нагромождение условий делает запрос громоздким и трудночитаемым. Давайте разберем более изящные альтернативы, которые предоставляет нам платформа 1С.

Способ 2. Оптимальная обработка пустых значений через ЕСТЬNULL

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

Посмотрим, как сократится наше условие, если мы предварительно обработаем поле:


ВЫБОР
    КОГДА ЕСТЬNULL(СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам, 0) = 0
    ТОГДА 0
    ИНАЧЕ "Расчет"
КОНЕЦ КАК ДоплатаШахтерам

Использование ЕСТЬNULL автоматически решает проблему отсутствующих связей в виртуальных или физических таблицах (когда СУБД возвращает NULL). Нам остается лишь сравнить полученный результат с нулем. Этот код значительно чище, проще в поддержке и работает быстрее.

Способ 3. Визуальное сокрытие нулей через условное оформление СКД

Если данные по строке физически необходимы в запросе и должны участвовать в расчете общих итогов по отчету, но при этом на экране вместо нулей нужно отобразить пустые ячейки, лучшим решением будет использование механизма Условного оформления СКД. Это позволит нам не писать лишний код в запросе и сохранить чистоту архитектуры.

Разберем по шагам, как настроить визуальное сокрытие пустых строк:

  1. Откройте схему компоновки данных вашего отчета и перейдите на вкладку «Настройки».
  2. В нижней части экрана выберите вкладку «Условное оформление» и нажмите кнопку «Добавить».
  3. В появившемся окне найдите параметр «Формат». Нажмите на многоточие и в конструкторе форматной строки задайте формат для вывода чисел. Например, укажите форматную строку вида ЧГ=0 или настройте параметр «Представление нуля» как пустую строку (пробел). Также можно использовать параметр «Текст», указав в его значении пустую строку, чтобы принудительно очистить ячейку при выполнении условий.
  4. Перейдите на вкладку «Условие». Добавьте новое условие сравнения. Выберите ваше расчетное поле (например, ДоплатаШахтерам) и укажите вид сравнения «Равно», а в качестве значения укажите 0. Также можно добавить дополнительное условие на НЕОПРЕДЕЛЕНО или NULL, если эти типы данных могут пробиваться в результат.
  5. Перейдите на вкладку «Оформляемые поля». Добавьте туда поле вашего расчета. Таким образом, оформление применится целенаправленно только к этой колонке, не затрагивая другие показатели отчета.

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

Способ 4. Системный отбор «Заполнено» на уровне настроек компоновки

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

Платформа 1С предоставляет мощный встроенный инструмент — вид сравнения «Заполнено» (и его противоположность — «Не заполнено»). Этот системный отбор на уровне платформы корректно обрабатывает все типы данных:

Просто добавьте в список отборов вашего отчета поле ПФРНаДоплатуШахтерам с видом сравнения «Заполнено». СКД самостоятельно модифицирует результирующий SQL-запрос, оптимизировав его под конкретную СУБД.

Оптимизация запроса: почему оператор ИЛИ — это скрытая угроза производительности

Выясним причину, почему опытные разработчики настоятельно рекомендуют избегать оператора ИЛИ в запросах 1С, особенно в секциях ГДЕ и в условиях соединения таблиц (ПО).

Когда СУБД (будь то Microsoft SQL Server, PostgreSQL или Oracle) строит план выполнения запроса, она пытается использовать заранее созданные индексы для ускорения поиска данных. Если в условии поиска присутствует оператор ИЛИ, связывающий разные поля или разнородные условия, оптимизатор СУБД зачастую не может построить эффективный план с использованием поиска по индексу (Index Seek). Вместо этого СУБД переходит к полному сканированию всей таблицы или индекса (Table Scan / Index Scan).

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

Как правильно оптимизировать ИЛИ в запросах 1С

Существует несколько проверенных методологических подходов к замене неоптимального оператора ИЛИ.

Вариант А: Использование конструкции ИСТИНА В (...) в блоке ВЫБОР КОГДА

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


ВЫБОР
    КОГДА ИСТИНА В (
        СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам = НЕОПРЕДЕЛЕНО,
        СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам ЕСТЬ NULL,
        СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам = 0,
        СтраховыеВзносыПоФизическимЛицам.ПФРНаДоплатуШахтерам = ""
    )
    ТОГДА 0
    ИНАЧЕ "Расчет"
КОНЕЦ КАК ДоплатаШахтерам

Такой синтаксис делает код приятным для чтения, избавляя от визуального шума. При этом СУБД обрабатывает такие конструкции более предсказуемо.

Вариант Б: Замена ИЛИ на ОБЪЕДИНИТЬ ВСЕ в секции ГДЕ

Если неоптимальное условие ИЛИ находится в секции фильтрации данных (например, нам нужно выбрать документы, где либо склад соответствует параметру, либо подразделение равно выбранному значению), то стандарты разработки 1С предписывают разбивать один тяжелый запрос на несколько простых, объединяя их результаты через оператор ОБЪЕДИНИТЬ ВСЕ.

Посмотрим на классический неоптимальный пример:


ВЫБРАТЬ Ссылка ИЗ Документ.РеализацияТоваровУслуг
ГДЕ Склад = &Склад ИЛИ Подразделение = &Подразделение

А теперь проанализируем, как будет выглядеть оптимизированный вариант:


ВЫБРАТЬ Ссылка ИЗ Документ.РеализацияТоваровУслуг ГДЕ Склад = &Склад
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ Ссылка ИЗ Документ.РеализацияТоваровУслуг ГДЕ Подразделение = &Подразделение И НЕ (Склад = &Склад)

В оптимизированном варианте каждый из двух запросов будет выполняться СУБД независимо и использовать свой выделенный индекс по полям Склад и Подразделение. Скорость выполнения такого пакета на больших базах данных будет на порядки выше, чем у исходного запроса с оператором ИЛИ.

Как обойти ограничения на спецсимволы в названиях колонок отчета

Еще одна частая проблема — необходимость назвать колонку в отчете понятным языком, например, «Доплата шахтерам 6%». Попытка прописать такой псевдоним непосредственно в тексте запроса через конструкцию КАК [Доплата шахтерам 6%] или в кавычках приведет к синтаксической ошибке.

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

Для решения этой проблемы мы можем использовать два штатных пути в рамках СКД.

Решение 1. Установка заголовка на уровне схемы данных (глобальный метод)

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

  1. Откройте конструктор схемы компоновки данных и перейдите на вкладку «Наборы данных».
  2. Найдите в таблице полей ваше расчетное поле (например, по пути к данным ДоплатаШахтерам).
  3. Обратите внимание на колонку «Заголовок» (не путайте с колонкой «Поле» или «Путь к данным»!).
  4. Дважды кликните по этой ячейке и введите любой произвольный текст, включая пробелы, цифры и спецсимволы: Доплата шахтерам 6%.

При формировании отчета система автоматически подставит это значение в шапку таблицы, сохранив техническое имя поля для внутренних расчетов.

Решение 2. Локальная настройка заголовка в структуре отчета

Если вам нужно переименовать поле только для определенного варианта отчета или в пользовательском режиме (без изменения конфигурации в конфигураторе):

  1. Перейдите на вкладку «Настройки» в схеме компоновки данных.
  2. В окне «Выбранные поля» найдите нужное вам поле.
  3. Нажмите по нему правой кнопкой мыши и выберите пункт меню «Установить заголовок».
  4. В открывшемся окне введите текст Доплата шахтерам 6% и нажмите «ОК».

Этот заголовок переопределит имя колонки для текущего варианта отчета. Этот метод также доступен продвинутым пользователям непосредственно в режиме «1С:Предприятие» при изменении настроек отчета.

← На главную