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

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

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

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

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

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

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

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

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

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

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

Получение ссылки в модуле формы документа

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

&НаКлиенте

Процедура КомандаПоказатьСсылку(Команда)

ТекущаяСсылка = Объект.Ссылка;

Если ЗначениеЗаполнено(ТекущаяСсылка) Тогда

Сообщить("Ссылка: " + Строка(ТекущаяСсылка.УникальныйИдентификатор()));

Иначе

Сообщить("Документ ещё не записан, ссылки нет.");

КонецЕсли;

КонецПроцедуры

Обратите внимание: если документ только что создан и ни разу не записан, Объект.Ссылка вернёт пустую ссылку. Это нормальное поведение — физической записи в базе ещё нет, и идентификатор не назначен.

Ссылка в обработчиках формы

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

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

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

Процедура ПриЗаписи(Отказ)

ТекущаяСсылка = Ссылка;

// Пример: запись в регистр сведений со ссылкой на документ

Запись = РегистрыСведений.СтатусыДокументов.СоздатьМенеджерЗаписи();

Запись.Документ = ТекущаяСсылка;

Запись.Статус = Перечисления.Статусы.Записан;

Запись.Записать();

КонецПроцедуры

В обработчике ОбработкаПроведения ссылка также доступна через Ссылка — именно её обычно подставляют в движения регистров как регистратор, хотя платформа при типовом проведении делает это автоматически.

Ссылка на новый, ещё не записанный документ

Иногда ссылка нужна до записи: например, чтобы заранее заполнить реквизит «Основание» в связанных объектах или сформировать идентификатор для обмена. Для этого используется пара методов ПолучитьСсылку() и УстановитьСсылкуНового():

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

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

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

НовыйДок.Дата = ТекущаяДатаСеанса();

НовыйДок.Записать();

// Теперь НовыйДок.Ссылка = НоваяСсылка, и она уже записана в базу

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

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

Во внешних обработках, при обмене данными или при восстановлении связей возникает обратная задача: есть уникальный идентификатор (GUID) в виде строки, нужно получить ссылку. Это делается через менеджер документа:

СтрокаGUID = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";

Идентификатор = Новый УникальныйИдентификатор(СтрокаGUID);

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

// Проверка, существует ли такой документ

Запрос = Новый Запрос("ВЫБРАТЬ ПЕРВЫЕ 1 Д.Ссылка ИЗ Документ.ПоступлениеТоваровУслуг КАК Д ГДЕ Д.Ссылка = &Ссылка");

Запрос.УстановитьПараметр("Ссылка", НайденнаяСсылка);

Если Запрос.Выполнить().Пустой() Тогда

Сообщить("Документ с таким идентификатором не найден.");

КонецЕсли;

Если ссылка пришла из другой системы в сериализованном виде (например, из XML через обмен), используйте функции ЗначениеИзСтрокиВнутр() для внутреннего формата или штатные механизмы конвертации вашего плана обмена.

Сравнение способов получения ссылки

КонтекстСпособОсобенность
Форма документаОбъект.СсылкаПустая, пока документ не записан
Модуль объектаСсылкаДоступна во всех обработчиках записи и проведения
Новый документ до записиПолучитьСсылку() + УстановитьСсылкуНового()Требует обязательной последующей записи
Известен GUIDДокументы.Вид.ПолучитьСсылку(GUID)Не гарантирует существование документа
Поиск по номеру/датеЗапрос или НайтиПоНомеру()Вернёт пустую ссылку, если документ не найден

Проверка корректности полученной ссылки

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

Если Не ЗначениеЗаполнено(ТекущаяСсылка) Тогда

ВызватьИсключение "Документ не записан, ссылка отсутствует.";

КонецЕсли;

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

ВызватьИсключение "Документ удалён из базы (битая ссылка).";

КонецЕсли;

Дополнительно проверяйте ПометкаУдаления и Проведен, если дальнейшая логика зависит от состояния документа: например, создавать подчинённые документы на основании помеченного на удаление обычно нельзя.

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

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

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

Возвращает Истина

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

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

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

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

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

Неопределено — записи в базе нет

Ссылка.УникальныйИдентификатор()
Норма

Возвращает GUID без ошибки

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

Ошибка обращения — тип значения не ссылочный

Типичные ошибки при работе со ссылками

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

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

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

Типовая задача — программно создать документ-основание и передать его ссылку в другой документ:

&НаСервере

Функция СоздатьЗаказИПолучитьСсылку(Контрагент)

НовыйЗаказ = Документы.ЗаказПокупателя.СоздатьДокумент();

НовыйЗаказ.Дата = ТекущаяДатаСеанса();

НовыйЗаказ.Контрагент = Контрагент;

НовыйЗаказ.Записать(РежимЗаписиДокумента.Запись);

Возврат НовыйЗаказ.Ссылка;

КонецФункции

&НаСервере

Процедура СоздатьРеализациюПоЗаказу()

СсылкаНаЗаказ = СоздатьЗаказИПолучитьСсылку(Контрагент);

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

Реализация.ДокументОснование = СсылкаНаЗаказ;

Реализация.Дата = ТекущаяДатаСеанса();

Реализация.Записать();

КонецПроцедуры

Здесь ключевой момент — вызов Записать() до чтения Ссылка. Без записи в реквизит «ДокументОснование» попадёт пустая ссылка, и связь между документами не установится.

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

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

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

Документ открыт в режиме создания и ещё ни разу не записан в базу. Пока нет физической записи, идентификатор не назначен. Запишите документ программно или дождитесь записи пользователем, после чего ссылка станет заполненной.

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

Используйте метод менеджера: Документы.ВидДокумента.НайтиПоНомеру(Номер, Дата). Метод вернёт ссылку или пустую ссылку, если документ не найден. Для поиска по нескольким условиям надёжнее запрос.

Чем пустая ссылка отличается от битой?

Пустая ссылка — это «нулевое» значение ссылочного типа, оно никогда не указывало на реальный объект. Битая ссылка содержит идентификатор документа, который был удалён из базы физически: заполненность вернёт Истина, но ПолучитьОбъект() даст Неопределено.

Можно ли изменить данные документа через ссылку?

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

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

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

Итог

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

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