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