Почему не присваивается ссылка создаваемому документу при использовании УстановитьСсылкуНового()?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Анализ механизма работы ссылок в платформе 1С

Выясним причину, по которой прямое обращение к свойству Ссылка не дает результата. В платформе 1С объект типа ДокументОбъект и его ссылка в базе данных — это разные сущности. Свойство Ссылка (Ref) заполняется платформой автоматически только в момент фактической фиксации записи в таблицах СУБД.

Когда мы вызываем метод УстановитьСсылкуНового(), мы не меняем текущее состояние свойства Ссылка. Мы лишь даем платформе команду: «Когда этот объект будет записываться, используй вот этот конкретный УникальныйИдентификатор (GUID)». До момента вызова Записать() ссылка считается «виртуальной».

Рассмотрим пример кода, который часто вызывает вопросы у разработчиков:


НовыйДокумент = Документы.ОперацияБух.СоздатьДокумент();
НоваяСсылка = Документы.ОперацияБух.ПолучитьСсылку(Новый УникальныйИдентификатор());
НовыйДокумент.УстановитьСсылкуНового(НоваяСсылка);

// В этой точке НовыйДокумент.Ссылка все еще будет пустой (00000000-0000-0000-0000-000000000000)

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

Как правильно получить и проверить ссылку до записи

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

  1. Генерируем или получаем нужный идентификатор (GUID).
  2. Получаем пустую ссылку нужного типа через менеджер документа.
  3. Устанавливаем эту ссылку объекту.
  4. Проверяем результат специальным методом.

// 1. Создаем объект
ДокументОбъект = Документы.ОперацияБух.СоздатьДокумент();

// 2. Формируем будущую ссылку (можно передать свой GUID)
БудущаяСсылка = Документы.ОперацияБух.ПолучитьСсылку(Новый УникальныйИдентификатор);

// 3. Бронируем эту ссылку за объектом
ДокументОбъект.УстановитьСсылкуНового(БудущаяСсылка);

// 4. Проверяем. Внимание: смотрим НЕ Ссылка, а ПолучитьСсылкуНового()
ЗарезервированныйИдентификатор = ДокументОбъект.ПолучитьСсылкуНового();

Если ЗарезервированныйИдентификатор = БудущаяСсылка Тогда
    Сообщить("Ссылка успешно забронирована!");
КонецЕсли;

Проблема записи движений для незаписанного документа

Рассмотрим ситуацию, когда разработчик пытается записать набор записей регистра (например, РегистрБухгалтерии), используя в качестве регистратора ссылку, которая еще не существует в базе. Проанализируем последствия: на уровне СУБД существует контроль ссылочной целостности. Если вы попытаетесь вызвать НаборЗаписей.Записать(), где Регистратор — это незаписанный документ, система выдаст ошибку.

Однако существует легальный способ сделать это в рамках одной транзакции. Проанализируем последовательность действий:

  1. Открываем транзакцию через НачатьТранзакцию().
  2. Создаем документ и устанавливаем ему ссылку через УстановитьСсылкуНового().
  3. Обязательно записываем документ ДокументОбъект.Записать(). Теперь ссылка физически существует в базе, но видна только внутри вашей транзакции.
  4. Создаем набор записей регистра, устанавливаем отбор по нашей ссылке и записываем его.
  5. Фиксируем транзакцию ЗафиксироватьТранзакцию().

Если в процессе возникнет ошибка или пользователь передумает, ОтменитьТранзакцию() удалит и документ, и его движения из базы полностью.

Особенности работы в управляемых формах

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

Рассмотрим правильный подход для управляемого приложения: использование параметров заполнения. Вместо ручной манипуляции GUID-ами, лучше передать данные в структуру ЗначениеЗаполнения. Но если ссылка принципиально важна (например, для сложной интеграции), следует передавать её в параметрах формы и обрабатывать в событии ПриСозданииНаСервере на стороне формы документа, вызывая там УстановитьСсылкуНового() для основного реквизита Объект.

Резюме и рекомендации

Подведем итоги нашего анализа:

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

← На главную