При разработке отчетов в системе 1С программисты часто сталкиваются с необходимостью классификации данных по строковым идентификаторам. Типичный пример — работа с кодами МКБ-10 (Международная классификация болезней), где коды имеют вид F20, E03.1, M0.1*. Основная сложность заключается в том, что стандартные механизмы работы с числами здесь не применимы, а обычное строковое сравнение может выдавать неожиданные результаты из-за особенностей лексикографического порядка.
В этой статье мы подробно разберем, как эффективно строить запросы для подсчета документов по диапазонам нечисловых кодов, проанализируем методы оптимизации структуры данных и выясним, как избежать типичных ошибок при сортировке строк.
Самый простой и очевидный способ — использование стандартных операторов сравнения (>=, <=) непосредственно к строковым полям. Поскольку коды МКБ-10 строятся по определенному стандарту (буква и цифры), они поддаются сравнению как обычные строки. Рассмотрим пример, когда нам нужно выбрать документы с кодами диагнозов в диапазоне от F00 до F45.
Проанализируем выражение для условия запроса:
|ГДЕ
| Обращения.Диагноз.Код >= "F00"
| И Обращения.Диагноз.Код <= "F45.9"
Почему мы добавляем .9 к конечной границе? Это важный нюанс строкового сравнения. Если мы укажем просто <= "F45", то код F45.1 уже не попадет в выборку, так как строка "F45.1" лексикографически длиннее и "больше", чем "F45". Добавление суффикса позволяет захватить все вложенные подпункты данной группы.
Если задача стоит в том, чтобы подсчитать количество документов, сгруппированных по верхнему уровню классификатора (например, только по первой букве кода), мы можем использовать функции работы со строками прямо в теле запроса. Рассмотрим, как можно сгруппировать данные по разделам:
ВЫБРАТЬ
ПОДСТРОКА(Обращения.Диагноз.Код, 1, 1) КАК РазделКода,
КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Обращения.Ссылка) КАК КоличествоДокументов
ИЗ
Документ.Обращения КАК Обращения
ГДЕ
Обращения.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания
СГРУППИРОВАТЬ ПО
ПОДСТРОКА(Обращения.Диагноз.Код, 1, 1)
В данном примере функция ПОДСТРОКА выделяет первый символ кода (букву), что позволяет мгновенно получить статистику по крупным блокам заболеваний (все коды на "F", все на "M" и т.д.). Для более точечных выборок удобно применять оператор ПОДОБНО. Например, для выбора всех психических расстройств (коды F):
ГДЕ Диагноз.Код ПОДОБНО "F%"
Если отчеты по диапазонам строковых кодов строятся часто и на больших объемах данных, постоянное использование функций ПОДСТРОКА или сложных сравнений строк может существенно замедлить работу базы данных. Разберем профессиональный подход к архитектуре справочника.
Рекомендуется "обогатить" справочник диагнозов техническими реквизитами:
F003.01 вместо F3.1).При таком подходе запрос становится максимально быстрым, так как поиск идет по индексированным полям с фиксированной длиной или числам. Рассмотрим пример записи такого элемента:
Процедура ПередЗаписью(Отказ)
// Пример примитивного парсинга для демонстрации идеи
БуквеннаяЧасть = Лев(Код, 1);
ЦифроваяЧасть = Число(Сред(Код, 2, 2));
// Теперь в запросах можно легко делать отборы по диапазонам чисел
КонецПроцедуры
Если диапазоны кодов (например, "F20-F41.5") являются логическими группами, которые могут меняться со временем, не стоит "зашивать" их условия прямо в программный код. Выясним, как сделать решение гибким.
Вариант А: Использование иерархии справочника. Если ваш справочник диагнозов иерархический, создайте группы, соответствующие диапазонам. В запросе используйте оператор В ИЕРАРХИИ. Это самый быстрый способ с точки зрения СУБД.
Вариант Б: Регистр сведений "НастройкиГруппДиагнозов". Создайте регистр с полями Группа (Строка), НачалоДиапазона (Строка) и КонецДиапазона (Строка). В запросе соедините таблицу документов с этим регистром по условию:
ВЫБРАТЬ
Настройки.Группа,
КОЛИЧЕСТВО(Обращения.Ссылка)
ИЗ
Документ.Обращения КАК Обращения
ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиГруппДиагнозов КАК Настройки
ПО Обращения.Диагноз.Код >= Настройки.НачалоДиапазона
И Обращения.Диагноз.Код <= Настройки.КонецДиапазона
СГРУППИРОВАТЬ ПО
Настройки.Группа
Важно помнить, что для компьютера строка "F2" больше, чем "F10", потому что символ "2" идет после "1". Чтобы избежать этой ловушки при работе с кодами, которые не имеют ведущих нулей, необходимо приводить их к каноническому виду. Если вы не можете изменить структуру справочника, старайтесь всегда использовать максимально точные границы в условиях МЕЖДУ или дополнять сравниваемые строки символами с высоким кодом (например, "я" или "99"), чтобы гарантированно закрыть диапазон.
Для создания отчетов по таким условиям идеально подходит СКД. Мы можем вынести классификацию кодов в Вычисляемые поля. Используя выражение ВЫБОР КОГДА... ТОГДА, мы можем прямо в настройках отчета присвоить каждому документу имя его группы, а затем просто сгруппировать результат по этому виртуальному полю. Это позволит пользователю видеть понятные названия групп ("Шизофрения", "Неврозы") вместо сухих диапазонов кодов.
Таким образом, выбор метода зависит от ваших приоритетов: гибкость (регистры), быстродействие (дополнительные реквизиты) или скорость разработки (прямое сравнение строк в запросе).