При разработке на платформе 1С:Предприятие часто возникает задача программного создания документов или элементов справочников. Начинающие разработчики нередко сталкиваются с вопросом: как правильно получить ссылку на только что созданный объект, чтобы использовать её в дальнейшем коде или заполнить связанные данные. В этой статье мы подробно разберем, как работать с новыми объектами, в чем разница между различными методами получения ссылки и как правильно наполнять документ данными.
Для начала рассмотрим классическую ситуацию, когда нам необходимо создать документ РеализацияТоваровУслуг. Когда мы вызываем метод СоздатьДокумент(), платформа выделяет область памяти под новый объект типа ДокументОбъект. Важно понимать, что на этом этапе объект существует только в оперативной памяти и еще не записан в базу данных.
Рассмотрим пример кода, с которого началось обсуждение:
ДокРеализация = Документы.РеализацияТоваров.СоздатьДокумент();
ДокРеализация.Дата = ТекущаяДата();
ДокРеализация.Контрагент = ВыбранныйКонтрагент;
ДокРеализация.Организация = ВыбраннаяОрганизация;
// Заполнение других реквизитов...
Многие разработчики полагают, что для добавления строк в табличную часть (например, «Товары») им обязательно нужна ссылка на этот документ. На самом деле, это распространенное заблуждение. Поскольку переменная ДокРеализация уже содержит в себе весь объект, мы можем обращаться к его коллекциям напрямую.
Давайте выясним, как правильно добавить номенклатуру в документ. Поскольку мы работаем с самим объектом, нам не нужно искать его в базе по ссылке. Мы обращаемся к табличной части как к свойству объекта.
// Добавляем новую строку в табличную часть "Товары"
НоваяСтрока = ДокРеализация.Товары.Добавить();
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоНаименованию("Услуга по доставке");
НоваяСтрока.Количество = 1;
НоваяСтрока.Цена = 1000;
НоваяСтрока.Сумма = 1000;
В данном сценарии ссылка (Ref) на документ еще не сформирована окончательно (она является «пустой» или временной), но это не мешает нам полностью подготовить данные документа к записи.
Если вам все же необходима ссылка (например, чтобы записать её в другой связанный документ или вывести пользователю сообщение), самый простой и надежный способ — обратиться к свойству Ссылка после выполнения метода Записать().
Проанализируем, что происходит в этот момент: когда вызывается ДокРеализация.Записать(), платформа физически создает запись в таблице базы данных. Именно в этот момент объекту присваивается уникальный идентификатор (GUID). После успешной записи свойство ДокРеализация.Ссылка будет содержать актуальную рабочую ссылку.
ДокРеализация.Записать(РежимЗаписиДокумента.Запись);
СсылкаНаНовыйДокумент = ДокРеализация.Ссылка;
Сообщить("Создан документ: " + СсылкаНаНовыйДокумент);
Важный нюанс по оптимизации: Существует мнение, что обращение к свойству .Ссылка сразу после записи неоптимально. Однако это не так. Объект в данный момент находится в кэше оперативной памяти, и платформа не выполняет повторный запрос SELECT к базе данных для получения этого значения.
Иногда возникают сложные задачи, когда ссылку на документ нужно знать до того, как он будет физически записан в базу. Например, если в рамках одной транзакции вы создаете документ и одновременно должны создать записи в независимом регистре сведений, где этот документ должен быть указан как «Регистратор» или «Владелец».
Для этих целей предназначен метод ПолучитьСсылкуНового(). Разберем по шагам, как он работает:
ПолучитьСсылкуНового() у объекта, который еще не записан.Пример использования:
БудущаяСсылка = ДокРеализация.ПолучитьСсылкуНового();
Если БудущаяСсылка.Пустая() Тогда
// Если платформа еще не сгенерировала идентификатор, можно принудительно его получить
ДокРеализация.УстановитьСсылкуНового(Документы.РеализацияТоваров.ПолучитьСсылку());
БудущаяСсылка = ДокРеализация.ПолучитьСсылкуНового();
КонецЕсли;
Осторожно: Если вы получили ссылку через ПолучитьСсылкуНового(), использовали её где-то в коде, но затем по какой-то причине метод Записать() не отработал (произошла ошибка или отказ в событии ПередЗаписью), вы получите «битую» ссылку. В базе данных объекта не будет, а в других местах кода останется ссылка на несуществующий GUID.
Рассмотрим ситуацию, если вы работаете в современном интерфейсе 1С (Управляемое приложение). В модуле формы вы работаете не с самим объектом напрямую, а с данными формы (тип ДанныеФормыСтруктура).
Если вам нужно получить ссылку на объект, который редактирует пользователь на экране, но который еще не записан, алгоритм будет следующим:
ОбъектБолванка = РеквизитФормыВЗначение("Объект");ОбъектБолванка.ПолучитьСсылкуНового().Однако чаще всего в управляемых формах достаточно дождаться события ПослеЗаписиНаСервере, где ссылка уже будет доступна в реквизите Объект.Ссылка.
Посмотрим на ошибки, которые часто встречаются в коде начинающих разработчиков:
ПустаяСсылка.Объект = Документы.РеализацияТоваров.ПолучитьСсылку() создаст новую пустую ссылку, но она никак не будет связана с вашим создаваемым объектом ДокРеализация, пока вы явно не укажете её через УстановитьСсылкуНового().Подведем итог нашему разбору. Если вам нужно просто заполнить табличную часть создаваемого документа номенклатурой, вам не нужна ссылка — работайте напрямую с объектом в памяти. Если ссылка нужна для передачи в другие процедуры после создания документа, используйте свойство .Ссылка сразу после вызова Записать(). В исключительных случаях, когда ссылка требуется строго до момента фиксации данных в БД, применяйте ПолучитьСсылкуНового().
Правильное понимание жизненного цикла объекта в 1С и механизмов кэширования позволяет писать не только работоспособный, но и максимально производительный код.