При работе с управляемыми формами в системе «1С:Предприятие 8.3» разработчики часто сталкиваются с особенностями поведения стандартных механизмов. Одной из таких особенностей является работа свойства ОтборСтрок для элементов типа «Таблица». Рассмотрим ситуацию: нам необходимо отфильтровать строки в табличной части по конкретному коду или номеру, например, «1.1». Однако вместо одной ожидаемой строки система выводит целый список: «1.1», «1.11», «1.12» и так далее. Проанализируем, почему это происходит, и разберем наиболее эффективные способы решения данной задачи.
Для начала выясним причину такого поведения системы. Обратившись к «Системе программного интерфейса» (СП), мы увидим, что отбор в строковых колонках табличной части по умолчанию выполняется по условию вхождения значения. Это означает, что платформа ищет все строки, которые начинаются с указанной последовательности символов.
Разберем на примере кода, который часто используют разработчики:
// Установка отбора в табличной части
Элементы.ТЧ.ОтборСтрок = Новый ФиксированнаяСтруктура("НомерСтроки", "1.1");
В данном случае, если в колонке НомерСтроки присутствуют значения «1.1», «1.11», «1.100», система посчитает, что все они соответствуют условию, так как каждое из них начинается на «1.1». Это поведение жестко зашито в логику свойства ОтборСтрок для строковых типов данных и изменить его напрямую (например, переключить режим на «Равно») невозможно.
Проанализируем самый надежный программный метод, который позволяет обойти ограничение «вхождения». Суть метода заключается в добавлении в таблицу дополнительной скрытой колонки булевского типа. Это позволит нам программно определить, какие строки должны быть показаны, а затем применить к ним простой и быстрый фильтр.
Рассмотрим по шагам реализацию этого метода:
ТочноеСоответствие с типом Булево.Видимость в значение Ложь.Пример кода для реализации:
// Очистим предыдущие пометки и установим новые
Для Каждого СтрокаТЧ Из Объект.Товары Цикл
// Здесь мы используем оператор сравнения "равно", который работает точно
Если СтрокаТЧ.НомерСтрокиТекстом = "1.1" Тогда
СтрокаТЧ.ТочноеСоответствие = Истина;
Иначе
СтрокаТЧ.ТочноеСоответствие = Ложь;
КонецЕсли;
КонецЦикла;
// Теперь применяем отбор по булевской колонке
// Для типа Булево отбор всегда работает на точное равенство
ПараметрыОтбора = Новый Структура("ТочноеСоответствие", Истина);
Элементы.Товары.ОтборСтрок = Новый ФиксированнаяСтруктура(ПараметрыОтбора);
Преимущества этого метода: он работает безотказно с любыми типами данных и позволяет реализовывать даже сложные условия фильтрации (например, по нескольким полям сразу или по сложным алгоритмам).
Посмотрим на ситуацию с другой стороны. Если проблема заключается в том, что «1.1» является началом для «1.11», мы можем изменить сам формат записи данных, чтобы исключить такое перекрытие. Этот метод часто используется в нумерации документов или справочников.
Вместо использования номеров типа «1.1», «1.2», ..., «1.11», рекомендуется использовать формат с фиксированной длиной дробной части, дополненной нулями:
В этом случае, при установке отбора по значению «1.01», система не найдет совпадений с «1.11», так как строки различаются уже во втором символе после точки. Однако этот метод требует изменения бизнес-логики формирования номеров и может быть неудобен, если пользователи уже привыкли к старому формату или если количество уровней вложенности заранее неизвестно.
Если нам нужно не просто программно отобрать строки для каких-то вычислений, а именно визуально скрыть ненужные данные от пользователя, мы можем воспользоваться механизмом «Условного оформления». Рассмотрим, как настроить его программно.
Метод заключается в том, чтобы сделать все строки, не подходящие под условие, невидимыми. Посмотрим на пример кода:
// Очищаем старые правила оформления, если они были созданы программно
УсловноеОформление.Элементы.Очистить();
// Создаем новое правило
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
// Указываем, что хотим изменять видимость
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Видимость", Ложь);
// Описываем условие: если Номер НЕ равен "1.1"
КомпоновкаОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
КомпоновкаОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Объект.Товары.НомерСтрокиТекстом");
КомпоновкаОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
КомпоновкаОтбора.ПравоеЗначение = "1.1";
// Указываем, что правило применяется ко всей строке таблицы
ПолеОформления = ЭлементОформления.Поля.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("Товары");
Важно отметить, что использование Видимости в условном оформлении для строк табличных частей имеет свои особенности. В некоторых версиях платформы это может приводить к появлению пустых пространств. Тем не менее, это мощный инструмент для динамического управления интерфейсом без изменения самих данных.
Иногда задача отбора стоит не для отображения на форме, а для последующей обработки данных в коде. В этом случае использование ОтборСтрок (который является свойством элемента формы, то есть интерфейсным механизмом) избыточно и неэффективно. Выясним, как сделать это на уровне данных.
Объект ТабличнаяЧасть и ТаблицаЗначений имеют встроенный метод НайтиСтроки(), который, в отличие от интерфейсного фильтра, работает именно по точному совпадению.
// Создаем структуру поиска
ПараметрыПоиска = Новый Структура;
ПараметрыПоиска.Вставить("НомерСтрокиТекстом", "1.1");
// Получаем массив строк, точно соответствующих условию
НайденныеСтроки = Объект.Товары.НайтиСтроки(ПараметрыПоиска);
// Обрабатываем результат
Для Каждого Строка Из НайденныеСтроки Цикл
// Здесь будут только строки с номером "1.1"
// Строки "1.11" в массив не попадут
КонецЦикла;
Подводя итог, можно сказать, что выбор метода зависит от конкретной цели:
Помните, что свойство ОтборСтрок ориентировано на быстродействие и удобство поиска «как в Excel», поэтому оно всегда будет предлагать варианты по началу строки. Понимание этой внутренней механики платформы 1С позволяет выбирать наиболее элегантные и эффективные решения для ваших задач.