Как программно найти элемент справочника по коду и открыть его форму в управляемом приложении?

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

В разработке на платформе 1С:Предприятие 8.3 одной из наиболее часто встречающихся задач является поиск объекта в базе данных по определенному признаку (например, по коду или наименованию) с последующим выводом этого объекта пользователю. Несмотря на кажущуюся простоту, новички часто сталкиваются с трудностями, связанными с клиент-серверным разделением. Давайте подробно разберем, как правильно реализовать этот механизм, соблюдая архитектурные требования управляемого приложения.

Разберем проблему контекста: почему нельзя сделать всё в одной процедуре?

Главная особенность управляемых форм — четкое разграничение полномочий между клиентом и сервером. Проанализируем, почему возникает ошибка при попытке объединить поиск и открытие формы:

  1. На сервере нам доступны все инструменты работы с базой данных. Мы можем использовать методы НайтиПоКоду(), НайтиПоНаименованию() или выполнять сложные запросы. Однако серверная часть программы «не видит» экран пользователя и не может инициализировать открытие окна.
  2. На клиенте мы имеем доступ к методам ОткрытьФорму() и ПоказатьЗначение(), которые отвечают за интерфейс. Но на клиенте запрещен прямой доступ к таблицам базы данных, и мы не можем просто так вызвать поиск элемента.

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

Шаг 1: Реализация серверного поиска

Для начала создадим функцию, которая будет принимать код и возвращать найденную ссылку. Рассмотрим наиболее оптимальный вариант с использованием директивы &НаСервереБезКонтекста. Это важно, так как такой вызов не передает данные всей формы на сервер, что значительно ускоряет работу системы.

Проанализируем пример кода для поиска в справочнике Организации:


&НаСервереБезКонтекста
Функция НайтиСсылкуПоКодуНаСервере(Знач КодЭлемента)
    // Используем метод поиска по коду для конкретного справочника
    НайденнаяСсылка = Справочники.Организации.НайтиПоКоду(КодЭлемента);
    Возврат НайденнаяСсылка;
КонецФункции

Важный момент: если элемент не будет найден, метод НайтиПоКоду() вернет пустую ссылку. Это не вызовет ошибку, но этот факт нам нужно будет обработать на следующем этапе.

Шаг 2: Клиентская логика и управление интерфейсом

Теперь рассмотрим, как вызвать эту функцию и что делать с результатом. На клиенте мы должны получить ссылку и проверить, является ли она валидной (не пустой).

Разберем по шагам клиентскую процедуру, которая запускается, например, при нажатии кнопки или завершении ввода кода пользователем:


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

КонецПроцедуры

Шаг 3: Обработка ситуации, когда элемент не найден

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

Если мы хотим не просто выдать ошибку, а сразу предложить пользователю создать новый объект с тем кодом, который он вводил, мы можем использовать параметр ЗначенияЗаполнения. Это позволит автоматически подставить данные в новую форму.

Рассмотрим расширенный пример кода:


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

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

Альтернативный метод: ПоказатьЗначение()

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

Плюсы этого метода:

Минусы:

Важные рекомендации по оптимизации

Проанализируем несколько технических нюансов, которые помогут сделать ваш код профессиональным:

  1. Уникальность кодов: Помните, что метод НайтиПоКоду() возвращает первый найденный элемент. Если в вашем справочнике коды уникальны только в пределах владельца или родителя, обязательно передавайте второй параметр в метод поиска.
  2. Асинхронность: При работе в веб-клиенте или мобильном клиенте всегда используйте ПоказатьВопрос вместо устаревшего метода Вопрос, так как последний блокирует поток выполнения и не поддерживается во многих современных режимах работы.
  3. Использование структуры Ключ: Помните, что если в ОткрытьФорму передан параметр Ключ, система ищет уже существующее окно с этим объектом. Если окно уже открыто, платформа просто активирует его, а не создаст дубль.

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

← На главную