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

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

Как получить объект в модуле менеджера 1С

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

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

Главная сложность для начинающих разработчиков — понимание разницы между ссылкой и объектом. Ссылка — это лёгкий идентификатор записи в базе, а объект — полноценная структура в памяти, которую можно изменять и записывать. В модуле менеджера вы работаете с обоими типами, но получаете их разными способами.

Ниже разобраны все рабочие способы получить объект в модуле менеджера: через ссылку, по коду или наименованию, через запрос, а также создание нового объекта. Для каждого способа указаны условия применения и ограничения.

Разница между ссылкой и объектом: что именно нужно получить

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

Объект в памяти занимает больше ресурсов и требует явного вызова Записать() для сохранения. Массовое получение объектов в цикле — классическая причина медленной работы обработок: на каждой итерации выполняется чтение всей записи из базы. Если нужно только перебрать данные, используйте запрос.

Получение объекта через ссылку методом ПолучитьОбъект()

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

Пример экспортной функции в модуле менеджера справочника:

Функция ПолучитьНаименованиеДляПечати(ЭлементСсылка) Экспорт

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

Возврат СокрЛП(ОбъектЭлемента.Наименование);

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

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

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

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

Поиск по коду или номеру

Функция НайтиЭлементПоКоду(КодЭлемента) Экспорт

НайденнаяСсылка = НайтиПоКоду(КодЭлемента);

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

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

КонецЕсли;

Возврат НайденнаяСсылка.ПолучитьОбъект();

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

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

Поиск через запрос

Когда критерий поиска сложнее кода или наименования, в модуле менеджера выполняют запрос и из выборки получают ссылку, а затем объект:

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

Запрос.Текст =

"ВЫБРАТЬ ПЕРВЫЕ 1

| Номенклатура.Ссылка КАК Ссылка

|ИЗ

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

|ГДЕ

| Номенклатура.Артикул = &Артикул";

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

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

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

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

КонецЕсли;

Создание нового объекта из модуля менеджера

Если нужен не существующий, а новый элемент, менеджер сам создаёт объект: СоздатьЭлемент() для справочников, СоздатьДокумент() для документов, СоздатьГруппу() для групп иерархических справочников. В модуле менеджера эти методы доступны напрямую.

Функция СоздатьНовыйЭлемент(НаименованиеЭлемента) Экспорт

НовыйОбъект = СоздатьЭлемент();

НовыйОбъект.Наименование = НаименованиеЭлемента;

НовыйОбъект.Записать();

Возврат НовыйОбъект.Ссылка;

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

После Записать() у объекта появляется ссылка, которую удобно вернуть из функции. Типичный шаблон — сначала попытаться найти существующий элемент, и только если его нет, создавать новый. Это защищает базу от дублей при повторных вызовах.

Порядок действий
  1. 1
    Определите, нужен объект для чтения или для изменения
  2. 2
    Получите ссылку: параметр, НайтиПоКоду, НайтиПоНаименованию или запрос
  3. 3
    Проверьте ссылку на Пустая() и результат ПолучитьОбъект() на Неопределено
  4. 4
    Внесите изменения и вызовите Записать()
  5. 5
    Проверьте в базе, что данные сохранились корректно

Работа с объектом: изменение и запись

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

Для документов помните о режиме записи: Записать(РежимЗаписиДокумента.Проведение) проводит документ, а обычный Записать() — только сохраняет. Проведение из модуля менеджера — допустимая практика, но массовое перепроведение лучше выполнять порциями с обработкой ошибок, чтобы одна проблемная запись не остановила весь процесс.

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

Когда объект получать не нужно: альтернативы

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

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

Маршрут решения

Как выбрать действие

Нужно только прочитать данные одного элементаОбратитесь к реквизитам через ссылку или выполните запрос
Нужно изменить и сохранить элементПолучите объект через Ссылка.ПолучитьОбъект(), измените, вызовите Записать()
Элемента ещё нет в базеСоздайте его через СоздатьЭлемент() или СоздатьДокумент()
Нужно обработать много записейИспользуйте запрос; ПолучитьОбъект() только там, где требуется запись

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

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

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

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

Ссылка после НайтиПоКоду
Норма

Ссылка.Пустая() возвращает Ложь

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

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

Результат ПолучитьОбъект()
Норма

Возвращён объект, реквизиты читаются

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

Неопределено — запись удалена, ссылка битая

Данные после Записать()
Норма

Запрос возвращает обновлённые значения

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

Значения старые — Записать() не вызван или завершился ошибкой

Часто задаваемые вопросы

Чем ПолучитьОбъект() отличается от обращения к реквизитам через ссылку?

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

Почему ПолучитьОбъект() возвращает Неопределено?

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

Можно ли в модуле менеджера вызывать методы без префикса Справочники.Имя?

Да. Внутри модуля менеджера методы НайтиПоКоду, НайтиПоНаименованию, СоздатьЭлемент, ПустаяСсылка и другие доступны напрямую, так как контекст менеджера уже задан.

Как получить ссылку на предопределённый элемент?

Через точку от менеджера по имени предопределённого элемента: Справочники.Валюты.Рубль, а внутри модуля менеджера — просто по имени. Также ссылку возвращает метод НайтиПоИмениПредопределенныхДанных().

Где размещать код: в модуле объекта или в модуле менеджера?

Логику конкретной записи (проверки, заполнение реквизитов) размещают в модуле объекта. Операции над множеством записей — поиск, создание, печать, начальное заполнение — в модуле менеджера.

Итог

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

Объект в модуле менеджера получают через Ссылка.ПолучитьОбъект() с обязательной проверкой на Неопределено, а новый — через СоздатьЭлемент() или СоздатьДокумент(). Для чтения данных предпочитайте запрос, объект запрашивайте только когда требуется изменение и запись.