Как обновить вспомогательные данные для объектов из расширения в 1С:Предприятии?

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

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

В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы Библиотеки стандартных подсистем (БСП) и рассмотрим несколько надежных способов её решения.

Выясняем причину: почему БСП «не видит» новые объекты расширения?

Для корректной работы механизмов разграничения прав доступа, бизнес-процессов и других служебных функций БСП хранит уникальные идентификаторы всех объектов конфигурации в справочнике ИдентификаторыОбъектовМетаданных. Для объектов из расширений предусмотрен отдельный механизм синхронизации с использованием регистра сведений ИдентификаторыОбъектовВерсийРасширений.

Когда мы пытаемся обновить вспомогательные данные (например, запуская конфигурацию с параметром /C ЗапуститьОбновлениеИнформационнойБазы), БСП обращается к функции СвойстваКоллекцийОбъектовМетаданных(), которая расположена в модуле менеджера справочника ИдентификаторыОбъектовМетаданных.

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

Решение 1. Исправление логики БСП через переопределение метода (Рекомендуемый способ)

Чтобы решить проблему раз и навсегда без снятия основной конфигурации с поддержки, мы можем использовать механизм расширений. Нам потребуется перехватить выполнение функции СвойстваКоллекцийОбъектовМетаданных() с помощью директивы &Вместо.

Выполним следующие шаги:

  1. Создадим новое служебное расширение или воспользуемся существующим.
  2. Добавим в расширение справочник ИдентификаторыОбъектовМетаданных и перенесем его модуль менеджера.
  3. В модуле менеджера переопределим функцию СвойстваКоллекцийОбъектовМетаданных().

Проанализируем пример кода, который принудительно включает поддержку расширений для необходимых нам типов объектов (например, для констант и справочников):


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

После применения данного расширения БСП начнет видеть ваши новые объекты констант или справочников. Теперь запуск обновления данных успешно зарегистрирует их в системе.

Решение 2. Принудительное программное обновление данных

Бывают ситуации, когда типовые обработки обновления утверждают, что «обновление не требуется». Это происходит потому, что версия конфигурации не изменилась. В таком случае мы можем запустить процесс обновления принудительно с помощью внешней обработки.

Создадим простую внешнюю обработку, добавим на форму кнопку и пропишем следующий код в её модуле на сервере:


&НаСервере
Процедура ПринудительноОбновитьДанныеНаСервере()
	
	УстановитьПривилегированныйРежим(Истина);
	
	// 1. Принудительно обновляем данные основного справочника идентификаторов
	ПараметрыОбновления = Справочники.ИдентификаторыОбъектовМетаданных.ПараметрыОбновитьДанныеСправочника();
	ПараметрыОбновления.ЗаписатьНовыеИдентификаторы = Истина;
	ПараметрыОбновления.ПометитьНаУдалениеНеиспользуемые = Истина;
	
	Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника(ПараметрыОбновления);
	
	// 2. Вызываем обновление идентификаторов объектов расширений БСП
	Справочники.ИдентификаторыОбъектовРасширений.ОбновитьДанныеСправочника(Истина);
	
	Сообщить("Вспомогательные данные расширений успешно обновлены!");
	
КонецПроцедуры

Обратите внимание, что данный код следует запускать в монопольном режиме (когда в базе нет других активных пользователей и фоновых заданий), чтобы избежать конфликтов блокировок таблиц СУБД.

Решение 3. Тонкости использования ключей командной строки при запуске

Часто разработчики пытаются использовать параметр запуска /С ЗапуститьОбновлениеИнформационнойБазы, но не получают ожидаемого результата. Давайте разберем основные подводные камни этого подхода:

Особенности работы в распределенных информационных базах (РИБ)

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

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

← На главную