В практике разработки на платформе 1С:Предприятие 8.3 часто возникает задача ограничить видимость данных в форме списка. Один из наиболее распространенных сценариев — установка фильтра по текущему пользователю. Однако при работе со строковыми полями (например, «Краткий состав», где перечислены участники документа) разработчики часто сталкиваются с неочевидными ошибками платформы. В этой статье мы подробно разберем, почему возникает ошибка «Нельзя сравнивать поля неограниченной длины» и как правильно реализовать программный отбор.
Рассмотрим ситуацию: у нас есть динамический список (например, список документов), и в нем присутствует поле КраткийСоставДок. Это текстовое поле, в которое программно записываются имена пользователей. Нам нужно, чтобы при открытии формы пользователь видел только те документы, где фигурирует его имя. Простая попытка установить элемент отбора через ОбщегоНазначенияКлиентСервер часто приводит к следующему результату:
Ошибка выполнения запроса: «Неверные параметры в операции сравнения. Нельзя сравнивать поля неограниченной длины и поля несовместимых типов». Это происходит потому, что в базе данных тип «Строка» может быть ограниченной длины (например, 100 символов) или неограниченной (тип TEXT или MEMO в SQL). Платформа 1С не позволяет выполнять операции сравнения (равенство, вхождение) непосредственно над полями неограниченной длины в запросах динамического списка.
Прежде чем писать программный код установки отбора, нам необходимо изменить схему компоновки данных самого динамического списка. Нам нужно «объяснить» системе, что поле КраткийСоставДок имеет конечную длину. Проанализируем, как это сделать правильно.
ВЫРАЗИТЬ.Посмотрим на пример того, как должен выглядеть фрагмент запроса:
ВЫБРАТЬ
ДокументПродажи.Ссылка,
ДокументПродажи.Дата,
ДокументПродажи.Номер,
ВЫРАЗИТЬ(ДокументПродажи.КраткийСоставДок КАК СТРОКА(1000)) КАК КраткийСоставДок
ИЗ
Документ.Продажи КАК ДокументПродажи
Важный момент: Мы ограничили длину строки до 1000 символов. Этого обычно достаточно для перечисления имен пользователей, и это позволяет SQL-серверу эффективно индексировать и сравнивать эти данные. Теперь поле перестало быть «неограниченным», и ошибка сравнения исчезнет.
Теперь перейдем к написанию кода в модуле формы списка. Лучшим местом для этого является процедура ПриСозданииНаСервере. Мы будем использовать типовую функцию из библиотеки стандартных подсистем (БСП), чтобы обеспечить корректную работу с компоновщиком настроек.
Проанализируем ситуацию: если мы используем вид сравнения Содержит, нам нужно передать строковое значение. Выясним, как правильно получить имя текущего пользователя.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Получаем имя текущего пользователя из параметров сеанса
ИмяПользователя = ПараметрыСеанса.ТекущийПользователь.Наименование;
// Устанавливаем отбор в динамическом списке "Список"
// Используем вид сравнения "Содержит", так как пользователь может быть одним из многих в строке
ОбщегоНазначенияКлиентСервер.УстановитьЭлементОтбораДинамическогоСписка(
Список,
"КраткийСоставДок",
ИмяПользователя,
ВидСравненияКомпоновкиДанных.Содержит
);
КонецПроцедуры
В данном коде Список — это основное имя реквизита формы с типом ДинамическийСписок. Если в вашем случае список называется иначе, подставьте соответствующее имя.
Если документов в базе сотни тысяч, использование отбора с видом сравнения Содержит может замедлить работу формы, так как такой поиск сложно оптимизировать индексами. Рассмотрим более профессиональный и быстрый подход — использование параметров запроса и оператора ПОДОБНО.
Для этого в тексте запроса динамического списка добавим условие ГДЕ:
ВЫБРАТЬ
...
ИЗ
Документ.Продажи КАК ДокументПродажи
ГДЕ
ВЫРАЗИТЬ(ДокументПродажи.КраткийСоставДок КАК СТРОКА(1000)) ПОДОБНО &ИмяПользователяПараметр
Теперь в программном коде нам не нужно устанавливать элемент отбора, достаточно задать значение параметра:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
ЗначениеПоиска = "%" + ПараметрыСеанса.ТекущийПользователь.Наименование + "%";
Список.Параметры.УстановитьЗначениеПараметра("ИмяПользователяПараметр", ЗначениеПоиска);
КонецПроцедуры
Символы % указывают системе, что искомая подстрока может находиться в любом месте поля КраткийСоставДок.
Рассмотрим несколько ситуаций, которые могут помешать корректной работе кода, описанного выше:
КраткийСоставДок в базе — это строка, а вы пытаетесь сравнить его с объектом ПараметрыСеанса.ТекущийПользователь (который является ссылкой), возникнет ошибка типов. Всегда проверяйте, что тип значения отбора совпадает с типом поля в списке.Мы выяснили, что для успешной фильтрации динамического списка по текстовому составу участников необходимо:
ВЫРАЗИТЬ.Содержит для вхождения или Равно для полного совпадения).Используя эти рекомендации, вы сможете создавать гибкие и быстрые интерфейсы, которые будут корректно отображать данные пользователям без лишних системных ошибок.