Почему поле ИмяПредопределенныхДанных ограничено в запросах и как его правильно использовать?

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

При переходе на платформу 1С:Предприятие 8.3 многие разработчики столкнулись с появлением нового системного реквизита — ИмяПредопределенныхДанных. На первый взгляд кажется, что это обычная строка, содержащая имя элемента из конфигуратора, но при попытке использовать её в сложных запросах платформа накладывает жесткие ограничения. Мы часто сталкиваемся с тем, что это поле нельзя использовать в строковых функциях или при определенных типах соединений. В этой статье мы подробно разберем, почему так происходит, как работает механизм связи с метаданными и как извлечь реальную пользу из этого реквизита.

Техническая природа и назначение поля

Для начала проанализируем, зачем вообще понадобилось это поле. До версии 8.3 связь между объектом в базе данных и объектом в конфигураторе (предопределенным элементом) осуществлялась жестко по внутреннему идентификатору (GUID). Это вызывало огромные сложности при обновлении конфигураций и в распределенных информационных базах (РИБ). Поле ИмяПредопределенныхДанных было введено, чтобы "отвязать" логическое имя элемента от его физического ID.

Важный нюанс: хотя в интерфейсе "1С:Предприятие" это поле выглядит как текстовое, на уровне СУБД (SQL) оно является индексированным служебным полем. Платформа воспринимает его не как произвольную строку, а как ключ связи. Именно поэтому мы не можем применять к нему операторы ПОДОБНО, функции ПОДСТРОКА или конкатенацию. Платформа ожидает только операции прямого сравнения, так как это позволяет эффективно использовать индексы базы данных.

Использование поля в условиях запроса

Рассмотрим распространенное заблуждение о том, что это поле бесполезно в секции ГДЕ. На самом деле, поле ИмяПредопределенныхДанных отлично работает в условиях отбора, если мы передаем туда конкретное значение или параметр. Посмотрим на пример кода, который позволяет выбрать ссылку по её имени в конфигураторе:


ВЫБРАТЬ
    Контрагенты.Ссылка КАК Ссылка
ИЗ
    Справочник.Контрагенты КАК Контрагенты
ГДЕ
    Контрагенты.ИмяПредопределенныхДанных = &ИмяПредопределенныхДанных

Такой подход удобен, когда нам нужно программно найти элемент, имя которого мы знаем только в виде строки (например, при загрузке настроек из внешнего файла или макета). Это гораздо производительнее, чем перебор всех элементов в цикле или использование функции НайтиПоНаименованию.

Решение проблемы дублей предопределенных элементов

Одной из самых полезных практик использования этого реквизита является поиск и устранение дублей. Иногда в базе данных из-за ошибок обмена или некорректного обновления возникают ситуации, когда два разных элемента (с разными ссылками) претендуют на одно и то же имя предопределенного. Мы можем найти такие записи, выполнив внутреннее соединение таблицы самой с собой по этому полю.

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


Процедура ОчиститьДублиПредопределенныхЭлементов()
    Запрос = Новый Запрос(
        "ВЫБРАТЬ
        |    СсылкиДляФорм.Ссылка КАК ИнформационнаяСсылка
        |ИЗ
        |    Справочник.ИнформационныеСсылкиДляФорм КАК СсылкиДляФорм
        |    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ИнформационныеСсылкиДляФорм КАК СсылкиДляФорм1
        |    ПО СсылкиДляФорм.ИмяПредопределенныхДанных = СсылкиДляФорм1.ИмяПредопределенныхДанных
        |    И СсылкиДляФорм.Ссылка <> СсылкиДляФорм1.Ссылка
        |ГДЕ
        |    СсылкиДляФорм1.ИмяПредопределенныхДанных <> """"");

    Выборка = Запрос.Выполнить().Выбрать();

    Пока Выборка.Следующий() Цикл
        // Получаем объект для редактирования
        ОбъектСсылка = Выборка.ИнформационнаяСсылка.ПолучитьОбъект();
        // Разрываем связь с метаданными, очищая имя
        ОбъектСсылка.ИмяПредопределенныхДанных = "";
        ОбъектСсылка.ПометкаУдаления = Истина;
        // Используем ОбменДанными.Загрузка, чтобы обойти проверки
        ОбъектСсылка.ОбменДанными.Загрузка = Истина;
        ОбъектСсылка.Записать();
    КонецЦикла;
КонецПроцедуры

В данном примере мы находим все элементы, у которых совпадает ИмяПредопределенныхДанных, но различаются ссылки. После чего мы программно "отвязываем" дублирующий элемент от метаданных, просто присваивая полю пустую строку. Это превращает предопределенный элемент в обычный, после чего его можно пометить на удаление.

Управление связью (Binding) в режиме 1С:Предприятие

Давайте выясним причину, по которой этот реквизит доступен для записи. Это дает разработчику мощный инструмент управления данными без изменения конфигурации:

  1. Создание связи: Если вы создали элемент справочника вручную и хотите сделать его предопределенным (чтобы к нему можно было обращаться через ЗНАЧЕНИЕ(...) в запросах), вы можете просто записать в его поле ИмяПредопределенныхДанных соответствующее имя из метаданных.
  2. Разрыв связи: Если элемент больше не должен быть предопределенным, очистка этого поля сделает его обычным элементом справочника.
  3. Исправление ошибок РИБ: В распределенных базах, если в разных узлах создались разные элементы с одинаковым назначением, выравнивание их ИмяПредопределенныхДанных позволит платформе правильно сопоставить их при синхронизации.

Программная работа и производительность

Проанализируем способы получения имени предопределенного элемента в коде. Помимо прямого обращения через точку (Ссылка.ИмяПредопределенныхДанных), существует метод менеджера: Справочники.Контрагенты.ПолучитьИмяПредопределенного(Ссылка).

Рекомендация по производительности: Всегда отдавайте предпочтение методу менеджера ПолучитьИмяПредопределенного(), если вам нужно узнать имя в коде. Платформа кэширует эти данные, и такое обращение не всегда вызывает реальный запрос к базе данных, в отличие от обращения к реквизиту через точку, которое всегда тянет данные объекта.

Отличия от булева свойства «Предопределенный»

Важно не путать эти два понятия, которые часто встречаются в конструкторе запросов:

Таким образом, мы видим, что ИмяПредопределенныхДанных — это не просто "бесполезная строка", а ключевой механизм платформы 8.3 для обеспечения гибкости и стабильности данных. Несмотря на ограничения в запросах (связанные с особенностями индексации в СУБД, такими как PostgreSQL или MS SQL), этот реквизит остается единственным легальным способом управления "предопределенностью" объектов в реальном времени.

← На главную