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

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

Как в 1С получить ссылку на новый документ

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

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

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

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

Чем объект документа отличается от ссылки

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

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

Получение ссылки до записи: ПолучитьСсылку и УстановитьСсылкуНового

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

НоваяСсылка = Документы.РеализацияТоваровУслуг.ПолучитьСсылку();

ДокОбъект = Документы.РеализацияТоваровУслуг.СоздатьДокумент();

ДокОбъект.УстановитьСсылкуНового(НоваяСсылка);

ДокОбъект.Дата = ТекущаяДатаСеанса();

// ... заполнение реквизитов

ДокОбъект.Записать();

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

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

Получение ссылки после записи документа

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

ДокОбъект = Документы.ПриходныйОрдер.СоздатьДокумент();

ДокОбъект.Дата = ТекущаяДатаСеанса();

// заполнение реквизитов

ДокОбъект.Записать();

СсылкаНаДокумент = ДокОбъект.Ссылка;

Если документ записывается с проведением (РежимЗаписиДокумента.Проведение), ссылка формируется на этапе записи, до проведения, поэтому она доступна сразу после завершения метода Записать() независимо от режима.

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

Порядок действий при программном создании
  1. 1
    Создайте объект через Документы.ВидДокумента.СоздатьДокумент()
  2. 2
    При необходимости заранее получите ссылку: ПолучитьСсылку() и УстановитьСсылкуНового()
  3. 3
    Заполните дату и обязательные реквизиты
  4. 4
    Вызовите Записать() с нужным режимом
  5. 5
    Считайте результат из свойства Ссылка объекта
  6. 6
    Проверьте ссылку функцией ЗначениеЗаполнено() перед дальнейшим использованием

Проверка и поиск существующего документа

Иногда под «получить ссылку нового документа» понимают другую задачу: найти ссылку документа, который, возможно, уже создан, чтобы не делать дубль. Для этого используется поиск по реквизитам — например, по номеру и дате или по уникальному идентификатору.

Если известен уникальный идентификатор, ссылку получают так:

УИ = Новый УникальныйИдентификатор("строка-uuid");

Ссылка = Документы.РеализацияТоваровУслуг.ПолучитьСсылку(УИ);

Если Ссылка.ПолучитьОбъект() = Неопределено Тогда

// документа с таким УИ в базе нет

КонецЕсли;

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

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

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

ЗначениеЗаполнено(Ссылка)
Норма

Возвращает Истина — ссылка присвоена

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

Ложь — документ не записан или ссылка не установлена

Ссылка.ПолучитьОбъект()
Норма

Возвращает объект документа

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

Неопределено — записи в базе нет (битая ссылка)

Запрос по ссылке
Норма

Возвращает строку с данными документа

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

Пустая выборка — документ не записан

Типичные ошибки и ограничения

Самая распространённая ошибка — попытка прочитать свойство Ссылка у объекта до записи без предварительного УстановитьСсылкуНового и удивляться пустому значению. Вторая по частоте — использование ПолучитьСсылку() без присвоения объекту: сгенерированный идентификатор просто теряется, а документ при записи получает другой.

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

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

Выбор подхода под конкретную задачу

Если ссылка нужна только после создания документа — ничего специально делать не надо, достаточно прочитать свойство Ссылка после Записать(). Механизм ПолучитьСсылку + УстановитьСсылкуНового оправдан, когда ссылку нужно сохранить в других объектах до записи документа или когда требуется строго контролировать уникальный идентификатор, например при обмене данными.

При загрузке данных из внешних систем часто используют связку: сначала ПолучитьСсылку(УИ) по идентификатору из источника, затем проверка существования объекта. Если объекта нет — создаётся новый документ, и ему устанавливается эта же ссылка. Так обеспечивается идемпотентность загрузки: повторный запуск не создаст дубль.

Сравнение вариантов

Свойство Ссылка после Записать()

Подходит для большинства задач. Ограничение: ссылка доступна только после записи

ПолучитьСсылку() + УстановитьСсылкуНового()

Когда ссылка нужна до записи. Требует аккуратности: риск битых ссылок при отмене записи

ПолучитьСсылку(УИ) + проверка объекта

Для обмена и загрузки по внешнему идентификатору. Не проверяет существование записи сама по себе

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

Можно ли получить ссылку документа, не записывая его в базу?

Да, через Документы.ВидДокумента.ПолучитьСсылку() с последующим УстановитьСсылкуНового() у объекта. Но такая ссылка указывает на несуществующую запись, пока документ не будет записан, поэтому использовать её в запросах и для чтения данных раньше времени нельзя.

Почему ДокОбъект.Ссылка возвращает пустое значение?

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

Как узнать, существует ли документ по имеющейся ссылке?

Вызовите Ссылка.ПолучитьОбъект(): если вернулось Неопределено, записи в базе нет. Альтернатива — запрос с условием по ссылке, что быстрее при массовых проверках.

Сохранится ли ссылка, если транзакция откатится?

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

Чем ПолучитьСсылку() отличается от ПолучитьСсылку(УИ)?

Вариант без параметра генерирует новый уникальный идентификатор. Вариант с параметром конструирует ссылку из переданного идентификатора — независимо от того, есть ли такой документ в базе.

Как получить ссылку на документ в управляемой форме после записи?

В модуле формы используйте Объект.Ссылка после записи, либо обработайте событие ПослеЗаписи — там ссылка уже гарантированно существует и доступна через параметры или реквизит объекта.

Итог

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

Ссылка нового документа появляется либо после Записать() через свойство Ссылка, либо заранее через ПолучитьСсылку() и УстановитьСсылкуНового(). Всегда проверяйте заполненность ссылки и не используйте её до фактической записи документа в базу.