Как в запросе 1С разделить строку с данными на отдельные записи?

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

При разработке отчетов в 1С:Предприятие часто возникают задачи, требующие обработки строковых данных. Одной из наиболее частых является попытка преобразовать строку, содержащую несколько значений через разделитель (например, «До, После» или «синий, красный, желтый»), в отдельные записи для дальнейшей обработки в Система Компоновки Данных (СКД) или вывода в отчет. Давайте разберем, почему эта задача вызывает трудности и как ее правильно решить.

Анализ проблемы: почему это сложно реализовать в запросе?

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

Вариант 1: Нормализация данных (Рекомендуемый подход)

Самым правильным подходом с точки зрения архитектуры является приведение данных к нормальному виду. Если у вас в Регистр Сведений хранятся «склеенные» строки, рекомендуется пересмотреть структуру хранения. Вместо одного поля с набором значений, лучше использовать отдельные записи для каждого события или измерения.

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

Вариант 2: Предварительная обработка данных кодом 1С

Если вы не можете изменить структуру хранения данных в базе, необходимо выполнить операцию «разбора» строк до того, как данные попадут в запрос. Для этого используем встроенный язык 1С (код в модуле объекта или менеджера).

Мы можем создать Временная Таблица и заполнить ее уже «чистыми» данными, используя строковые функции платформы. Рассмотрим логику процесса:

  1. Выбираем исходные записи из регистра.
  2. Для каждого полученного набора «склеенных» данных вызываем функцию СтрРазделить.
  3. Полученный массив значений обходим в цикле и создаем новую структуру данных (например, ТаблицаЗначений).
  4. Передаем сформированную ТаблицаЗначений в запрос через МенеджерВременныхТаблиц.

Пример логики обработки данных перед передачей в запрос:


// Предположим, мы получили данные из запроса
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("ГруппаПвр");
ТЗ.Колонки.Добавить("Поле1");
ТЗ.Колонки.Добавить("Поле2");

Пока Выборка.Следующий() Цикл
    МассивПоле1 = СтрРазделить(Выборка.Поле1, ", ");
    МассивПоле2 = СтрРазделить(Выборка.Поле2, ", ");
    
    Для Индекс = 0 По МассивПоле1.Количество() - 1 Цикл
        НоваяСтрока = ТЗ.Добавить();
        НоваяСтрока.ГруппаПвр = Выборка.Группа;
        НоваяСтрока.Поле1 = МассивПоле1[Индекс];
        НоваяСтрока.Поле2 = МассивПоле2[Индекс];
    КонецЦикла;
КонецЦикла;

Вариант 3: Использование вычисляемых полей в СКД

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

В настройках отчета СКД вы можете создать вычисляемое выражение, где внутри функции Вычислить или в модуле объекта (через ПриКомпоновкеРезультата) вы будете обрабатывать строки. Но опять же, для эффективной работы лучше всего подготавливать данные в ТаблицаЗначений, описанную во втором варианте, и подавать её в качестве НаборДанныхОбъект для СКД.

Заключение: как поступить?

Проанализировав ситуацию, мы пришли к выводу, что реализация «разложения» строк средствами только языка запросов 1С на текущий момент технически невозможна. Чтобы отчет работал быстро и корректно, мы рекомендуем:

Используя эти рекомендации, вы сможете построить стабильную систему отчетности, которая будет легко поддерживаться и развиваться в будущем.

← На главную