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

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

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

Как обратиться к объекту справочника в 1С: менеджер, ссылка, объект, поиск по коду и наименованию, создание и изменение элементов, примеры кода на встроенном языке.

Обращение к объекту справочника — базовая операция при доработке конфигураций 1С. Через него выполняется чтение реквизитов, создание новых элементов, изменение существующих и установка пометки удаления. Ошибка на этом этапе приводит либо к падению кода с исключением, либо к неявным блокировкам и лишним запросам к базе данных.

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

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

Три представления справочника: менеджер, ссылка, объект

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

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

Объект — это редактируемая копия данных элемента в памяти. Его получают вызовом Ссылка.ПолучитьОбъект() или создают через Справочники.Имя.СоздатьЭлемент(). Все изменения выполняются в объекте и фиксируются методом Записать(). Именно на записи объекта срабатывают подписки на события, проверки заполнения и права доступа.

Как найти элемент справочника

Самый быстрый способ — поиск по коду, если код уникален и известен:

Элемент = Справочники.Номенклатура.НайтиПоКоду("000000123");

Если Не Элемент.Пустая() Тогда

Наименование = Элемент.Наименование;

КонецЕсли;

Поиск по наименованию поддерживает точное и неточное совпадение. Второй параметр Истина включает поиск по точному соответствию:

Элемент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Ромашка", Истина);

Для поиска по произвольному реквизиту используется НайтиПоРеквизиту(). Метод вернёт первый найденный элемент, поэтому он надёжен только для реквизитов с уникальными значениями (ИНН, артикул):

Контрагент = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", "7707083893");

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

Как создать и записать новый элемент

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

НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();

НовыйЭлемент.Наименование = "Кабель ВВГ 3х2.5";

НовыйЭлемент.Артикул = "КБ-325";

НовыйЭлемент.Записать();

СсылкаНаНовый = НовыйЭлемент.Ссылка;

Для иерархического справочника может потребоваться указать родителя: НовыйЭлемент.Родитель = ГруппаСсылка;. Группу создают отдельным методом СоздатьГруппу().

Если справочник подчинён владельцу (например, «Договоры» подчинены «Контрагентам»), перед записью обязательно заполните свойство Владелец, иначе запись завершится ошибкой.

Порядок действий при создании элемента
  1. 1
    Получите объект: Справочники.Имя.СоздатьЭлемент()
  2. 2
    Заполните наименование и обязательные реквизиты, при необходимости Родитель и Владелец
  3. 3
    Вызовите Записать() — здесь сработают проверки и подписки
  4. 4
    Проверьте результат: объект.Ссылка не пустая, элемент доступен в списке

Как изменить существующий элемент

Изменение всегда идёт через объект. Типовой шаблон: найти ссылку, получить объект, изменить, записать:

Ссылка = Справочники.Номенклатура.НайтиПоКоду("000000123");

Если Не Ссылка.Пустая() Тогда

Объект = Ссылка.ПолучитьОбъект();

Объект.Наименование = "Новое наименование";

Объект.Записать();

КонецЕсли;

Частая ошибка — попытка присвоить значение реквизиту напрямую через ссылку: Ссылка.Наименование = "..". Такой код вызовет исключение, потому что реквизиты ссылки доступны только для чтения.

Для установки пометки удаления изменять объект не нужно — есть метод ссылки УстановитьПометкуУдаления(Истина) или метод объекта УстановитьПометкуУдаления(). Физическое удаление выполняется штатной обработкой «Удаление помеченных объектов» и требует монопольного доступа.

Выборка элементов и обход в цикле

Для перебора элементов без сложных условий подходит метод Выбрать():

Выборка = Справочники.Номенклатура.Выбрать();

Пока Выборка.Следующий() Цикл

Сообщить(Выборка.Наименование);

КонецЦикла;

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

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ Ссылка, Наименование, Артикул

|ИЗ Справочник.Номенклатура

|ГДЕ НЕ ПометкаУдаления";

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

Сравнение вариантов обхода

Выбрать() в цикле

Простой код для небольших справочников; на больших объёмах медленный из-за запросов на каждой итерации

Запрос

Одно обращение к базе, гибкие условия и нужные поля; требует написания текста запроса

НайтиПоКоду/Наименованию

Мгновенный поиск одного элемента по индексированным полям; не подходит для сложных условий

Обращение к справочнику в форме и через COM

В форме элемента текущие данные доступны через реквизит формы Объект (тип ДанныеФормыСтруктура), а не как СправочникОбъект. Чтобы получить настоящий объект для записи, используют РеквизитФормыВЗначение("Объект"), а после изменения — обратное преобразование. На клиенте объект недоступен вовсе: изменение выполняется на сервере.

При обмене через COM-соединение обращение выглядит так же, но через объект соединения: Соединение.Справочники.Номенклатура.НайтиПоКоду(..).

Типичные ошибки и как их проверить

Типичные ошибки
01
Присвоение реквизиту через ссылку: Ссылка.Наименование =.. — исключение, реквизиты ссылки только для чтения
02
Отсутствие проверки на пустую ссылку после поиска — обращение к реквизитам несуществующего элемента
03
Чтение реквизитов ссылки в цикле — сотни лишних запросов к базе вместо одного запроса
04
Забытый Записать() после изменения объекта — изменения теряются без ошибки
05
Запись без заполнения Владелец или Родитель в подчинённых и иерархических справочниках — ошибка записи

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

Итог

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

Менеджер (Справочники.Имя) ищет и создаёт, ссылка читает, объект изменяет и записывается через Записать(). После поиска проверяйте пустоту ссылки, для массовых операций используйте запрос, а массовые изменения сначала испытывайте на копии базы.

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

Чем ссылка отличается от объекта справочника?

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

Как проверить, что элемент найден?

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

Можно ли изменить элемент без ПолучитьОбъект()?

Нет, изменение реквизитов возможно только через объект. Исключение — пометка удаления, которую можно переключить методом УстановитьПометкуУдаления() прямо у ссылки.

Как обратиться к табличной части элемента справочника?

Через объект: после ПолучитьОбъект() табличная часть доступна как коллекция, например Объект.ДополнительныеРеквизиты. Строки добавляются методом Добавить(), изменения сохраняются общим вызовом Записать().

Почему НайтиПоНаименованию не находит элемент?

Чаще всего из-за неразрывных пробелов, лишних пробелов или регистра в искомой строке, а также потому что поиск по умолчанию выполняется по началу наименования. Проверьте точное значение в базе и используйте второй параметр Истина для поиска по точному соответствию.

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

Методом ПолучитьСсылку() у менеджера можно заранее получить новую ссылку и назначить её объекту через УстановитьСсылкуНового(). Это нужно, когда на создаваемый элемент должны ссылаться другие записи, записываемые в той же транзакции.