Как в 1С выполнить отбор и группировку по диапазону нечисловых кодов

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

При разработке отчетов в системе 1С программисты часто сталкиваются с необходимостью классификации данных по строковым идентификаторам. Типичный пример — работа с кодами МКБ-10 (Международная классификация болезней), где коды имеют вид F20, E03.1, M0.1*. Основная сложность заключается в том, что стандартные механизмы работы с числами здесь не применимы, а обычное строковое сравнение может выдавать неожиданные результаты из-за особенностей лексикографического порядка.

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

Метод 1. Сравнение строковых диапазонов в запросе

Самый простой и очевидный способ — использование стандартных операторов сравнения (>=, <=) непосредственно к строковым полям. Поскольку коды МКБ-10 строятся по определенному стандарту (буква и цифры), они поддаются сравнению как обычные строки. Рассмотрим пример, когда нам нужно выбрать документы с кодами диагнозов в диапазоне от F00 до F45.

Проанализируем выражение для условия запроса:


|ГДЕ
|   Обращения.Диагноз.Код >= "F00"
|   И Обращения.Диагноз.Код <= "F45.9"

Почему мы добавляем .9 к конечной границе? Это важный нюанс строкового сравнения. Если мы укажем просто <= "F45", то код F45.1 уже не попадет в выборку, так как строка "F45.1" лексикографически длиннее и "больше", чем "F45". Добавление суффикса позволяет захватить все вложенные подпункты данной группы.

Метод 2. Группировка по маске и оператор ПОДОБНО

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


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

В данном примере функция ПОДСТРОКА выделяет первый символ кода (букву), что позволяет мгновенно получить статистику по крупным блокам заболеваний (все коды на "F", все на "M" и т.д.). Для более точечных выборок удобно применять оператор ПОДОБНО. Например, для выбора всех психических расстройств (коды F):

ГДЕ Диагноз.Код ПОДОБНО "F%"

Метод 3. Оптимизация через дополнительные реквизиты

Если отчеты по диапазонам строковых кодов строятся часто и на больших объемах данных, постоянное использование функций ПОДСТРОКА или сложных сравнений строк может существенно замедлить работу базы данных. Разберем профессиональный подход к архитектуре справочника.

Рекомендуется "обогатить" справочник диагнозов техническими реквизитами:

  1. БуквеннаяЧасть (Строка) — хранит только префикс (например, "F").
  2. ЦифроваяЧасть (Число) — хранит числовой код для точного сравнения.
  3. ПолныйКодДляСортировки (Строка) — нормализованный код, где числа дополнены ведущими нулями (например, F003.01 вместо F3.1).

При таком подходе запрос становится максимально быстрым, так как поиск идет по индексированным полям с фиксированной длиной или числам. Рассмотрим пример записи такого элемента:


Процедура ПередЗаписью(Отказ)
    // Пример примитивного парсинга для демонстрации идеи
    БуквеннаяЧасть = Лев(Код, 1);
    ЦифроваяЧасть = Число(Сред(Код, 2, 2)); 
    // Теперь в запросах можно легко делать отборы по диапазонам чисел
КонецПроцедуры

Метод 4. Классификация через иерархию или регистры

Если диапазоны кодов (например, "F20-F41.5") являются логическими группами, которые могут меняться со временем, не стоит "зашивать" их условия прямо в программный код. Выясним, как сделать решение гибким.

Вариант А: Использование иерархии справочника. Если ваш справочник диагнозов иерархический, создайте группы, соответствующие диапазонам. В запросе используйте оператор В ИЕРАРХИИ. Это самый быстрый способ с точки зрения СУБД.

Вариант Б: Регистр сведений "НастройкиГруппДиагнозов". Создайте регистр с полями Группа (Строка), НачалоДиапазона (Строка) и КонецДиапазона (Строка). В запросе соедините таблицу документов с этим регистром по условию:


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

Проблема лексикографического порядка

Важно помнить, что для компьютера строка "F2" больше, чем "F10", потому что символ "2" идет после "1". Чтобы избежать этой ловушки при работе с кодами, которые не имеют ведущих нулей, необходимо приводить их к каноническому виду. Если вы не можете изменить структуру справочника, старайтесь всегда использовать максимально точные границы в условиях МЕЖДУ или дополнять сравниваемые строки символами с высоким кодом (например, "я" или "99"), чтобы гарантированно закрыть диапазон.

Использование Системы компоновки данных (СКД)

Для создания отчетов по таким условиям идеально подходит СКД. Мы можем вынести классификацию кодов в Вычисляемые поля. Используя выражение ВЫБОР КОГДА... ТОГДА, мы можем прямо в настройках отчета присвоить каждому документу имя его группы, а затем просто сгруппировать результат по этому виртуальному полю. Это позволит пользователю видеть понятные названия групп ("Шизофрения", "Неврозы") вместо сухих диапазонов кодов.

Таким образом, выбор метода зависит от ваших приоритетов: гибкость (регистры), быстродействие (дополнительные реквизиты) или скорость разработки (прямое сравнение строк в запросе).

← На главную