В процессе разработки на платформе 1С:Предприятие 8.3 одной из самых частых задач является связывание нескольких объектов между собой. Например, когда на основании одного документа создается другой, или когда в одном документе нужно хранить ссылку на «первичный» или «связанный» документ. Разберем детально, как правильно организовать этот процесс, выберем подходящие типы данных и научимся программно управлять открытием этих ссылок.
Прежде чем приступать к написанию кода, нам необходимо правильно настроить метаданные. Если мы хотим хранить ссылку на Документ1 в Документе2, у нас есть три варианта настройки типа данных для реквизита. Проанализируем каждый из них:
Реквизит1 будет храниться ссылка только на один вид документа (например, ДокументСсылка.КартаРБ), следует выбирать именно этот тип. Это обеспечит максимальную производительность базы данных и позволит платформе автоматически генерировать кнопку открытия (лупу) и гиперссылку в интерфейсе.ДокументОснование, включаем в него нужные документы, а затем назначаем этот тип всем нужным реквизитам. Это значительно упрощает поддержку кода в будущем.Рассмотрим ситуацию, когда мы программно создаем новый документ (например, КартаРБ) и хотим сразу же записать ссылку на него в реквизит другого документа (КартаМО). Рассмотрим по шагам правильный алгоритм действий в 1С 8.3:
Важный нюанс: Ссылка у документа в памяти существует сразу после вызова метода СоздатьДокумент(), однако она еще не записана в базу данных. Если передать такую «незаписанную» ссылку в другой объект, вы получите ошибку «Объект не найден».
Разберем пример кода, который выполняет эту задачу корректно:
// 1. Создаем объект нового документа в памяти
НовыйДокОбъект = Документы.КартаРБ.СоздатьДокумент();
// 2. Заполняем обязательные реквизиты
НовыйДокОбъект.Дата = ТекущаяДата();
НовыйДокОбъект.Организация = Справочники.Организации.НайтиПоНаименованию("Наша компания");
// ... заполнение остальных полей ...
// 3. Записываем документ в базу данных.
// Только после этого ссылка становится валидной для использования в других объектах.
НовыйДокОбъект.Записать(РежимЗаписиДокумента.Запись);
// 4. Получаем ссылку на созданный документ
СсылкаНаНовыйДок = НовыйДокОбъект.Ссылка;
// 5. Записываем эту ссылку в реквизит другого документа (например, текущего)
Объект.ДокСсылкаРБ = СсылкаНаНовыйДок;
Проанализируем ситуацию: если бы мы попытались выполнить Объект.ДокСсылкаРБ = НовыйДокОбъект.Ссылка до вызова метода Записать(), то в поле документа КартаМО отобразилась бы «битая» ссылка. Всегда соблюдайте последовательность: Создание -> Заполнение -> Запись -> Получение ссылки.
Иногда нам нужно найти уже существующий документ по какому-то признаку и получить ссылку на него. Посмотрим на пример, как это сделать эффективно с помощью запроса, а не перебором или устаревшими методами типа НайтиПоРеквизиту.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КартаРБ.Ссылка КАК Ссылка
|ИЗ
| Документ.КартаРБ КАК КартаРБ
|ГДЕ
| КартаРБ.НомерВизита = &НомерВизита";
Запрос.УстановитьПараметр("НомерВизита", "В001");
РезультатЗапроса = Запрос.Выполнить();
Если НЕ РезультатЗапроса.Пустой() Тогда
Выборка = РезультатЗапроса.Выбрать();
Выборка.Следующий();
// Получаем ссылку из выборки
Объект.Реквизит1 = Выборка.Ссылка;
КонецЕсли;
Использование запроса — это наиболее быстрый и «правильный» способ получения ссылок в 1С 8.3, особенно когда речь идет о работе на сервере или работе с большими объемами данных.
Выясним причину, по которой иногда ссылка в поле ввода не открывается по клику. В управляемых формах 1С 8.3 поведение ссылки настраивается в свойствах элемента формы (поля ввода). Чтобы пользователь мог нажать на ссылку и сразу попасть в нужный документ (как в примере с КартаРБ и КартаМО), можно использовать два способа:
Если же вам нужно реализовать сложную логику (например, перед открытием проверить права доступа или вывести предупреждение), мы можем программно перехватить событие нажатия.
Рассмотрим, как принудительно открыть форму документа, ссылка на который хранится в реквизите ДокСсылкаРБ. Для этого в модуле управляемой формы используется метод ПоказатьЗначение или ОткрытьФорму.
&НаКлиенте
Процедура ОткрытьСвязаннуюКарту(Команда)
// Проверяем, заполнена ли ссылка
Если ЗначениеЗаполнено(Объект.ДокСсылкаРБ) Тогда
// Самый простой способ открыть стандартную форму объекта
ПоказатьЗначение( , Объект.ДокСсылкаРБ);
Иначе
ПоказатьПредупреждение(, "Документ еще не создан или ссылка не указана!");
КонецЕсли;
КонецПроцедуры
Проанализируем старый код из версии 7.7, который часто пытаются перенести в 8.3. В старых версиях использовались конструкции вроде ПустаяСтрока(ТекущийДокумент). В современной платформе это работать не будет, так как ссылка — это не строка, а сложный объект (128-битный идентификатор GUID).
Основные правила проверки ссылок в 8.3:
ЗначениеЗаполнено(Ссылка).Ссылка.Пустая().НайтиПоРеквизиту внутри циклов, всегда используйте запросы. Это сократит количество обращений к базе данных в десятки раз.Разберем пример правильной проверки:
// НЕПРАВИЛЬНО (стиль 7.7):
// Если Ссылка = "" Тогда ...
// ПРАВИЛЬНО:
Если Объект.ДокСсылкаРБ.Пустая() Тогда
// Логика для незаполненного поля
КонецЕсли;
// ИЛИ ЕЩЕ ЛУЧШЕ:
Если НЕ ЗначениеЗаполнено(Объект.ДокСсылкаРБ) Тогда
// Логика для незаполненного поля
КонецЕсли;
Подводя итог, можно сказать, что работа со ссылками в 1С 8.3 строится на строгой типизации и объектной модели. Правильно выбрав тип данных (желательно конкретный тип или определяемый), вовремя записав объект перед получением ссылки и используя стандартные механизмы управляемых форм для отображения, вы создадите надежную и быструю систему связей между документами.