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

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

При разработке функциональности в системе 1С, особенно в управляемых формах, мы часто сталкиваемся с необходимостью открыть форму списка или форму выбора какого-либо объекта (будь то элемент справочника или документ) и сразу же установить курсор на конкретном, заранее определенном элементе. Эта задача кажется довольно прямолинейной, но на практике она может вызывать затруднения из-за неверного использования параметров метода ОткрытьФорму().

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

Анализ исходной проблемы и некорректного подхода

Наш коллега столкнулся с проблемой: при попытке открыть форму выбора документа «СчетФактураВыданный» и спозиционировать ее на ранее выбранном документе, курсор устанавливался в самый низ списка, а не на нужный элемент. Исходный фрагмент кода, который был использован, выглядел следующим образом:


&НаКлиенте
Процедура ПодборСчетФактураВыданный(Команда)
    ПараметрыВыбора = Новый Структура;
    ПараметрыВыбора.Вставить("РежимВыбора",        Истина);    
    ПараметрыВыбора.Вставить("МножественныйВыбор", Ложь);    
    ПараметрыВыбора.Вставить("ЗакрыватьПриВыбора", Ложь);    
    //
    Если РанееВыбранныйДокумент <> Неопределено Тогда
        ПараметрыВыбора.Вставить("УстановитьПараметрыФункциональныхОпцийФормы", Новый Структура("ТекущаяСтрока", РанееВыбранныйДокумент)); 
    КонецЕсли;
    //
    ОбработкаВыбора = Новый ОписаниеОповещения("ПриЗакрытииФормыВыбора4", ЭтотОбъект, "Подбор");
    //
    ОткрытьФорму("Документ.СчетФактураВыданный.ФормаВыбора", ПараметрыВыбора, ЭтаФорма, , , , ОбработкаВыбора);
КонецПроцедуры

Если мы внимательно посмотрим на этот код, мы увидим ключевую ошибку, которая препятствовала правильному позиционированию. Передаваемый параметр УстановитьПараметрыФункциональныхОпцийФормы был использован для совершенно иной цели – для установки текущей строки. Этот параметр предназначен для работы с функциональными опциями приложения, которые управляют динамическим включением или выключением определенной функциональности, влияя на видимость элементов интерфейса и поведение кода. Таким образом, вложение параметра ТекущаяСтрока внутрь структуры для функциональных опций было неверным.

Корректное решение: Использование параметра "ТекущаяСтрока"

Для правильного и успешного позиционирования курсора на конкретном элементе при открытии формы списка или выбора в 1С 8.3 на управляемых формах, необходимо передать ссылку на этот элемент напрямую в параметре ТекущаяСтрока. Этот параметр является стандартным для всех управляемых форм и обеспечивает точное позиционирование на строке списка, которая соответствует переданному значению.

Давайте рассмотрим исправленный вариант кода, который успешно решает поставленную задачу и позволяет нам достичь желаемого поведения:


&НаКлиенте
Процедура ПодборСчетФактураВыданный(Команда)
    ПараметрыВыбора = Новый Структура;
    ПараметрыВыбора.Вставить("РежимВыбора",        Истина);    
    ПараметрыВыбора.Вставить("МножественныйВыбор", Ложь);    
    ПараметрыВыбора.Вставить("ЗакрыватьПриВыбора", Ложь);    
    //
    Если РанееВыбранныйДокумент <> Неопределено Тогда
        // Корректное позиционирование: передаем ссылку в параметре "ТекущаяСтрока"
        ПараметрыВыбора.Вставить("ТекущаяСтрока", РанееВыбранныйДокумент); 
    КонецЕсли;
    //
    ОбработкаВыбора = Новый ОписаниеОповещения("ПриЗакрытииФормыВыбора4", ЭтотОбъект, "Подбор");
    //
    ОткрытьФорму("Документ.СчетФактураВыданный.ФормаВыбора", ПараметрыВыбора, ЭтаФорма, , , , ОбработкаВыбора);
КонецПроцедуры

&НаКлиенте
Процедура ПриЗакрытииФормыВыбора4(Значение, ДопПараметры) Экспорт
    Если Значение = Неопределено Тогда
        Возврат;            
    КонецЕсли;
    //
    РанееВыбранныйДокумент = Значение;
КонецПроцедуры    

Как мы видим в этом исправленном коде, мы убрали некорректное вложение параметра и теперь напрямую передаем ссылку на РанееВыбранныйДокумент в параметр ТекущаяСтрока внутри структуры ПараметрыВыбора. Именно такой подход является правильным и эффективным для позиционирования в формах выбора и списка. Мы используем стандартный механизм платформы, что обеспечивает предсказуемое поведение и совместимость.

Подробнее о параметрах открытия форм в 1С: Углубленный анализ

Теперь давайте углубимся в различные способы передачи параметров при открытии форм и подробно рассмотрим их истинное назначение. Это поможет нам избежать подобных ошибок в будущем и более уверенно работать с механизмами форм в 1С.

  1. Корректная передача параметра "ТекущаяСтрока" для позиционирования

    Как мы уже выяснили в нашем случае, для того чтобы форма списка или выбора успешно спозиционировалась на определенном элементе, абсолютно необходимо передать ссылку на этот элемент в параметре ТекущаяСтрока в структуре параметров метода ОткрытьФорму(). Этот параметр является одним из наиболее часто используемых и стандартных для управляемых форм. Он обеспечивает прямое позиционирование на строке списка, которая соответствует переданному значению, сразу при открытии или повторном открытии формы.

    Важно отметить, что если форма используется для выбора или подбора (то есть открывается с РежимВыбора = Истина), то установка этого параметра имеет более высокий приоритет по сравнению со свойством формы НачальноеЗначениеВыбора, если оно также было бы установлено.

    Посмотрим на пример его использования в простейшем виде:

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

    Таким образом, мы видим, что параметр ТекущаяСтрока является прямым и эффективным инструментом для управления начальным положением курсора в форме.

  2. Назначение параметра "Ключ" для открытия формы существующего объекта

    Иногда наша задача заключается не в открытии формы списка или выбора с последующим позиционированием, а в открытии формы конкретного, уже существующего объекта (например, формы элемента справочника, формы документа или другого прикладного объекта) для его просмотра или редактирования. В таких случаях ссылку на этот объект следует передавать в параметре Ключ структуры параметров метода ОткрытьФорму().

    При использовании параметра Ключ система автоматически определяет, какую форму объекта нужно открыть (обычно это основная форма объекта), и заполняет ее данными из переданной ссылки. В результате открывается не список, а сразу форма конкретного элемента.

    Рассмотрим пример:

    
    // Предположим, у нас есть ссылка на определенный документ "МойДокумент"
    МояСсылкаНаДокумент = Документы.МойДокумент.НайтиПоНомеру("00000001", Дата("20230101"));
    
    // Создаем структуру параметров и передаем ссылку в "Ключ"
    ПараметрыФормы = Новый Структура("Ключ", МояСсылкаНаДокумент);
    
    // Открываем форму документа, а не его список
    ОткрытьФорму("Документ.МойДокумент.ФормаДокумента", ПараметрыФормы);
    

    Этот подход значительно упрощает навигацию и взаимодействие с конкретными экземплярами объектов в системе.

  3. Использование "УстановитьПараметрыФункциональныхОпцийФормы"

    Параметр УстановитьПараметрыФункциональныхОпцийФормы, который, как мы выяснили, был ошибочно использован в первоначальном коде для позиционирования, имеет совершенно иное и очень важное назначение. Он предназначен для работы с функциональными опциями в прикладном решении 1С. Функциональные опции – это мощный механизм, позволяющий динамически включать или выключать определенную функциональность приложения, а также влиять на видимость элементов интерфейса (таких как реквизиты, команды, колонки таблиц) и поведение программного кода в зависимости от определенных условий.

    Метод УстановитьПараметрыФункциональныхОпцийФормы() позволяет программно устанавливать значения параметров функциональных опций для конкретной открываемой формы. Это может быть полезно, например, для адаптации поведения формы под определенный контекст (например, показать или скрыть поля в зависимости от настроек учета для конкретной организации). Критически важно понимать, что изменение значений функциональных опций через этот параметр не приводит к автоматическому обновлению командного интерфейса формы. Для того чтобы изменения в функциональных опциях отразились на интерфейсе формы, может потребоваться дополнительный вызов метода ОбновитьИнтерфейс() или его аналогов.

    Рассмотрим гипотетический пример использования этого параметра:

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

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

  4. Передача параметров в динамический список для отбора

    При открытии формы, которая содержит динамический список (особенно если этот список основан на произвольном запросе), часто возникает необходимость передать параметры для этого запроса, чтобы получить уже отфильтрованные данные. Мы можем это сделать, передав необходимые значения через структуру параметров формы, используя метод ОткрытьФорму().

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

    Рассмотрим пример. Сначала, как мы передаем параметр при вызове формы:

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

    Затем, внутри модуля формы списка (например, в модуле формы Документ.МойДокумент.ФормаСписка), мы обрабатываем этот параметр:

    
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        // Проверяем, был ли передан параметр "ОрганизацияОтбора"
        Если Параметры.Свойство("ОрганизацияОтбора") Тогда
            // Устанавливаем значение параметра для динамического списка
            // "ПараметрОрганизация" - это имя параметра в запросе динамического списка
            Список.Параметры.УстановитьЗначениеПараметра("ПараметрОрганизация", Параметры.ОрганизацияОтбора);
        КонецЕсли;
        // Можно также установить отбор через свойства списка, если динамический список
        // не использует произвольный запрос, а основан на данных регистра
        // Если Список.Отбор.Свойства.Содержит("Организация") Тогда
        //     ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        //     ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Организация");
        //     ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
        //     ЭлементОтбора.ПравоеЗначение = Параметры.ОрганизацияОтбора;
        //     ЭлементОтбора.Использование = Истина;
        // КонецЕсли;
    КонецПроцедуры
    

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

  5. Общие рекомендации по передаче параметров в формы

    Для повышения надежности, производительности и читаемости кода при работе с управляемыми формами в 1С 8.3, мы рекомендуем придерживаться нескольких общих правил по передаче параметров:

    1. Всегда используйте ОткрытьФорму(): Мы настоятельно рекомендуем всегда отдавать предпочтение методу глобального контекста ОткрытьФорму(). Следует избегать альтернативного способа, который включает вызов ПолучитьФорму() с последующим Форма.Открыть(). Метод ОткрытьФорму() более полно и корректно управляет жизненным циклом формы, включая ее создание, инициализацию и отображение, что снижает вероятность возникновения ошибок.
    2. Передавайте все параметры при открытии: Все параметры, которые необходимы форме для ее корректной работы и инициализации, следует передавать в наборе параметров метода ОткрытьФорму(). Эти параметры должны быть организованы в виде структуры. Такой подход гарантирует, что вся необходимая инициализация формы произойдет на сервере в обработчике ПриСозданииНаСервере. Это также помогает централизовать весь код инициализации формы в одном месте, делая его более легким для понимания и поддержки.
    3. Избегайте обращения к форме после ее открытия: Старайтесь не обращаться к методам и свойствам формы для ее параметризации уже после того, как она была открыта. Вся необходимая для формы информация должна быть передана однократно при вызове ОткрытьФорму(). После открытия формы ее контекст уже сформирован, и попытки изменить его извне могут привести к непредсказуемым результатам или ошибкам.
    4. Используйте выражения или промежуточные переменные: При передаче параметров в формы не следует передавать непосредственно атрибуты текущего контекста (например, значение реквизита документа, такого как Объект.Ссылка). Метод ОткрытьФорму() возвращает контекст открытой формы в тот же параметр, что в некоторых сценариях может привести к непреднамеренной очистке значения или его изменению. Рекомендуется использовать промежуточные переменные или явные выражения для передачи значений, чтобы избежать этой потенциальной проблемы. Например, вместо ПараметрыФормы.Вставить("Ключ", Объект.Ссылка); лучше использовать СсылкаОбъекта = Объект.Ссылка; ПараметрыФормы.Вставить("Ключ", СсылкаОбъекта);.
  6. Отбор и позиционирование в форме выбора

    В дополнение к параметру ТекущаяСтрока для непосредственного позиционирования, мы также можем передавать структуру Отбор в ПараметрыВыбора для фильтрации данных в форме списка или выбора. Это очень мощная комбинация, которая позволяет нам открывать форму, которая уже содержит только нужные, отфильтрованные данные, а затем дополнительно позиционировать курсор на конкретном элементе внутри этого уже отфильтрованного списка.

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

    Рассмотрим пример, объединяющий отбор и позиционирование:

    
    // Предположим, мы хотим выбрать счет-фактуру выданную
    // для конкретной организации и позиционировать на последнем выбранном документе
    МояОрганизацияСсылка = Справочники.Организации.НайтиПоНаименованию("Тестовая организация");
    РанееВыбранныйДокумент = Документы.СчетФактураВыданный.НайтиПоНомеру("СФ00000005", Дата("20230315"));
    
    ПараметрыВыбора = Новый Структура;
    ПараметрыВыбора.Вставить("РежимВыбора", Истина);    
    ПараметрыВыбора.Вставить("МножественныйВыбор", Ложь);    
    ПараметрыВыбора.Вставить("ЗакрыватьПриВыбора", Ложь);    
    
    // Создаем структуру для отбора
    ПараметрыОтбора = Новый Структура;
    ПараметрыОтбора.Вставить("Организация", МояОрганизацияСсылка); // Отбор по организации
    ПараметрыВыбора.Вставить("Отбор", ПараметрыОтбора);
    
    // Позиционирование на конкретном документе внутри отфильтрованного списка
    Если РанееВыбранныйДокумент <> Неопределено Тогда
        ПараметрыВыбора.Вставить("ТекущаяСтрока", РанееВыбранныйДокумент); 
    КонецЕсли;
    
    // Открываем форму выбора счета-фактуры выданного с отбором и позиционированием
    ОткрытьФорму("Документ.СчетФактураВыданный.ФормаВыбора", ПараметрыВыбора, ЭтаФорма);
    

    Этот комплексный подход позволяет нам очень гибко настраивать отображение и взаимодействие с формами списка и выбора в 1С, значительно улучшая эргономику и эффективность работы пользователя.

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

← На главную