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

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

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

В этой статье мы подробно разберем все этапы реализации этого механизма: от выбора правильного системного типа до продвинутых способов автоматизации вычислений.

Выбор типа данных: системные возможности 1С

Рассмотрим распространенное заблуждение о том, что для хранения знаков сравнения в таблице значений (ТЗ) необходимо создавать собственное перечисление. В платформе 1С уже существуют готовые системные типы, которые идеально подходят для этих задач. Проанализируем два основных варианта:

  1. ВидСравнения — это классический тип данных, который используется в построителе запросов. Он содержит стандартный набор операций: «Равно», «Больше», «Меньше», «В списке» и другие.
  2. ВидСравненияКомпоновкиДанных — более современный и гибкий тип, используемый в Системе компоновки данных (СКД). Помимо базовых операций, он включает в себя такие полезные проверки, как «Заполнено», «Не заполнено», «Содержит» (для строк) и «ВСпискеПоИерархии».

Вопреки частому мнению, эти типы данных можно и нужно использовать в таблицах значений, создаваемых программно. Выясним, как правильно объявить колонку с таким типом. Для этого воспользуемся объектом ОписаниеТипов.

Рассмотрим пример программного создания таблицы значений:


ТаблицаУсловий = Новый ТаблицаЗначений;
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("ВидСравненияКомпоновкиДанных"));
ОписаниеВидаСравнения = Новый ОписаниеТипов(МассивТипов);

ТаблицаУсловий.Колонки.Добавить("Оператор", ОписаниеВидаСравнения, "Знак");
ТаблицаУсловий.Колонки.Добавить("Значение", , "Значение для сравнения");

Визуализация: заменяем текст на символы

Если просто вывести колонку с типом ВидСравненияКомпоновкиДанных на форму, пользователь увидит длинные строковые представления, такие как «Больше или равно». Это загромождает интерфейс. Разберем, как сделать так, чтобы в таблице отображались лаконичные значки >=, <, =, при этом сохраняя в данных системное значение.

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

  1. Разместим таблицу на форме и найдем элемент управления (Поле ввода), соответствующий колонке «Оператор».
  2. Установим свойство РежимВыбораИзСписка в значение Истина.
  3. Программно или в конфигураторе заполним список выбора.

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


ЭлементОператор = ЭтаФорма.Элементы.ТаблицаУсловийОператор;
ЭлементОператор.СписокВыбора.Очистить();
ЭлементОператор.СписокВыбора.Добавить(ВидСравненияКомпоновкиДанных.Равно, "=");
ЭлементОператор.СписокВыбора.Добавить(ВидСравненияКомпоновкиДанных.Больше, ">");
ЭлементОператор.СписокВыбора.Добавить(ВидСравненияКомпоновкиДанных.Меньше, "<");
ЭлементОператор.СписокВыбора.Добавить(ВидСравненияКомпоновкиДанных.БольшеИлиРавно, ">=");
ЭлементОператор.СписокВыбора.Добавить(ВидСравненияКомпоновкиДанных.МеньшеИлиРавно, "<=");

Важный нюанс: в поле «Значение» списка выбора мы помещаем системный элемент перечисления, а в поле «Представление» — строку-символ. Теперь платформа будет хранить в ТЗ объект типа ВидСравненияКомпоновкиДанных, но показывать пользователю привычный математический знак.

Автоматизация сравнения: как избежать «мартышкиного труда»

Когда пользователь выбрал условие, нам необходимо программно проверить его. Типичная ошибка — писать длинную конструкцию:


Если СтрокаТЗ.Оператор = ВидСравненияКомпоновкиДанных.Равно Тогда
    Результат = (Значение1 = Значение2);
ИначеЕсли СтрокаТЗ.Оператор = ВидСравненияКомпоновкиДанных.Больше Тогда
    Результат = (Значение1 > Значение2);
// И так далее для всех 10+ видов сравнения...
КонецЕсли;

Это неудобно и трудно поддерживать. Рассмотрим более изящные способы автоматизации этой задачи.

Способ 1: Использование функции Вычислить()

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


// Подготовим карту соответствий (можно сделать один раз при старте)
ОператорыСтрокой = Новый Соответствие;
ОператорыСтрокой.Вставить(ВидСравненияКомпоновкиДанных.Равно, "=");
ОператорыСтрокой.Вставить(ВидСравненияКомпоновкиДанных.Больше, ">");

// Выполняем сравнение
Знак = ОператорыСтрокой.Получить(СтрокаТЗ.Оператор);
Условие = "Значение1 " + Знак + " Значение2";
Результат = Вычислить(Условие);

Внимание: при использовании Вычислить() крайне важно следить за типами данных. Если вы сравниваете числа, они должны быть переданы в выражение корректно. Если строки — они должны быть экранированы кавычками.

Способ 2: Использование возможностей СКД

Наиболее надежный и «чистый» с точки зрения архитектуры способ — делегировать сравнение самой платформе через механизмы компоновки. Мы можем создать небольшой объект Отбор в памяти, передать туда наши значения и попросить систему проверить результат.

Разберем, как это работает через КомпоновщикНастроек:

  1. Создаем виртуальную схему компоновки или используем существующий компоновщик.
  2. Добавляем элемент отбора.
  3. Устанавливаем левое значение (поле), вид сравнения и правое значение.
  4. Используем процессор компоновки для фильтрации коллекции.

Этот метод сложнее в реализации «в лоб», но он незаменим, когда видов сравнения много (например, «В списке», «ВИерархии»), так как платформа берет на себя всю сложную логику проверки вхождения в группы и массивы.

Способ 3: Соответствие функций

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

Итоги и рекомендации

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

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

← На главную