При изучении материалов на ИТС или просмотре чужого кода начинающие разработчики часто сталкиваются с конструкциями, которые кажутся "магическими" или нарушающими привычную логику объектной модели. Один из таких примеров — прямое обращение к свойствам формы, которых нет в стандартном синтакс-помощнике. Давайте разберем, как это работает, почему это вызывает вопросы у опытных программистов и как реализовать передачу отборов максимально грамотно с точки зрения архитектуры платформы 1С:Предприятие 8.3.
Рассмотрим пример кода, который часто вызывает недоумение:
&НаКлиенте
Процедура ПриходныеНакладные(Команда)
ФормаСписка = ПолучитьФорму("Документ.ПриходнаяНакладная.ФормаСписка");
ФормаСписка.ФильтрПоТовару = Элементы.Список.ТекущаяСтрока;
ФормаСписка.Открыть();
КонецПроцедуры
Здесь ФормаСписка.ФильтрПоТовару — это не предопределенное свойство платформы. На самом деле, это реквизит формы, который разработчик создал вручную в редакторе управляемой формы ПриходнаяНакладная.ФормаСписка. В управляемом приложении платформа позволяет обращаться к реквизитам формы через точку от объекта формы.
Проанализируем, почему это решение часто подвергается критике. Основная проблема заключается в смешивании пространств имен. Когда мы пишем Форма.Имя, платформа ищет это имя среди:
ТолькоПросмотр, Заголовок).Если вы случайно назовете свой реквизит так же, как называется новое свойство, которое 1С добавит в платформу в будущем, ваш код может перестать работать или начать вести себя непредсказуемо. Поэтому рассмотрим более надежные способы реализации этой задачи.
Платформа 1С предоставляет встроенный механизм для наложения простых фильтров при открытии формы. Для этого используется параметр Отбор, который представляет собой структуру. Ключ этой структуры — имя поля в динамическом списке, а значение — то, что мы хотим найти.
Рассмотрим, как это выглядит на практике. Вместо использования функции ПолучитьФорму() и ручного присвоения реквизитов, мы воспользуемся методом ОткрытьФорму():
&НаКлиенте
Процедура ОткрытьСписокСОтбором(Команда)
ПараметрыОтбора = Новый Структура("Товар", Элементы.Список.ТекущаяСтрока);
ПараметрыФормы = Новый Структура("Отбор", ПараметрыОтбора);
ОткрытьФорму("Документ.ПриходнаяНакладная.ФормаСписка", ПараметрыФормы);
КонецПроцедуры
Этот метод предпочтительнее, так как платформа берет на себя всю работу по применению фильтра к основному реквизиту формы (Динамическому списку). Нам не нужно создавать лишние реквизиты в форме списка и писать дополнительный код для их обработки.
Иногда требуется передать не просто равенство, а сложный отбор (например, вхождение в список или вид сравнения "Больше"). В этом случае стандартный параметр Отбор может не подойти. Проанализируем использование Фиксированных настроек.
Фиксированные настройки хороши тем, что пользователь не сможет изменить или удалить такой отбор через меню "Настроить список". Это гарантирует, что логика приложения не будет нарушена действиями пользователя.
Разберем алгоритм реализации:
ПриСозданииНаСервере применяем настройки к компоновщику динамического списка.Пример кода в вызывающем модуле:
&НаКлиенте
Процедура ОткрытьСписокСЖесткимОтбором(Команда)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ВыбранныйТовар", Элементы.Список.ТекущаяСтрока);
ОткрытьФорму("Документ.ПриходнаяНакладная.ФормаСписка", ПараметрыФормы);
КонецПроцедуры
Пример кода в модуле открываемой формы (ПриСозданииНаСервере):
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ВыбранныйТовар") Тогда
ЭлементОтбора = Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Товар");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Параметры.ВыбранныйТовар;
ЭлементОтбора.Использование = Истина;
КонецЕсли;
КонецПроцедуры
Если в вашей форме списка используется динамический список с произвольным запросом, вы можете передать значение фильтра напрямую в параметр запроса. Выясним, как это сделать наиболее элегантно.
Предположим, в форме списка ПриходнаяНакладная в тексте запроса динамического списка написано:
ВЫБРАТЬ * ИЗ Документ.ПриходнаяНакладная ГДЕ Товар = &ПараметрТовар
В этом случае мы можем связать параметр запроса с реквизитом формы. Выполним следующие шаги:
ФильтрТовар.&ПараметрТовар в колонке "Выражение" указываем имя нашего реквизита: ФильтрТовар.Теперь, как только мы программно изменим значение реквизита ФильтрТовар, список автоматически обновится. Это именно то, что пытался сделать автор примера с ИТС, но с использованием более глубокой интеграции с механизмом динамических списков.
Проанализируем разницу между этими двумя методами. В старых примерах часто используется ПолучитьФорму(). Однако в современном стандарте разработки 1С рекомендуется использовать ОткрытьФорму().
Почему это важно?
ОткрытьФорму() инициализация (событие ПриСозданииНаСервере) происходит один раз, и в неё сразу передаются все нужные параметры.ПолучитьФорму(), а затем начинаете менять её реквизиты (как в примере ФормаСписка.ФильтрПоТовару = ...), это может спровоцировать лишние серверные вызовы. Платформа сначала создает форму, а потом вынуждена "переваривать" измененные данные, что замедляет работу интерфейса.ОткрытьФорму() более безопасен с точки зрения инкапсуляции. Вы передаете данные в "черный ящик" (структуру параметров), а форма сама решает, как их обработать.Чтобы избежать ошибок при работе с реквизитами формы, важно помнить приоритет обращения к именам внутри модуля формы. Рассмотрим ситуацию, когда у вас есть локальная переменная и реквизит формы с одинаковым именем:
&НаКлиенте
Процедура Тест()
Переменная1 = 10; // Локальная переменная
// Если мы напишем просто Переменная1, мы обратимся к локальной переменной.
// Чтобы гарантированно обратиться к реквизиту формы, используем:
ЭтотОбъект.Переменная1 = 20;
КонецПроцедуры
Выясним, в каком порядке платформа ищет идентификатор, если он написан без префикса:
Именно из-за этого "сваливания в кучу" разработчики в обсуждении называют прямой доступ к реквизитам "серьезным просчетом". Чтобы ваш код был понятным и легко поддерживаемым, старайтесь использовать структуру Параметры и обрабатывать их внутри события ПриСозданииНаСервере. Это сделает ваши формы более независимыми и предсказуемыми в работе.
Рассмотренное "шаманство" с ФормаСписка.ФильтрПоТовару — это легитимная, но не самая лучшая практика работы в управляемом приложении 1С. Для качественной разработки рекомендуется использовать механизм параметров формы и настройки компоновщика данных динамического списка. Это обеспечит стабильность кода при обновлениях платформы и упростит чтение вашей логики другими программистами.