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

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

Как обратиться к объекту 1С из встроенного языка

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

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

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

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

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

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

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

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

Обращение к справочникам

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

Основные методы поиска: НайтиПоКоду("000001"), НайтиПоНаименованию("Стул"), НайтиПоРеквизиту("Артикул", "АРТ-15"). Каждый из них возвращает ссылку, а если ничего не найдено — пустую ссылку, которую обязательно нужно проверить перед использованием.

Создание нового элемента

Новый элемент создаётся методом СоздатьЭлемент() (для групп — СоздатьГруппу()). После заполнения реквизитов вызывается Записать(), и только после записи у элемента появляется ссылка, доступная через свойство Ссылка.

bsl
Найденный = Справочники.Номенклатура.НайтиПоКоду("000001");
Если Найденный.Пустая() Тогда
    НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
    НовыйЭлемент.Наименование = "Новый товар";
    НовыйЭлемент.Записать();
    СсылкаНаТовар = НовыйЭлемент.Ссылка;
Иначе
    СсылкаНаТовар = Найденный;
КонецЕсли;

Обращение к документам

Документы ищут методом НайтиПоНомеру("0001-000001", Дата) — второй параметр ограничивает период поиска и сильно ускоряет работу. Если номер неизвестен, используют запрос с отбором по реквизитам. Обращение к менеджеру — Документы.РеализацияТоваровУслуг.

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

bsl
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ДокОбъект.Комментарий = "Скорректировано обработкой";
Для Каждого СтрокаТовара Из ДокОбъект.Товары Цикл
    СтрокаТовара.Цена = СтрокаТовара.Цена * 1.1;
КонецЦикла;
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);

Обращение к регистрам сведений и накопления

К регистрам сведений обращаются через менеджеры записей и наборы записей. Чтение одной записи по ключу выполняется так: создаётся менеджер записи РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи(), заполняются измерения и период, вызывается Прочитать(). Если запись не найдена, проверяют метод Выбран().

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

Обращение через запросы

Когда нужно найти объекты по сложному условию или обработать множество записей, используют объект Запрос. Текст пишется на языке запросов 1С, обращение к таблице — по имени метаданных: ВЫБРАТЬ Ссылка ИЗ Справочник.Номенклатура ГДЕ ПометкаУдаления = ЛОЖЬ.

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

Способы обращения к данным

Методы НайтиПо*

Быстро для точного поиска по коду, номеру или реквизиту. Не подходят для сложных условий и массовой выборки.

Запрос

Гибкие отборы, соединения, итоги. Оптимален для массовых операций, но требует знания языка запросов.

ПолучитьОбъект()

Единственный способ изменить данные. Дорогой по ресурсам, не применять в цикле без необходимости.

Обращение к реквизитам и табличным частям

Реквизиты объекта доступны через точку по имени, заданному в конфигураторе: Объект.Организация, Ссылка.Валюта. Табличные части перебираются циклом Для Каждого ... Из Объект.Товары, а у ссылки табличная часть доступна только на чтение.

Если имя реквизита известно только в строковой переменной, используют обращение через квадратные скобки: Объект[ИмяРеквизита]. Это удобно в универсальных обработках, но лишает контроля со стороны компилятора — ошибку в имени вы увидите только во время выполнения.

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

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

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

Любые пакетные изменения выполняйте сначала на копии базы. Перед массовой записью объектов делайте резервную копию, а в коде используйте транзакции, чтобы при ошибке в середине цикла база не осталась в частично изменённом состоянии.

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

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

Результат поиска
Норма

Ссылка не пустая, реквизиты читаются

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

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

Запись объекта
Норма

Записать() отработал без исключения, изменения видны в форме

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

Ошибка записи, данные в базе не изменились

Проведение документа
Норма

Документ проведён, движения появились в регистрах

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

Документ сохранён, но не проведён, движений нет

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

Чем отличается НайтиПоНаименованию от НайтиПоРеквизиту?

НайтиПоНаименованию ищет только по стандартному реквизиту «Наименование» и по умолчанию — по точному совпадению. НайтиПоРеквизиту работает с любым реквизитом, по которому построен индекс, и подходит для поиска по артикулу, ИНН и другим полям.

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

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

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

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

Как обратиться к объекту, если имя метаданных хранится в строке?

Используйте обращение через квадратные скобки к менеджеру: Справочники[ИмяСправочника].НайтиПоКоду(Код). Это стандартный приём для универсальных обработок, работающих с разными типами объектов.

Почему обработка с циклом по объектам работает медленно?

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

Что делать, если документ не проводится из кода?

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

Итог

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

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