При обновлении нетиповых или доработанных конфигураций «1С:Предприятие 8.3» программисты часто сталкиваются с неприятной ситуацией: в режиме «1С:Предприятие» в плане счетов (например, «Хозрасчетный») некоторые счета задваиваются. При этом оба счета отображаются со значком предопределенного элемента («желтый шарик»), но в режиме Конфигуратора никакой задвоенности не видно.
Попытки вручную изменить код, перенести подчиненность (родителя) или удалить один из таких счетов стандартными средствами обычно заканчиваются ошибками блокировки платформы. В этой статье мы подробно разберем, почему возникает эта проблема, как правильно ее исправить и как не допустить ее появления при последующих обновлениях.
Для того чтобы понять природу этой ошибки, нам необходимо заглянуть во внутреннюю архитектуру платформы «1С:Предприятие». База данных 1С хранит предопределенные элементы в виде физических записей в таблицах СУБД. Связующим звеном между объектом метаданных в Конфигураторе и записью в базе данных является уникальный идентификатор — GUID (UUID).
Рассмотрим пошагово стандартный сценарий, который приводит к сбою:
GUID_A.GUID_B.GUID_B, и создает под него новую запись в базе данных. При этом старая запись с GUID_A также остается физически существовать в базе данных и сохраняет в поле ИмяПредопределенныхДанных привязку к метаданным.Давайте проанализируем три основных способа решения этой проблемы в зависимости от того, на каком этапе обнаружена ошибка и насколько критично восстанавливать базу из резервной копии.
Если с момента неудачного обновления прошло немного времени, в базе не велся активный ввод документов и у вас есть резервная копия (бэкап) до обновления — этот метод является самым чистым и безопасным.
Разберем алгоритм правильного обновления измененной конфигурации:
.cfu) или полные файлы дистрибутивов (.cf), а не простое сравнение/объединение файлов конфигураций.Что делать, если откат к резервной копии невозможен, так как в системе уже работают пользователи и заносить документы заново нельзя? В этом случае нам придется прибегнуть к программному исправлению непосредственно в рабочей базе.
Поскольку платформа не позволяет редактировать или удалять предопределенные элементы вручную, нам нужно временно «превратить» один из дублирующихся счетов в обычный (пользовательский), очистив у него свойство ИмяПредопределенныхДанных. После этого мы сможем воспользоваться стандартным механизмом поиска и замены дубликатов.
Для реализации этого метода создадим внешнюю обработку и напишем следующий код:
&НаСервере
Процедура СнятьПризнакПредопределенностиНаСервере(СсылкаНаНеправильныйСчет)
// Получаем объект счета для редактирования
ОбъектСчета = СсылкаНаНеправильныйСчет.ПолучитьОбъект();
Если ОбъектСчета = Неопределено Тогда
Сообщить("Не удалось получить объект счета. Возможно, он заблокирован.");
Возврат;
КонецЕсли;
// Очищаем имя предопределенных данных.
// Именно это свойство отвечает за связь записи БД с метаданными конфигуратора.
ОбъектСчета.ИмяПредопределенныхДанных = "";
// В планах счетов также часто предопределены виды субконто.
// Очистим признак предопределенности для строк табличной части субконто.
Для Каждого СтрокаСубконто Из ОбъектСчета.ВидыСубконто Цикл
СтрокаСубконто.Предопределенное = Ложь;
КонецЦикла;
// Записываем объект в базу данных без проверок контроля предопределенности
Попытка
ОбъектСчета.Записать();
Сообщить("Успешно снята предопределенность со счета: " + ОбъектСчета.Код);
Исключение
Сообщить("Произошла ошибка при записи счета: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Рассмотрим, как правильно применить данный код на практике:
ПланСчетовСсылка.Хозрасчетный). Выведите его на форму вместе с кнопкой выполнения.Внимание! Этот метод является недокументированным, нарушает лицензионное соглашение фирмы 1С и должен применяться только опытными администраторами баз данных в экстренных случаях. Перед проведением любых работ в СУБД обязательно создайте резервную копию базы данных средствами SQL Server или PostgreSQL!
Если база данных работает в клиент-серверном режиме, метаданные предопределенности хранятся в SQL-таблицах. Для планов счетов это обычно таблицы с именами вида _AccX (где X — порядковый номер таблицы плана счетов).
Проанализируем схему исправления через СУБД:
SELECT _IDRRef, _Code, _Description, _PredefinedID
FROM _Acc15
WHERE _Code = '76.10'
_PredefinedID будет заполнено актуальным бинарным идентификатором, соответствующим конфигурации. У «неправильного» (старого) счета это поле также будет заполнено старым идентификатором._PredefinedID в 0x00... (пустой уникальный идентификатор) по его ссылке _IDRRef:
UPDATE _Acc15
SET _PredefinedID = 0x00000000000000000000000000000000
WHERE _IDRRef = <Идентификатор_Старого_Счета>
Для того чтобы проблема не повторилась при выпуске следующих релизов обновлений, соблюдайте базовые правила разработки и ведения учета:
.cf). В этом случае их GUID гарантированно совпадут.