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

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

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

Выбор типа данных для реквизита: как избежать ошибок на этапе проектирования

Прежде чем приступать к написанию кода, нам необходимо правильно настроить метаданные. Если мы хотим хранить ссылку на Документ1 в Документе2, у нас есть три варианта настройки типа данных для реквизита. Проанализируем каждый из них:

  1. Конкретный тип ссылки. Если мы точно уверены, что в поле Реквизит1 будет храниться ссылка только на один вид документа (например, ДокументСсылка.КартаРБ), следует выбирать именно этот тип. Это обеспечит максимальную производительность базы данных и позволит платформе автоматически генерировать кнопку открытия (лупу) и гиперссылку в интерфейсе.
  2. Составной тип данных. Если в одном и том же поле могут храниться ссылки на разные типы объектов (например, и на «Оказание услуг», и на «Реализацию товаров»), используется составной тип. Помните, что злоупотребление составными типами может незначительно замедлить запросы, так как системе приходится проверять несколько таблиц.
  3. Определяемый тип. В современных конфигурациях (особенно на базе БСП) хорошим тоном считается использование объекта метаданных ОпределяемыйТип. Мы создаем тип, например, ДокументОснование, включаем в него нужные документы, а затем назначаем этот тип всем нужным реквизитам. Это значительно упрощает поддержку кода в будущем.

Алгоритм программного получения ссылки при создании документа

Рассмотрим ситуацию, когда мы программно создаем новый документ (например, КартаРБ) и хотим сразу же записать ссылку на него в реквизит другого документа (КартаМО). Рассмотрим по шагам правильный алгоритм действий в 1С 8.3:

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

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


// 1. Создаем объект нового документа в памяти
НовыйДокОбъект = Документы.КартаРБ.СоздатьДокумент();

// 2. Заполняем обязательные реквизиты
НовыйДокОбъект.Дата = ТекущаяДата();
НовыйДокОбъект.Организация = Справочники.Организации.НайтиПоНаименованию("Наша компания");
// ... заполнение остальных полей ...

// 3. Записываем документ в базу данных. 
// Только после этого ссылка становится валидной для использования в других объектах.
НовыйДокОбъект.Записать(РежимЗаписиДокумента.Запись);

// 4. Получаем ссылку на созданный документ
СсылкаНаНовыйДок = НовыйДокОбъект.Ссылка;

// 5. Записываем эту ссылку в реквизит другого документа (например, текущего)
Объект.ДокСсылкаРБ = СсылкаНаНовыйДок;

Проанализируем ситуацию: если бы мы попытались выполнить Объект.ДокСсылкаРБ = НовыйДокОбъект.Ссылка до вызова метода Записать(), то в поле документа КартаМО отобразилась бы «битая» ссылка. Всегда соблюдайте последовательность: Создание -> Заполнение -> Запись -> Получение ссылки.

Как получить ссылку с помощью языка запросов

Иногда нам нужно найти уже существующий документ по какому-то признаку и получить ссылку на него. Посмотрим на пример, как это сделать эффективно с помощью запроса, а не перебором или устаревшими методами типа НайтиПоРеквизиту.


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

Запрос.УстановитьПараметр("НомерВизита", "В001");

РезультатЗапроса = Запрос.Выполнить();

Если НЕ РезультатЗапроса.Пустой() Тогда
    Выборка = РезультатЗапроса.Выбрать();
    Выборка.Следующий();
    // Получаем ссылку из выборки
    Объект.Реквизит1 = Выборка.Ссылка;
КонецЕсли;

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

Интерактивное открытие: как сделать ссылку кликабельной

Выясним причину, по которой иногда ссылка в поле ввода не открывается по клику. В управляемых формах 1С 8.3 поведение ссылки настраивается в свойствах элемента формы (поля ввода). Чтобы пользователь мог нажать на ссылку и сразу попасть в нужный документ (как в примере с КартаРБ и КартаМО), можно использовать два способа:

  1. Свойство «Кнопка открытия». В свойствах поля на форме установите галочку «Кнопка открытия» в значение «Да» (или «Авто»). В поле появится значок лупы.
  2. Свойство «Гиперссылка». Если установить галочку «Гиперссылка», текст в поле станет синим и подчеркнутым. Переход к документу будет осуществляться по обычному клику мыши.

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

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

Рассмотрим, как принудительно открыть форму документа, ссылка на который хранится в реквизите ДокСсылкаРБ. Для этого в модуле управляемой формы используется метод ПоказатьЗначение или ОткрытьФорму.


&НаКлиенте
Процедура ОткрытьСвязаннуюКарту(Команда)
    
    // Проверяем, заполнена ли ссылка
    Если ЗначениеЗаполнено(Объект.ДокСсылкаРБ) Тогда
        
        // Самый простой способ открыть стандартную форму объекта
        ПоказатьЗначение( , Объект.ДокСсылкаРБ);
        
    Иначе
        ПоказатьПредупреждение(, "Документ еще не создан или ссылка не указана!");
    КонецЕсли;
    
КонецПроцедуры

Отличия от 1С 7.7 и типичные ошибки миграции кода

Проанализируем старый код из версии 7.7, который часто пытаются перенести в 8.3. В старых версиях использовались конструкции вроде ПустаяСтрока(ТекущийДокумент). В современной платформе это работать не будет, так как ссылка — это не строка, а сложный объект (128-битный идентификатор GUID).

Основные правила проверки ссылок в 8.3:

Разберем пример правильной проверки:


// НЕПРАВИЛЬНО (стиль 7.7):
// Если Ссылка = "" Тогда ...

// ПРАВИЛЬНО:
Если Объект.ДокСсылкаРБ.Пустая() Тогда
    // Логика для незаполненного поля
КонецЕсли;

// ИЛИ ЕЩЕ ЛУЧШЕ:
Если НЕ ЗначениеЗаполнено(Объект.ДокСсылкаРБ) Тогда
    // Логика для незаполненного поля
КонецЕсли;

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

← На главную