При запуске информационной базы 1С:Зарплата и Управление Персоналом (или других конфигураций на базе Библиотеки стандартных подсистем) пользователи могут столкнуться с аварийным завершением работы. В окне ошибки выводится сообщение следующего вида: {ОбщийМодуль.ОбновлениеИнформационнойБазыСлужебныйПовтИсп.Модуль(51)}: Значение не является значением объектного типа (Получить), а проблемная строка выглядит так: Параметры = Константы[ИмяКонстанты].Получить().Получить();.
Разберем детально, почему возникает данный сбой и какими способами можно восстановить работоспособность информационной базы.
Проанализируем программный код, вызвавший исключение. Конструкция вида Константы[ИмяКонстанты].Получить().Получить() использует так называемое двойное разыменование:
Получить() обращается к объекту метаданных КонстантаМенеджер и считывает текущее значение из базы данных. Для служебных констант БСП этим значением является объект типа ХранилищеЗначения.Получить() применяется уже непосредственно к объекту ХранилищеЗначения, чтобы извлечь из него упакованные данные (как правило, структуру параметров работы программы).Если константа в базе данных не была проинициализирована (например, после некорректного накатывания релиза), первое обращение возвращает значение Неопределено. Соответственно, попытка вызвать метод Получить() у значения Неопределено приводит к критической ошибке платформы.
Выделим основные причины, почему константа оказывается пустой:
Неопределено перед чтением хранилища.Если база находится на поддержке и менять код конфигурации нежелательно, проинициализируем проблемные константы с помощью внешнего скрипта или обработки. К числу констант, вызывающих данное исключение, чаще всего относятся: ПараметрыРаботыПрограммы, ПараметрыБазовойФункциональности, ПараметрыРаботыПользователей, ПараметрыСообщенияПриОбращенииВОтделТехническойПоддержки.
Рассмотрим пример кода для внешней обработки или консоли кода, который создает пустое хранилище значения и записывает его в константу:
ИмяКонстанты = "ПараметрыРаботыПрограммы";
Константы[ИмяКонстанты].Установить(Новый ХранилищеЗначения(Новый Структура));
// При необходимости повторим для остальных системных констант
ИмяКонстантыБФ = "ПараметрыБазовойФункциональности";
Если Метаданные.Константы.Найти(ИмяКонстантыБФ) <> Неопределено Тогда
Константы[ИмяКонстантыБФ].Установить(Новый ХранилищеЗначения(Новый Структура));
КонецЕсли;
Запустить внешнюю обработку в аварийной базе можно через командную строку с ключом /Execute <ПутьКФайлуОбработки>.
Если конфигурация уже снята с поддержки или находится в режиме возможности редактирования, устраним причину ошибки непосредственно в коде модуля ОбновлениеИнформационнойБазыСлужебныйПовтИсп. Для этого разделим получение значения константы и распаковку данных безопасным условием.
Посмотрим на исправленный вариант функции ПараметрыРаботыПрограммы:
Функция ПараметрыРаботыПрограммы(ИмяКонстанты) Экспорт
УстановитьПривилегированныйРежим(Истина);
Хранилище = Константы[ИмяКонстанты].Получить();
Если Хранилище = Неопределено Тогда
Параметры = Новый Структура;
Константы[ИмяКонстанты].Установить(Новый ХранилищеЗначения(Параметры));
Иначе
Параметры = Хранилище.Получить();
Если ТипЗнч(Параметры) <> Тип("Структура") Тогда
Параметры = Новый Структура;
Константы[ИмяКонстанты].Установить(Новый ХранилищеЗначения(Параметры));
КонецЕсли;
КонецЕсли;
Возврат Новый ФиксированнаяСтруктура(Параметры);
КонецФункции
Такая конструкция гарантирует, что даже при полностью пустом значении константы в базе метод не упадет, а создаст новую пустую структуру и корректно вернет ФиксированнаяСтруктура.
Если ошибка возникла внезапно без явного обновления, выполним регламентные процедуры по восстановлению целостности информационной базы:
%LocalAppData%\1C\1cv8 и %AppData%\1C\1cv8.Если ошибка стала следствием пропуска релизов, наиболее правильным шагом будет возврат к резервной копии базы до обновления. Выполним последовательное обновление конфигурации строго по цепочке релизов, указанной в файле ReadMe.txt к каждому дистрибутиву обновления, запуская информационную базу в режиме «Предприятие» после каждого промежуточного шага для завершения работы служебных процедур обновления.