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

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

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

Разбор основной проблемы: несоответствие типов

Рассмотрим ситуацию, представленную в обсуждении. Разработчик пытается открыть форму справочника ПоправочныеКоэффициенты и установить отбор по реквизиту Параграф. Этот реквизит имеет тип СправочникСсылка.ВидыРабот. Главная ошибка заключалась в попытке передать в структуру отбора строковое значение или результат функции ЗначениеВСтрокуВнутр.

Проанализируем фрагмент кода с ошибкой:


&НаСервереБезКонтекста 
Функция НайтиНоменклатуруПоНаименованию()
    // ОШИБКА: ЗначениеВСтрокуВнутр превращает ссылку в техническую строку
    Параграф = ЗначениеВСтрокуВнутр(Справочники.ВидыРабот.НайтиПоНаименованию("Реквизит наименование")); 
    Возврат Параграф; 
КонецФункции

&НаКлиенте
Процедура ПриОткрытии(Отказ, Элемент, ДанныеВыбора, СтандартнаяОбработка)
    Итог = НайтиНоменклатуруПоНаименованию();
    СтандартнаяОбработка = Ложь;
    
    ПараметрыФормы = Новый Структура;
    Отборы = Новый Структура;
    
    // ОШИБКА: В структуру отбора передается строка "Итог", 
    // в то время как реквизит "Параграф" в базе данных ожидает Ссылку.
    Отборы.Вставить("Параграф", Итог); 
    
    ПараметрыФормы.Вставить("Отбор", Отборы);
    ОткрытьФорму("Справочник.ПоправочныеКоэффициенты.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры

Важно понимать: для платформы 1С строка "Вид работы №1" и ссылка на элемент справочника "Вид работы №1" — это абсолютно разные типы данных. Если реквизит в справочнике типизирован как СправочникСсылка, то и в структуру отбора нужно передавать именно ссылку. Использование ЗначениеВСтрокуВнутр вообще недопустимо для целей фильтрации, так как этот метод предназначен для сериализации объекта в специальный системный формат, который не распознается механизмом компоновки данных в динамических списках.

Правильная программная установка отбора

Для того чтобы отбор заработал, нам необходимо получить чистую ссылку на стороне сервера и передать её без каких-либо преобразований в строку. Рассмотрим исправленный вариант реализации задачи.

Шаг 1. Получение ссылки на сервере. Проанализируем, как должна выглядеть серверная функция. Она должна возвращать объект типа СправочникСсылка.


&НаСервереБезКонтекста
Функция ПолучитьСсылкуНаВидРаботы(НаименованиеОбъекта)
    // Находим элемент справочника по наименованию
    СсылкаНаОбъект = Справочники.ВидыРабот.НайтиПоНаименованию(НаименованиеОбъекта);
    
    // Проверяем, найден ли элемент, чтобы не передавать ПустуюСсылку случайно
    Если СсылкаНаОбъект.Пустая() Тогда
        Сообщить("Элемент с наименованием '" + НаименованиеОбъекта + "' не найден!");
    КонецЕсли;
    
    Возврат СсылкаНаОбъект;
КонецФункции

Шаг 2. Вызов формы с корректными параметрами. Теперь на стороне клиента мы вызываем эту функцию и передаем результат в структуру Отбор.


&НаКлиенте
Процедура УстановитьОтборИОткрытьФорму()
    
    // Получаем реальную ссылку, а не строку
    СсылкаПараграф = ПолучитьСсылкуНаВидРаботы("НужноеНаименование");
    
    // Подготавливаем параметры для открытия формы
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("Параграф", СсылкаПараграф);
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Отбор", ПараметрыОтбора);
    
    // Открываем форму выбора справочника ПоправочныеКоэффициенты
    ОткрытьФорму("Справочник.ПоправочныеКоэффициенты.ФормаВыбора", ПараметрыФормы);
    
КонецПроцедуры

Альтернативный метод: Связи параметров выбора

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

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

В этом случае платформа сама при нажатии кнопки выбора в поле Коэффициент проанализирует, что выбрано в поле ВидРаботы, и автоматически применит фильтр к открывающемуся справочнику. Это наиболее "чистый" и производительный способ решения задачи.

Важные нюансы и рекомендации по производительности

При работе с отборами в динамических списках (которыми являются формы выбора) следует учитывать несколько технических аспектов:

Почему нельзя использовать Строка() для ссылок в отборах?

Разберем ситуацию, когда разработчик пытается сделать так: Отборы.Вставить("Параграф", Строка(Ссылка)). Метод Строка() возвращает только представление объекта (его наименование). Если вы передадите в отбор строку, система попытается сравнить GUID (уникальный идентификатор ссылки в базе) с текстовым набором символов. Естественно, такое сравнение всегда будет давать результат "Ложь", и в списке не отобразится ни одной записи.

Запомните правило: Тип значения в структуре отбора должен строго соответствовать типу реквизита в метаданных справочника.

Заключение

Мы проанализировали типичную проблему при работе с формами в 1С и выяснили, что ключ к успеху кроется в строгом соблюдении типизации данных. Передавая в параметры формы структуру Отбор, всегда проверяйте, что именно вы туда помещаете. Если это ссылочное поле — передавайте объект СправочникСсылка, если строковое — Строка. Такой подход гарантирует стабильную работу интерфейса и отсутствие трудноуловимых ошибок при фильтрации данных.

← На главную