Работа с документами в 1С:Предприятие часто требует манипуляций с объектами до их сохранения в базе данных. Типичная ситуация: пользователь создал новый документ, заполнил реквизиты, но еще не нажал «Записать» или «Провести». В этот момент у документа нет физической записи в таблицах базы, но программно уже можно получить его ссылку — уникальный идентификатор, который пригодится для связывания с другими объектами, передачи в обработки или отчеты.
В этой статье разберем все актуальные способы получения ссылки на несохраненный документ в разных режимах 1С 8.3: от простых методов для управляемых форм до универсальных решений через встроенный язык. Особое внимание уделим нуансам работы с временными ссылками, которые исчезают после закрытия сеанса, и покажем, как избежать типичных ошибок при их использовании.
1. Почему стандартный метод Ссылка() не работает для новых документов
Многие разработчики привыкли получать ссылку на документ через метод Ссылка(). Например, так:
СсылкаНаДокумент = Документ.Ссылка();
Однако для несохраненного документа этот метод вернет Неопределено. Дело в том, что метод Ссылка() обращается к физической записи в базе данных, которой у нового документа просто нет. Вместо этого система создает временную ссылку — виртуальный идентификатор, действующий только в рамках текущего сеанса.
Вот что происходит при попытке получить ссылку стандартным способом:
| Состояние документа | Метод Ссылка() |
Результат |
|---|---|---|
| Новый (не сохранен) | Документ.Ссылка() |
Неопределено |
| Сохранен (записан) | Документ.Ссылка() |
Ссылка на запись в базе |
| Новый (не сохранен) | Документ.ПолучитьСсылку() |
Временная ссылка |
⚠️ Внимание: Временные ссылки не сохраняются между сеансами 1С. Если вы передадите такую ссылку в другой сеанс (например, через RPC или фоновое задание), она станет недействительной.
2. Способ 1: Метод ПолучитьСсылку() для управляемых форм
Самый простой способ получить ссылку на несохраненный документ в управляемом приложении — использовать метод ПолучитьСсылку(). Он работает для всех объектов, поддерживающих интерфейс ОбъектСсылка, включая документы, справочники и планы обмена.
Пример кода для формы документа:
// В модуле объекта документа или в обработчике формы
Процедура ПолучитьВременнуюСсылку(Команда)
Сообщить(Объект.ПолучитьСсылку());
КонецПроцедуры
Особенности метода:
- 🔹 Работает только в управляемом режиме (для обычных форм нужен другой подход).
- 🔹 Возвращает ссылку вида
Документ.ЗаказПокупателя.ВременныйИдентификатор. - 🔹 Ссылка действует до закрытия формы или завершения сеанса.
- 🔹 Можно использовать для передачи между формами в рамках одного сеанса.
☑️ Проверка перед использованием ПолучитьСсылку()
Если вам нужно передать такую ссылку в другой модуль той же конфигурации, используйте параметры методов или глобальные переменные. Например:
Процедура ОткрытьОбработкуСоСсылкой(Команда)
Параметры = Новый Структура("СсылкаНаДокумент", Объект.ПолучитьСсылку());
ОткрытьФорму("ДополнительнаяОбработка.ФормаОбработки", Параметры);
КонецПроцедуры
3. Способ 2: Создание временного объекта через МенеджерВременныхДанных
Для более гибкой работы с несохраненными данными в 1С 8.3 предусмотрен механизм МенеджерВременныхДанных. Он позволяет создавать временные объекты, которые существуют только в оперативной памяти, но имеют все свойства обычных объектов — включая ссылки.
Алгоритм получения ссылки:
- Создать временный документ через
МенеджерВременныхДанных.СоздатьОбъект(). - Заполнить реквизиты документа.
- Получить ссылку методом
ПолучитьСсылку().
Пример кода:
// Создаем временный документ
ВременныйДокумент = МенеджерВременныхДанных.СоздатьОбъект("Документ.ЗаказПокупателя");
// Заполняем реквизиты
ВременныйДокумент.Дата = ТекущаяДата();
ВременныйДокумент.Контрагент = Справочники.Контрагенты.НайтиПоНаименованию("ООО Розница");
// Получаем ссылку
СсылкаНаВременныйДокумент = ВременныйДокумент.ПолучитьСсылку();
Сообщить(СсылкаНаВременныйДокумент); // Документ.ЗаказПокупателя.ВременныйИдентификатор
Преимущества этого метода:
- 🔹 Работает и в управляемом, и в обычном приложении.
- 🔹 Позволяет создавать объекты без привязки к форме.
- 🔹 Поддерживает все стандартные методы объектов (например,
Записать(),Провести()).
⚠️ Внимание: Временные объекты, созданные через МенеджерВременныхДанных, не видны в списках документов и не участвуют в транзакциях базы данных. Их нельзя найти через стандартные запросы к регистрам или справочникам.
4. Способ 3: Использование конструктора временных таблиц в запросах
Если вам нужно получить ссылку на несохраненный документ в контексте запроса (например, для передачи в отчет или обработку), можно использовать КонструкторВременныхТаблиц. Этот метод особенно полезен, когда требуется работать с набором данных, включающим как сохраненные, так и несохраненные документы.
Пример создания временной таблицы с документом:
Запрос = Новый Запрос;
Конструктор = Новый КонструкторВременныхТаблиц;
// Создаем временную таблицу с структурой документа "ЗаказПокупателя"
ТаблицаДокументов = Конструктор.ДобавитьТаблицу("ВременныеДокументы");
Конструктор.ДобавитьКолонку(ТаблицаДокументов, "Ссылка", Новый ОписаниеТипов("Ссылка.Документ.ЗаказПокупателя"));
Конструктор.ДобавитьКолонку(ТаблицаДокументов, "Дата", Новый ОписаниеТипов("Дата"));
Конструктор.ДобавитьКолонку(ТаблицаДокументов, "Номер", Новый ОписаниеТипов("Строка"));
// Добавляем строку с данными несохраненного документа
НоваяСтрока = ТаблицаДокументов.Добавить();
НоваяСтрока.Ссылка = Документ.ПолучитьСсылку(); // Ссылка на несохраненный документ
НоваяСтрока.Дата = Документ.Дата;
НоваяСтрока.Номер = Документ.Номер;
// Используем таблицу в запросе
Запрос.Текст =
"ВЫБРАТЬ
| ВременныеДокументы.Ссылка КАК Ссылка,
| ВременныеДокументы.Дата КАК Дата
|ИЗ
| &ТаблицаДокументов КАК ВременныеДокументы";
Запрос.УстановитьВременнуюТаблицу("ТаблицаДокументов", ТаблицаДокументов);
Результат = Запрос.Выполнить();
Когда этот способ пригодится:
- 📊 Для формирования отчетов с учетом несохраненных данных.
- 🔄 При обмене данными между узлами распределенной базы.
- 🔗 Для связывания несохраненных документов с другими объектами в запросах.
Ограничения конструктора временных таблиц
Временные таблицы существуют только в рамках одного запроса. После выполнения запроса данные теряются, если их явным образом не сохранить в коллекцию или массив. Также временные таблицы не поддерживают индексы, что может замедлить выполнение сложных запросов.
5. Работа с несохраненными документами в обычных формах (8.2 и ранее)
В обычном приложении (режим совместимости с 8.2) метод ПолучитьСсылку() недоступен. Здесь для получения ссылки на несохраненный документ используют недокументированный механизм через свойство ВременныйИдентификатор.
Пример кода для обычной формы:
// В модуле формы документа
Процедура ПолучитьВременнуюСсылку()
Если НЕ Объект.ЭтоНовый() Тогда
// Документ уже сохранен - используем стандартную ссылку
Возврат Объект.Ссылка();
Иначе
// Создаем временную ссылку вручную
ВременныйID = Объект.УникальныйИдентификатор();
Возврат СсылкаНаОбъект(ВременныйID, "Документ.ЗаказПокупателя");
КонецЕсли;
КонецПроцедуры
// Функция для создания ссылки (аналог ПолучитьСсылку())
Функция СсылкаНаОбъект(Идентификатор, ТипОбъекта)
Возврат Новый("Ссылка." + ТипОбъекта, Идентификатор);
КонецФункции
Важные нюансы:
- 🔧 Метод
УникальныйИдентификатор()возвращает GUID, который используется как временный ID. - 🔧 Ссылка, созданная таким образом, будет действовать только в текущем сеансе.
- 🔧 В обычных формах нет гарантии, что временный идентификатор будет уникальным между сеансами.
⚠️ Внимание: Использование недокументированных свойств вроде УникальныйИдентификатор() может привести к ошибкам при обновлении платформы. Рекомендуется тестировать такой код на каждой новой версии 1С:Предприятие.
6. Типичные ошибки и как их избежать
При работе с временными ссылками разработчики часто сталкиваются с типичными проблемами. Вот самые распространенные из них и способы их решения:
| Ошибка | Причина | Решение |
|---|---|---|
Ошибка при вызове метода контекста (ПолучитьСсылку) |
Метод вызван для объекта, не поддерживающего интерфейс ОбъектСсылка |
Проверьте тип объекта через ТипЗнч() перед вызовом |
| Ссылка становится недействительной после записи документа | Временная ссылка заменяется на постоянную при записи | После записи получайте ссылку заново через Ссылка() |
Недопустимое значение параметра (передача ссылки в другой сеанс) |
Попытка использовать временную ссылку в другом сеансе или процессе | Передавайте только данные, а не ссылки, или записывайте документ перед передачей |
Еще одна частая проблема — потеря связи между объектами при использовании временных ссылок. Например, если вы создали документ ЗаказПокупателя и привязали к нему Оплата через временную ссылку, то после записи заказа ссылка в оплате станет недействительной. Чтобы этого избежать:
- Сначала запишите главный документ (заказ).
- Получите его постоянную ссылку через
Ссылка(). - Привяжите зависимые документы (оплату) уже к постоянной ссылке.
Если вам нужно передать данные о несохраненном документе во внешнюю систему (например, через HTTP-сервис), вместо ссылки используйте структуру с данными. После записи документа можно будет сопоставить его по уникальному реквизиту (например, номеру или дате).
7. Практический пример: Связывание несохраненных документов
Рассмотрим типичную задачу: пользователь создает Заказ покупателя и сразу хочет создать связанную Реализацию товаров, не сохраняя заказ в базу. Нам нужно передать ссылку на несохраненный заказ в форму реализации.
Решение для управляемого приложения:
// В модуле формы заказа
Процедура СоздатьРеализацию(Команда)
// Получаем временную ссылку на текущий заказ
СсылкаНаЗаказ = Объект.ПолучитьСсылку();
// Открываем форму реализации и передаем ссылку как параметр
Параметры = Новый Структура("СсылкаНаЗаказ", СсылкаНаЗаказ);
ОткрытьФорму("Документ.РеализацияТоваровУслуг.ФормаОбъекта", Параметры, ЭтотОбъект);
КонецПроцедуры
// В модуле формы реализации (при создании на сервере)
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("СсылкаНаЗаказ") Тогда
// Получаем переданную ссылку
СсылкаНаЗаказ = Параметры.СсылкаНаЗаказ;
// Проверяем, что это временная ссылка
Если ТипЗнч(СсылкаНаЗаказ) = Тип("Ссылка.Документ.ЗаказПокупателя") Тогда
// Заполняем реквизит "Заказ" в реализации
Объект.Заказ = СсылкаНаЗаказ;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
После того как пользователь запишет оба документа, временные ссылки автоматически заменятся на постоянные, и связь между заказом и реализацией сохранится.
Всегда проверяйте тип полученной ссылки через ТипЗнч() перед использованием. Это поможет избежать ошибок при работе с временными и постоянными ссылками в одном коде.
FAQ: Частые вопросы по работе с временными ссылками
Можно ли получить временную ссылку на документ в мобильном приложении 1С?
Да, в мобильном клиенте 1С:Предприятие метод ПолучитьСсылку() работает так же, как и в десктопной версии. Однако учитывайте, что временные ссылки в мобильном приложении не сохраняются между запусками — они действуют только в рамках одного сеанса работы.
Как узнать, является ли ссылка временной или постоянной?
Программно отличить временную ссылку от постоянной можно по ее строковому представлению. Временные ссылки содержат фрагмент ВременныйИдентификатор, а постоянные — реальный идентификатор записи в базе. Пример проверки:
Функция ЭтоВременнаяСсылка(Ссылка)
Возврат Строка(Ссылка).Содержит("ВременныйИдентификатор");
КонецФункции
Что будет, если попытаться записать документ по временной ссылке?
Ничего критичного — платформа автоматически преобразует временную ссылку в постоянную при записи документа. Все объекты, ссылающиеся на этот документ через временную ссылку, будут корректно обновлены. Однако если документ так и не был записан, временная ссылка станет недействительной после закрытия формы.
Можно ли использовать временные ссылки в фоновых заданиях?
Нет, это приведет к ошибке. Фоновые задания выполняются в отдельном сеансе, где временные ссылки текущего пользовательского сеанса недоступны. Для передачи данных в фоновое задание используйте:
- Структуры с данными (без ссылок).
- Идентификаторы объектов (например,
УникальныйИдентификатор()), если документы уже записаны.
Как передать временную ссылку между разными базами 1С?
Передача временных ссылок между базами невозможна — они действуют только в рамках одного сеанса одной базы. Для обмена данными между базами:
- Запишите документ в исходной базе.
- Передайте его уникальный идентификатор (например,
УникальныйИдентификатор()) или набор реквизитов для поиска. - В целевой базе найдите документ по переданным данным.