Каждый разработчик или администратор баз данных 1С хотя бы раз сталкивался с ситуацией, когда после очередного обновления конфигурации или некорректного переноса данных система начинает выдавать пугающую ошибку: «Ошибка при получении атрибута контекста». Особенно неприятно, когда эта ошибка возникает при обращении к, казалось бы, существующему предопределенному элементу справочника, например: Справочники.ПрочиеДоходыИРасходы.ВосстановлениеСтоимостиПрочегоИмущества.
В этой статье мы подробно разберем, почему возникает эта проблема в платформе «1С:Предприятие 8.3», как устроен механизм предопределенных данных «под капотом» и какими практическими способами можно быстро и безопасно восстановить работоспособность системы.
Проанализируем типичный сценарий: во время обновления конфигурации предопределенный элемент справочника был удален (или изменен его уникальный идентификатор). Обнаружив пропажу, администратор или программист решает проблему «в лоб» — просто создает в режиме «1С:Предприятие» новый элемент с точно таким же наименованием и кодом. Однако при первом же обращении программы к этому элементу через код происходит аварийное завершение операции с ошибкой получения атрибута контекста. Выясним, почему так происходит.
Начиная с версии платформы 8.3.5, разработчики «1С» кардинально изменили логику работы с предопределенными элементами. В старых версиях (платформа 8.2 и более ранние) связь между объектом в конфигураторе и записью в базе данных жестко фиксировалась по внутреннему уникальному идентификатору (GUID). В современных версиях 1С 8.3 эта связь стала более гибкой, но и более сложной.
Теперь ключевым связующим звеном является специальный стандартный реквизит ИмяПредопределенныхДанных. В конфигураторе мы задаем имя элемента (например, ВосстановлениеСтоимостиПрочегоИмущества). В базе данных у соответствующей записи в таблице справочника в поле ИмяПредопределенныхДанных должно быть записано точно такое же строковое значение.
Когда мы обращаемся к элементу программно: Справочники.ПрочиеДоходыИРасходы.ВосстановлениеСтоимостиПрочегоИмущества, платформа выполняет запрос к базе данных, пытаясь найти строку, у которой реквизит ИмяПредопределенныхДанных равен значению "ВосстановлениеСтоимостиПрочегоИмущества". Если мы просто создали элемент вручную через интерфейс программы, мы получили обычный, непредопределенный элемент. Его реквизит ИмяПредопределенныхДанных пуст. Платформа не находит нужной записи в базе данных и сообщает нам, что такого свойства (атрибута контекста) у менеджера справочника не существует.
Ниже мы подробно рассмотрим четыре практических способа решения этой проблемы, начиная от быстрого написания кода «на коленке» до использования стандартных механизмов БСП.
Если в вашей базе данных уже создан элемент вручную, и пользователи успели выбрать его в десятках документов, удалять его и создавать заново крайне нежелательно — это приведет к появлению битых ссылок. Самый быстрый способ исправить ситуацию — программно записать в существующий элемент нужное имя предопределенных данных.
Давайте посмотрим на пример кода, который можно запустить с помощью внешней обработки или консоли кода:
&НаСервере
Процедура СвязатьЭлементНаСервере()
// Шаг 1. Находим созданный вручную элемент по наименованию или коду
ИмяСправочника = "ПрочиеДоходыИРасходы";
ИмяПредопределенного = "ВосстановлениеСтоимостиПрочегоИмущества";
НаименованиеПоиска = "Восстановление стоимости прочего имущества";
СсылкаНаЭлемент = Справочники[ИмяСправочника].НайтиПоНаименованию(НаименованиеПоиска);
Если Не СсылкаНаЭлемент.Пустая() Тогда
// Шаг 2. Получаем объект для редактирования
ОбъектСправочника = СсылкаНаЭлемент.ПолучитьОбъект();
// Шаг 3. Заполняем имя предопределенных данных в соответствии с Конфигуратором
ОбъектСправочника.ИмяПредопределенныхДанных = ИмяПредопределенного;
Попытка
ОбъектСправочника.Записать();
Сообщить("Связь успешно установлена! Элемент стал предопределенным.");
Исключение
Сообщить("Не удалось записать изменения: " + ОписаниеОшибки());
КонецПопытки;
Иначе
Сообщить("Элемент с наименованием '" + НаименованиеПоиска + "' не найден в базе данных.");
КонецЕсли;
КонецПроцедуры
После успешного выполнения этой процедуры пиктограмма элемента в списке справочника изменится — на ней появится характерная желтая точка, указывающая на то, что элемент стал предопределенным. Ошибка инициализации атрибута контекста будет устранена.
Если вы работаете в типовой конфигурации 1С (например, 1С:Бухгалтерия, 1С:ERP или 1С:Управление торговлей), то в нее гарантированно интегрирована Библиотека стандартных подсистем (БСП). В БСП встроены мощные механизмы автоматического восстановления структуры данных.
Рассмотрим этот процесс по шагам:
Справочники.ПрочиеДоходыИРасходы.ВосстановитьПредопределенныеЭлементы();
Или воспользуйтесь общим методом для всех справочников системы:
СтандартныеПодсистемыСервер.УстановитьОбновлениеПредопределенныхДанных(Истина);
После этого в справочнике появится новый элемент (с желтой точкой), созданный самой системой.Прочие доходы и расходы.Если вы не хотите писать код или запускать сложные процедуры поиска дублей, можно воспользоваться готовыми решениями от сообщества разработчиков. Существуют универсальные внешние обработки для интерактивного связывания предопределенных элементов.
Принцип работы таких обработок чрезвычайно прост и удобен:
Прочие доходы и расходы).ИмяПредопределенныхДанных без написания кода вручную.Иногда восстановить логическую целостность базы данных можно с помощью встроенных утилит администрирования платформы 1С. Для этого мы можем задействовать штатный режим «Тестирование и исправление».
Прежде чем приступить, выполните важное действие: откройте свойства вашего справочника в Конфигураторе и найдите свойство «Обновление предопределенных данных». Убедитесь, что там установлено значение Авто или Обновлять автоматически. Если там стоит значение Не обновлять, платформа проигнорирует любые попытки автоматического восстановления.
Выполним процедуру исправления по шагам:
После завершения тестирования запустите программу в режиме «1С:Предприятие» и проверьте справочник. Недостающий предопределенный элемент будет создан автоматически. Вам останется лишь объединить его с ручным дублем с помощью стандартной обработки, как это было описано во втором способе. Для быстрого переноса ссылок на восстановленный элемент можно использовать обработку для поиска и замены значений во всей информационной базе.
Мы подробно проанализировали внутренние механизмы платформы 1С 8.3 и выяснили, почему обычное ручное создание элемента справочника с аналогичным именем и кодом не решает проблему отсутствия предопределенного элемента. Платформе требуется строгое совпадение реквизита ИмяПредопределенныхДанных.
Чтобы избежать подобных ошибок в будущем, соблюдайте простые правила: