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

Программист 1С v7.7
← На главную

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

Проанализируем ситуацию: разработчик пытается найти элемент справочника по коду и присвоить его реквизиту формы. Однако делает это не совсем корректно, что и приводит к описанному поведению.

Анализ неверного подхода

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


// Неправильный код
Спр = СоздатьОбъект("Справочник.ТипыБланков"); 

Если Спр.НайтиПоКоду("401951") = 1 Тогда
    // Эта строка является причиной ошибки
    ТипБСО.Код = Спр.ТекущийЭлемент().Код;
КонецЕсли;

В чем здесь ошибка? Ключевая ошибка — в попытке присвоить свойству .Код реквизита формы значение кода найденного элемента. Реквизит формы, имеющий тип Справочник.ТипыБланков, ожидает получить не строку с кодом, а ссылку на сам элемент справочника. Конструкция ТипБСО.Код = ... пытается изменить код уже выбранного в реквизите ТипБСО элемента, а не установить в этот реквизит новый элемент. Если до этого в реквизите ТипБСО не был выбран элемент, такая строка кода может привести к ошибке "Не выбран элемент!".

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

Правильное решение: присваивание ссылки на элемент

Чтобы система корректно "поняла", какой элемент мы хотим установить, нужно присвоить реквизиту формы не его свойство (код или наименование), а целиком сам объект (ссылку на элемент). Для этого используется метод ТекущийЭлемент(), который возвращает ссылку на тот элемент, на котором в данный момент спозиционирован объект справочника.

Рассмотрим по шагам правильный алгоритм действий:

  1. Создаем объект для работы с нужным справочником.
  2. Используем один из методов поиска, например, НайтиПоКоду() или НайтиПоНаименованию().
  3. Обязательно проверяем результат поиска. Метод поиска возвращает 1 в случае успеха и 0, если элемент не найден. Эта проверка защитит систему от ошибок.
  4. Если элемент найден, присваиваем реквизиту формы результат вызова метода ТекущийЭлемент().

Посмотрим на исправленный код:


// Создаем объект для работы со справочником "ТипыБланков"
Спр = СоздатьОбъект("Справочник.ТипыБланков"); 

// Ищем элемент по коду и проверяем, что он найден
Если Спр.НайтиПоКоду("401951") = 1 Тогда
    // Правильное присваивание.
    // Реквизиту "ТипБСО" присваивается ссылка на найденный элемент.
    ТипБСО = Спр.ТекущийЭлемент();
КонецЕсли;

В этом варианте реквизит ТипБСО получает полноценную ссылку на элемент справочника с кодом "401951". Теперь, если пользователь нажмет на кнопку выбора в этом поле, форма справочника откроется с курсором, уже установленным на нужном элементе.

Дополнительные важные моменты

При реализации подобной логики стоит учитывать еще несколько аспектов.

Различие реквизитов формы и документа

Важно понимать, с чем вы работаете: с реквизитом формы или с реквизитом самого документа.

Пример для реквизита документа в контексте модуля формы документа:


Процедура УстановитьТипБСОПоУмолчанию()
    Спр = СоздатьОбъект("Справочник.ТипыБланков"); 

    Если Спр.НайтиПоКоду("401951") = 1 Тогда
        // Предполагаем, что ТипБСО - это реквизит документа
        ТипБСО = Спр.ТекущийЭleмент();
        
        // Если нужно сразу сохранить изменение в базе данных, 
        // не дожидаясь, пока пользователь нажмет "ОК" или "Записать"
        // Записать(); 
        // Примечание: вызов Записать() внутри других процедур может быть 
        // нежелателен, так как это приведет к записи всего документа.
        // Обычно достаточно просто изменить значение реквизита на форме.
    КонецЕсли;
КонецПроцедуры

// Этот код можно вызвать, например, при открытии формы
Процедура ПриОткрытии()
    // Устанавливаем значение по умолчанию, если документ новый
    Если ЭтоНовый() = 1 Тогда
        УстановитьТипБСОПоУмолчанию();
    КонецЕсли;
КонецПроцедуры

Использование метода АктивизироватьОбъект()

В некоторых задачах требуется не просто установить значение в поле, а открыть форму списка справочника и программно установить на ней курсор. Для этого предназначен метод АктивизироватьОбъект(). Он применяется к объекту формы списка.

Пример: представим, что у нас есть открытая форма списка справочника, и мы хотим спозиционироваться на нужном элементе.


// Получим нужный элемент
Спр = СоздатьОбъект("Справочник.ТипыБланков");
Спр.НайтиПоКоду("401951");
НужныйЭлемент = Спр.ТекущийЭлемент();

// Предположим, у нас есть открытая форма списка справочника
// и мы получили ее контекст в переменную ФормаСписка
Если ТипЗначения(НужныйЭлемент) = 11 Тогда // Убедимся, что элемент найден
    ФормаСписка.АктивизироватьОбъект(НужныйЭлемент);
КонецЕсли;

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

Итак, главный вывод: при работе с реквизитами ссылочных типов (справочники, документы и т.д.) всегда присваивайте им сам объект (ссылку), а не отдельные его свойства, такие как Код или Наименование.

← На главную