Как добавить произвольную ссылку в ресурс регистра сведений через расширение 1С

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

При разработке расширений для платформы 1С:Предприятие 8.3 программисты часто сталкиваются с жестким ограничением: невозможностью выбрать тип данных ЛюбаяСсылка для новых реквизитов или ресурсов. Это ограничение обусловлено архитектурой платформы — состав системного типа ЛюбаяСсылка формируется на уровне основной конфигурации, и расширение не может динамически изменять этот глобальный тип, чтобы не нарушать ссылочную целостность базы данных.

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

Причина ограничения платформы

Разберем ситуацию глубже. Тип ЛюбаяСсылка в 1С — это не просто абстрактный указатель, а объединение всех ссылочных типов конфигурации (справочников, документов, планов видов характеристик и т.д.). Когда мы создаем расширение, платформа должна гарантировать, что данные расширения будут корректно сопоставляться с основной базой. Поскольку расширение "накладывается" на основную конфигурацию, динамическое расширение типа ЛюбаяСсылка объектами самого расширения или попытка его использования в новых структурах данных заблокирована на уровне ядра 1С для обеспечения стабильности SQL-таблиц.

Способ 1. Создание фиксированного составного типа данных

Если нам заранее известен примерный перечень типов объектов, которые могут быть записаны в ресурс регистра, самым правильным и производительным решением будет использование составного типа данных. Рассмотрим, как это реализовать.

Проанализируем шаги:

  1. Откроем свойство ресурса в расширении.
  2. В окне редактирования типа данных снимем флаг "Составной тип данных", а затем снова его установим (это обновит список доступных типов).
  3. Вручную отметим галочками те справочники и документы, ссылки на которые мы планируем хранить.

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

Способ 2. Использование сериализации в строку (XML или Внутренняя строка)

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

Рассмотрим использование метода ЗначениеВСтрокуВнутр. Этот метод позволяет преобразовать любой объект 1С (включая ссылку) в уникальную системную строку.

Для записи данных используем следующий подход:


// Пример записи ссылки в ресурс типа Строка
НоваяЗапись = РегистрыСведений.МойРегистрРасширения.СоздатьМенеджерЗаписи();
НоваяЗапись.Период = ТекущаяДата();
НоваяЗапись.ОбъектСтрокой = ЗначениеВСтрокуВнутр(СсылкаНаОбъект);
НоваяЗапись.Записать();

Для обратного получения ссылки из регистра проанализируем следующий код:


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

Этот способ позволяет обойти любые ограничения типов, но делает невозможным построение запросов с отбором по самой ссылке внутри базы данных, так как в SQL будет лежать просто текст.

Способ 3. Хранение пары «УникальныйИдентификатор» и «ИмяТипа»

Это более профессиональный и "чистый" метод. Вместо одной непонятной строки мы создаем в регистре два ресурса:

  1. ИмяТипа (Тип: Строка) — здесь будем хранить полное имя метаданных, например, "Справочник.Номенклатура".
  2. Идентификатор (Тип: Строка или УникальныйИдентификатор) — здесь будем хранить GUID ссылки.

Выясним, как программно восстановить ссылку, имея эти данные. Для этого воспользуемся возможностями XML-сериализации, которая позволяет гибко работать с типами:


// Функция для восстановления ссылки из метаданных и GUID
Функция ПолучитьСсылкуИзПараметров(ИмяМетаданных, СтрокаGUID) Экспорт
    
    ТипОбъекта = Тип(ИмяМетаданных);
    Если ТипОбъекта = Неопределено Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Используем XMLЗначение для получения ссылки по типу и идентификатору
    Попытка
        Возврат XMLЗначение(ТипОбъекта, СтрокаGUID);
    Исключение
        Возврат Неопределено;
    КонецПопытки;
    
КонецФункции

Такой подход позволяет нам не только хранить произвольные ссылки, но и при необходимости строить отчеты, группируя данные хотя бы по типам объектов (через поле ИмяТипа).

Способ 4. Использование объекта «ХранилищеЗначения»

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

Посмотрим на пример записи:


Запись = РегистрыСведений.МойРегистр.СоздатьМенеджерЗаписи();
// ... заполнение ключей записи ...
Запись.ДанныеОбъекта = Новый ХранилищеЗначения(СсылкаНаЛюбойОбъект);
Запись.Записать();

Важно помнить, что содержимое ХранилищеЗначения нельзя прочитать в запросе. Этот способ подходит только для тех случаев, когда данные нужны исключительно при чтении записи программным кодом (например, в формах или при обработке данных в фоне).

Анализ проблем производительности и целостности

Рассмотрим риски, которые возникают при использовании обходных путей:

Рекомендации по выбору решения

Подведем итог и выберем оптимальный путь для вашей задачи:

  1. Если список типов ограничен (даже если их 50 штук) — используйте составной тип. Это обеспечит максимальную скорость и надежность системы.
  2. Если вы создаете универсальный механизм (например, логирование изменений или систему внешних связей), где типы заранее не известны — используйте связку ИмяМетаданных + GUID в строке. Это наиболее гибкий и читаемый способ для разработчика.
  3. К методу ЗначениеВСтрокуВнутр прибегайте только в крайнем случае, так как этот формат является внутренним для 1С и его трудно анализировать внешними средствами (например, через консоль запросов или напрямую в SQL).

Таким образом, несмотря на отсутствие прямой поддержки ЛюбаяСсылка в расширениях, платформа предоставляет достаточно инструментов для решения этой задачи. Главное — заранее продумать, как вы будете обрабатывать удаление объектов и строить отчеты по этим данным.

← На главную