К статье
Практический материал

Разработка и Конфигурация · 13 мин

Как обратиться к справочнику на клиенте в 1С

Как обратиться к справочнику на клиенте в 1С: директива &НаКлиенте, работа с формой списка, выбор значения, безопасные приёмы и типичные ошибки разработчика.

Обращение к справочнику на клиенте в 1С — одна из типовых задач при разработке управляемых форм. Однако здесь есть важное ограничение: в клиентском контексте недоступны объектные методы работы с данными, такие как Справочники.Номенклатура.НайтиПоКоду() или создание объектов через менеджер справочника. Попытка использовать их приведёт к ошибке компиляции или выполнения.

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

Ниже разобраны все рабочие сценарии с примерами кода, ограничения каждого подхода и способы проверить результат. Материал ориентирован на управляемые формы (тонкий клиент, веб-клиент); для обычных форм часть ограничений не действует, но и такие конфигурации встречаются всё реже.

Почему на клиенте нельзя работать со справочником напрямую

В управляемом приложении 1С код явно делится на контексты с помощью директив компиляции: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста и &НаКлиентеНаСервереБезКонтекста. Клиентский контекст не имеет доступа к менеджерам объектов — Справочники, Документы, Запрос там недоступны.

Это не произвольное ограничение, а следствие трёхзвенной архитектуры. Тонкий клиент может выполняться на машине пользователя, где нет ни соединения с СУБД, ни прав на прямое чтение таблиц. Вся логика доступа к данным сосредоточена на сервере 1С:Предприятия, что одновременно повышает безопасность и снижает требования к клиентским машинам.

Практический вывод: если в процедуре с директивой &НаКлиенте вы написали Справочники.Контрагенты.НайтиПоНаименованию(...), модуль просто не скомпилируется, а при использовании Вычислить() или выполнении в толстом клиенте вы получите ошибку времени выполнения. Проверяйте директиву компиляции до написания кода.

Открытие формы списка или элемента справочника

Самый частый сценарий обращения к справочнику на клиенте — показать пользователю список или карточку элемента. Для этого используется функция ОткрытьФорму(), которая полностью выполняется на клиенте и не требует серверного вызова для своего запуска.

Чтобы открыть список справочника, достаточно указать имя формы в формате Справочник.ИмяСправочника.ФормаСписка. Если нужна конкретная форма, созданная в конфигураторе, укажите её имя: Справочник.Номенклатура.Форма.ФормаСпискаПродаж.

&НаКлиенте

Процедура ПоказатьНоменклатуру(Команда)

ОткрытьФорму("Справочник.Номенклатура.ФормаСписка");

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

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

&НаКлиенте

Процедура ОткрытьКарточку(Команда)

ПараметрыФормы = Новый Структура("Ключ", ТекущийКонтрагент);

ОткрытьФорму("Справочник.Контрагенты.ФормаОбъекта", ПараметрыФормы);

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

Дополнительно через параметры можно передать отбор для списка (Структура("Отбор", ...)), владельца формы и уникальность. Отбор по реквизиту — удобный способ показать пользователю уже отфильтрованный список без программирования динамического списка.

Выбор значения из справочника на клиенте

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

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

&НаКлиенте

Процедура ВыбратьКонтрагента(Команда)

Оповещение = Новый ОписаниеОповещения("ПослеВыбораКонтрагента", ЭтотОбъект);

ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", , ЭтотОбъект, , , , Оповещение);

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

&НаКлиенте

Процедура ПослеВыбораКонтрагента(Результат, ДопПараметры) Экспорт

Если Результат <> Неопределено Тогда

Контрагент = Результат; // ссылка на выбранный элемент

КонецЕсли;

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

Порядок организации выбора из справочника
  1. 1
    Создайте клиентскую процедуру-обработчик с параметрами (Результат, ДополнительныеПараметры) и директивой Экспорт
  2. 2
    В основной процедуре сформируйте Новый ОписаниеОповещения с именем обработчика и ЭтотОбъект
  3. 3
    Откройте форму выбора справочника, передав оповещение последним параметром
  4. 4
    В обработчике проверьте Результат на Неопределено — пользователь мог закрыть форму без выбора
  5. 5
    Сохраните полученную ссылку в реквизит формы или передайте на сервер для дальнейшей обработки

Для поля ввода на форме выбор работает ещё проще: если реквизит формы имеет тип ссылки на справочник, платформа автоматически показывает форму выбора при нажатии кнопки выбора. Дополнительный код нужен только для нестандартной обработки — например, в событии ОбработкаВыбора элемента формы.

Получение данных справочника через серверный вызов

Когда на клиенте нужны данные элемента — наименование, реквизиты, результаты поиска — единственный корректный путь: вызвать серверную процедуру, которая обратится к справочнику и вернёт результат. На клиенте при этом должна быть ссылка или параметры поиска.

Серверная процедура размещается либо в модуле формы с директивой &НаСервере или &НаСервереБезКонтекста, либо в общем модуле с признаками «Сервер» и «Вызов сервера». Второй вариант предпочтителен, если функция используется из нескольких форм.

&НаСервереБезКонтекста

Функция ПолучитьРеквизитыКонтрагента(Ссылка)

Запрос = Новый Запрос("ВЫБРАТЬ Наименование, ИНН ИЗ Справочник.Контрагенты ГДЕ Ссылка = &Ссылка");

Запрос.УстановитьПараметр("Ссылка", Ссылка);

Выборка = Запрос.Выполнить().Выбрать();

Если Выборка.Следующий() Тогда

Возврат Новый Структура("Наименование, ИНН", Выборка.Наименование, Выборка.ИНН);

КонецЕсли;

Возврат Неопределено;

КонецФункции

&НаКлиенте

Процедура ЗаполнитьДанные(Команда)

Данные = ПолучитьРеквизитыКонтрагента(Контрагент);

Если Данные <> Неопределено Тогда

ИНН = Данные.ИНН;

КонецЕсли;

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

Обратите внимание на типы возвращаемых значений. С клиента на сервер и обратно передаются только сериализуемые данные: примитивные типы, структуры, массивы, ссылки. Нельзя вернуть объект справочника (СправочникОбъект), результат запроса или выборку — это вызовет ошибку сериализации. Возвращайте структуру с нужными полями.

Работа с динамическим списком справочника на форме

Если справочник выведен на форму как динамический список (основной реквизит типа ДинамическийСписок), обращаться к нему на клиенте можно через элемент формы — таблицу, отображающую список. Доступны текущая строка, выделенные строки, программная установка отбора и параметров.

Типовые действия: получить ссылку текущей строки через Элементы.Список.ТекущиеДанные.Ссылка, обойти выделенные строки через Элементы.Список.ВыделенныеСтроки, обновить список методом Элементы.Список.Обновить() после внешних изменений данных.

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

Способы обращения к справочнику с клиента

ОткрытьФорму

Подходит для показа списка или карточки элемента. Не возвращает данные, только открывает интерфейс

Форма выбора с оповещением

Подходит для выбора значения пользователем. Возвращает ссылку, требует асинхронного обработчика

Серверный вызов

Подходит для чтения реквизитов и поиска. Требует серверной процедуры и сериализуемых типов возврата

Динамический список на форме

Подходит для работы со списком, уже размещённым на форме: отборы, текущая строка, обновление

Типичные ошибки и как их избежать

Первая и самая частая ошибка — попытка использовать менеджер справочника в клиентской процедуре. Код вроде Справочники.Валюты.НайтиПоКоду("840") под &НаКлиенте не компилируется в тонком клиенте. Решение — вынести поиск в серверную функцию и вернуть ссылку.

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

Третья группа ошибок — производительность: серверные вызовы в цикле при обработке табличной части, чтение реквизитов «через точку» от ссылки в клиентском коде (каждое обращение через точку к реквизиту ссылки на клиенте — это отдельный неявный запрос). Если нужны пять реквизитов элемента — получите их одним запросом на сервере в структуру.

Типичные ошибки
01
Вызов Справочники.Имя.НайтиПо...() на клиенте — ошибка компиляции в тонком клиенте; выносите поиск на сервер
02
Возврат СправочникОбъект с сервера — ошибка сериализации; возвращайте структуру с нужными полями
03
Серверный вызов внутри цикла по строкам — резкое падение скорости; делайте один пакетный запрос
04
Обращение к реквизитам ссылки через точку на клиенте — скрытые запросы к базе на каждое обращение
05
Игнорирование Неопределено в обработчике выбора — ошибка, когда пользователь закрыл форму без выбора

Проверка результата и отладка

Убедиться, что обращение к справочнику отработало правильно, можно несколькими способами. Для формы выбора: после выбора проверьте, что реквизит формы заполнился ссылкой — выведите её через Сообщить() или посмотрите в отладчике. Для серверного вызова: поставьте точку останова в серверной процедуре и проверьте, что запрос вернул строки.

При отладке серверных вызовов включите в конфигураторе отладку на сервере (параметр отладки сервера 1С), иначе точки останова в серверном контексте не сработают. В веб-клиенте дополнительно проверяйте, что серверная процедура доступна — общий модуль должен иметь флажки «Сервер» и «Вызов сервера».

Контрольные точки

Как проверить результат

Компиляция модуля формы
Норма

Модуль сохраняется без ошибок при проверке в конфигураторе

Тревожный признак

Ошибка «Переменная не определена (Справочники)» — объектный код в клиентском контексте

Выбор из формы выбора
Норма

Обработчик оповещения получает ссылку, реквизит формы заполняется

Тревожный признак

Результат всегда Неопределено — форма открыта без передачи оповещения

Серверный вызов
Норма

Функция возвращает структуру с данными, клиент их получает

Тревожный признак

Ошибка сериализации или пустой результат — проверьте типы и параметры запроса

Полезная практика — проверять права пользователя. Если у учётной записи нет прав на чтение справочника, форма списка откроется пустой, а серверный запрос вернёт пустой результат без явной ошибки. При подозрительном «молчаливом» отсутствии данных проверьте роли и RLS-ограничения.

Итог

Что важно запомнить

На клиенте справочник доступен только через интерфейс: открытие форм, выбор значения, динамический список. Чтение и поиск данных выполняются на сервере, а на клиент возвращаются сериализуемые структуры. Избегайте модальных вызовов, серверных вызовов в цикле и обращений к реквизитам ссылки через точку.

Частые вопросы

Можно ли создать новый элемент справочника на клиенте?

Напрямую — нет: создание и запись объекта возможны только на сервере. На клиенте можно открыть форму нового элемента через ОткрытьФорму("Справочник.Имя.ФормаОбъекта") — пользователь заполнит и запишет его сам. Либо вызвать серверную процедуру, которая создаст элемент программно и вернёт ссылку.

Как получить наименование элемента по ссылке на клиенте?

Обращение вида Ссылка.Наименование на клиенте технически сработает, но выполнит скрытый запрос к базе. Для разового показа это допустимо, но в циклах и массовых операциях получайте наименования пакетно через серверный запрос, возвращающий соответствие или массив структур.

Почему ОткрытьФормуМодально выдаёт ошибку?

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

Как открыть список справочника с отбором по реквизиту?

Передайте в ОткрытьФорму структуру параметров с ключом Отбор, содержащим вложенную структуру: Новый Структура("Отбор", Новый Структура("Владелец", СсылкаНаВладельца)). Платформа применит отбор к стандартной форме списка автоматически.

Чем отличается &НаСервере от &НаСервереБезКонтекста при работе со справочником?

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

Можно ли выполнить запрос к справочнику на клиенте через Выполнить()?

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