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