Как настроить контроль дублей БСП для справочника в Расширении и исправить ошибку идентификаторов?

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

При разработке расширений для конфигураций на базе БСП (Библиотека Стандартных Подсистем) мы часто сталкиваемся с задачей подключения типовых механизмов к новым объектам. Одна из таких задач — включение контроля дублей для нового справочника. Казалось бы, достаточно поставить галочки и внедрить код, но на практике возникает ошибка "Неверный идентификатор: пустая ссылка типа Идентификатор объекта метаданных".

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

Анализ проблемы и ошибки

Рассмотрим ситуацию: мы создали в расширении справочник МаркиАвтомобилей. Мы хотим использовать типовую обработку "Поиск и удаление дублей". При попытке запуска обработки или выполнения кода поиска мы получаем сообщение об ошибке, содержащее следующий стек вызовов:


Ошибка при выполнении функции ОбщегоНазначения.ОбъектМетаданныхПоИдентификатору.
Неверный идентификатор: пустая ссылка типа "Идентификатор объекта метаданных".
...
{Справочник.ИдентификаторыОбъектовМетаданных.МодульМенеджера(830)}: ОбъектыМетаданных = ОбъектыМетаданныхПоИдентификаторам(Идентификаторы, ВызыватьИсключение);

В чем суть проблемы? Механизмы БСП не работают с объектами метаданных (справочниками, документами) напрямую через Метаданные.Справочники... во всех местах. Для хранения настроек и ссылок БСП использует специальные служебные справочники:

  1. ИдентификаторыОбъектовМетаданных — для объектов основной конфигурации.
  2. ИдентификаторыОбъектовРасширений — для объектов, добавленных в расширениях.

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

Шаг 1. Обновление идентификаторов объектов расширений

Самое первое действие при появлении таких ошибок — актуализация служебных справочников. Для объектов расширения это справочник ИдентификаторыОбъектовРасширений.

Рассмотрим способы, как это сделать:

Способ А: Через параметры запуска (Рекомендуемый)

Запустите «1С:Предприятие» с ключом, который инициирует принудительное обновление:


/C ЗапуститьОбновлениеИдентификаторовОбъектовРасширений

Или на английском:


/C RunUpdateExtensionObjectIdentifiers

Способ Б: Программный вызов

Если у вас есть доступ к консоли кода или внешней обработке, выполните следующую команду:


Справочники.ИдентификаторыОбъектовРасширений.ОбновитьДанные();

После выполнения этой процедуры ваш справочник МаркиАвтомобилей корректно пропишется в служебных таблицах БСП, и функции общего назначения смогут получать его идентификатор без ошибок.

Шаг 2. Регистрация справочника в подсистеме поиска дублей

Даже если ошибка идентификатора уйдет, обработка "Поиск и удаление дублей" может "не видеть" ваш справочник в списке доступных для поиска. БСП нужно явно сообщить, что в этом справочнике можно искать дубли.

Для этого в расширении нам необходимо переопределить логику общего модуля ПоискИУдалениеДублейПереопределяемый. Посмотрим, как это сделать правильно:

  1. Найдите в основной конфигурации общий модуль ПоискИУдалениеДублейПереопределяемый.
  2. Добавьте его в расширение (только заимствование, текст модуля копировать не нужно).
  3. Создайте в расширении процедуру-аннотацию для метода ПриОпределенииОбъектовСПоискомДублей.

Код в модуле расширения будет выглядеть так:


&После("ПриОпределенииОбъектовСПоискомДублей")
Процедура Расш1_ПриОпределенииОбъектовСПоискомДублей(Объекты)
	
	// Регистрируем наш справочник из расширения
	Объекты.Добавить(Метаданные.Справочники.МаркиАвтомобилей);
	
КонецПроцедуры

Теперь стандартная обработка будет знать о существовании вашего справочника и позволит пользователю выбирать его для анализа.

Шаг 3. Реализация запрета создания дублей (При записи)

Автор темы также задавал вопрос: "Также нужно реализовать запрет на создание элементов с похожим названием, как это сделать?".

Чтобы система проверяла наличие дублей прямо в момент создания новой карточки, нам нужно внести изменения в модуль объекта самого справочника МаркиАвтомобилей (в расширении).

Разберем алгоритм:

  1. Заимствуйте справочник в расширение.
  2. Откройте модуль объекта.
  3. Используйте событие ПередЗаписью.

Внутри события мы будем обращаться к экспортным методам модуля ПоискИУдалениеДублей. В актуальных версиях БСП (3.x) код выглядит примерно так:


&После("ПередЗаписью")
Процедура Расш1_ПередЗаписью(Отказ)
	
	// Если уже есть Отказ или это загрузка данных - проверку не делаем
	Если Отказ Или ОбменДанными.Загрузка Тогда
		Возврат;
	КонецЕсли;
	
	// Параметры поиска дублей
	ПараметрыПоиска = ПоискИУдалениеДублей.ПараметрыПоискаДублей(Метаданные());
	// Указываем правило поиска (например, по наименованию)
	// Важно: правило должно быть предварительно настроено или задано здесь программно
	
	// Выполняем проверку
	НайденоДублей = ПоискИУдалениеДублей.НайтиДубли(ЭтотОбъект, ПараметрыПоиска);
	
	Если НайденоДублей.Количество() > 0 Тогда
		// Здесь логика: либо запретить запись, либо предупредить
		
		ТекстСообщения = "Найдены похожие элементы: " + Символы.ПС;
		Для Каждого СтрокаДубля Из НайденоДублей Цикл
			ТекстСообщения = ТекстСообщения + СтрокаДубля.Ссылка + Символы.ПС;
		КонецЦикла;
		
		ОбщегоНазначения.СообщитьПользователю(ТекстСообщения);
		
		// Если нужен жесткий запрет:
		Отказ = Истина;
	КонецЕсли;

КонецПроцедуры

Важное замечание про нечеткий поиск:
Если вы хотите, чтобы поиск находил не только полные совпадения (например, "Audi" и "Audi"), но и похожие ("Audi" и "Ауди"), вам потребуется использование Полнотекстового поиска. Для этого:

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

Итог

Для корректной работы БСП с объектами расширения необходимо соблюдать последовательность:

  1. Обновить идентификаторы: Запустите метод Справочники.ИдентификаторыОбъектовРасширений.ОбновитьДанные(), чтобы избавиться от ошибок типа "Неверный идентификатор".
  2. Подключить к подсистеме: Расширьте процедуру ПриОпределенииОбъектовСПоискомДублей, добавив туда ваш справочник.
  3. Настроить проверки: Используйте методы модуля ПоискИУдалениеДублей в событии ПередЗаписью вашего справочника.
← На главную