При активном сопровождении и доработке нетиповых конфигураций на платформе 1С:Предприятие 8.3 (например, измененной конфигурации 1С:Бухгалтерия предприятия 3.0) разработчики регулярно сталкиваются со специфическими трудностями синхронизации данных. Одной из наиболее сложных и неочевидных проблем является сбой обмена в распределенных информационных базах (РИБ) при добавлении новых предопределенных счетов в план счетов.
В процессе загрузки файла обмена в периферийном узле (ПБ) система может аварийно завершить работу, выдав ошибку: «Не предопределенные объекты не могут иметь предопределенные записи видов субконто». При этом отмена регистрации изменений данных для плана счетов часто приводит к другой ошибке — нарушению структуры XML-пакета. Давайте подробно разберем причины этой проблемы и рассмотрим надежные практические методы её решения.
Для того чтобы понять природу ошибки, проанализируем, как платформа 1С работает с предопределенными элементами, начиная с версии 8.3. В современных версиях платформы предопределенные элементы разделены на два уровня:
ИмяПредопределенныхДанных.В планах счетов табличная часть видов субконто (ВидыСубконто) имеет свой собственный внутренний признак — Предопределенное (для строк субконто). Платформа накладывает жесткое логическое ограничение: предопределенные строки субконто могут быть записаны только в те счета, которые уже признаны системой как предопределенные.
В контексте распределенных баз (РИБ) во время выполнения метода ПрочитатьИзменения() происходит одновременное получение и обновление конфигурации, и загрузка измененных данных. Из-за внутренней специфики транзакций СУБД новые счета записываются в базу данных подчиненного узла как обычные элементы до того, как платформа окончательно обновит конфигурацию базы данных и свяжет новые элементы с метаданными (заполнив поле ИмяПредопределенныхДанных).
В этот критический момент транзакции платформа считает импортируемый счет обычным (созданным пользователем вручную), видит в его табличной части предопределенные виды субконто и немедленно прерывает транзакцию с ошибкой. Это поведение может проявляться даже на современных релизах платформ при использовании режима совместимости или сложных кастомных планов счетов.
Рассмотрим проверенные на практике методы обхода и устранения этой проблемы.
Если у вас нет прямого доступа к конфигураторам периферийных узлов или политика безопасности запрещает ручное вмешательство в базы подчиненных узлов, этот способ будет самым безопасным и простым. Мы разделим процесс внедрения новых предопределенных счетов на два последовательных релиза.
Шаг 1: Создание пустых счетов в Центральной базе (ЦБ)
В конфигураторе центральной базы добавим новые предопределенные счета. При этом табличную часть ВидыСубконто у этих счетов оставим абсолютно пустой. Обновим конфигурацию базы данных ЦБ и выполним стандартный сеанс обмена с периферийными узлами.
Поскольку у новых счетов нет аналитики, обмен пройдет без ошибок. В подчиненных базах успешно создадутся новые счета, и платформа корректно свяжет их с метаданными как предопределенные элементы.
Шаг 2: Добавление видов субконто в ЦБ
После того как все периферийные узлы успешно завершили обмен первого этапа, вернемся в конфигуратор центральной базы. Теперь мы можем спокойно добавить нужные виды субконто к созданным ранее счетам. Выпустим второй релиз конфигурации и выполним повторный обмен. При чтении пакета аналитика без проблем запишется в уже существующие и сопоставленные предопределенные счета.
Этот метод гарантирует стопроцентный результат, так как мы принудительно обновим структуру метаданных в периферийной базе до того, как запустим процесс импорта данных из файла обмена.
Проанализируем пошагово, как это сделать:
.cf) из обновленной Центральной базы через меню Конфигурация -> Сохранить конфигурацию в файл....
// Программное отключение периферийной базы от главного узла
ПланыОбмена.УстановитьГлавныйУзел(Неопределено);
.cf-файл. Применим изменения (клавиша F7).
// Восстановление связи с центральной базой
СсылкаНаГлавный = ПланыОбмена.НайтиПоКоду("ЦБ"); // Укажите код вашего главного узла
Если ЗначениеЗаполнено(СсылкаНаГлавный) Тогда
ПланыОбмена.УстановитьГлавныйУзел(СсылкаНаГлавный);
КонецЕсли;
Иногда ошибка возникает из-за того, что в подчиненном узле счета уже были созданы, но у них по какой-то причине сбилось или очистилось внутреннее свойство ИмяПредопределенныхДанных. Платформа видит эти счета как созданные вручную пользователем.
Для исправления этой ситуации мы можем программно восстановить связь объектов базы данных с метаданными конфигурации. Для этого запустим в проблемном узле обработку со следующим кодом:
// Восстановление предопределенного свойства для конкретного счета
СчетСсылка = ПланыСчетов.Хозрасчетный.НайтиПоКоду("10.12"); // Пример проблемного счета
Если Не СчетСсылка.Пустая() Тогда
СчетОбъект = СчетСсылка.ПолучитьОбъект();
// Заполняем имя предопределенных данных, как оно задано в конфигураторе
СчетОбъект.ИмяПредопределенныхДанных = "МатериалыВПути";
СчетОбъект.ОбменДанными.Загрузка = Истина;
Попытка
СчетОбъект.Записать();
Сообщить("Связь предопределенного счета успешно восстановлена!");
Исключение
Сообщить("Ошибка записи: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
После записи объекта с установленным свойством ИмяПредопределенныхДанных платформа снова начнет считать этот счет предопределенным, и последующий импорт видов субконто пройдет штатно.
Очень часто ошибка усугубляется тем, что новые предопределенные счета ошибочно регистрируются к обмену как обычные изменения данных в Центральной базе. Предопределенные элементы должны переноситься исключительно на уровне метаданных конфигурации, а не через XML-сериализацию объектов данных.
Рассмотрим, как правильно очистить регистрацию:
Хозрасчетный).Используя приведенные методики, мы сможем эффективно и безболезненно обновлять любые сложные планы счетов в распределенных информационных системах 1С.