Как исправить задвоение предопределенных счетов в плане счетов после обновления 1С?

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

При обновлении нетиповых или доработанных конфигураций «1С:Предприятие 8.3» программисты часто сталкиваются с неприятной ситуацией: в режиме «1С:Предприятие» в плане счетов (например, «Хозрасчетный») некоторые счета задваиваются. При этом оба счета отображаются со значком предопределенного элемента («желтый шарик»), но в режиме Конфигуратора никакой задвоенности не видно.

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

Выясняем техническую причину: почему произошло задвоение?

Для того чтобы понять природу этой ошибки, нам необходимо заглянуть во внутреннюю архитектуру платформы «1С:Предприятие». База данных 1С хранит предопределенные элементы в виде физических записей в таблицах СУБД. Связующим звеном между объектом метаданных в Конфигураторе и записью в базе данных является уникальный идентификатор — GUID (UUID).

Рассмотрим пошагово стандартный сценарий, который приводит к сбою:

  1. В рабочей базе существовал счет (например, 76.10), который был создан вручную в режиме конфигуратора или перенесен некорректным обновлением. Ему был присвоен определенный GUID_A.
  2. В новой конфигурации поставщика (обновлении) также присутствует счет 76.10, но в конфигурации поставщика он имеет совершенно другой внутренний идентификатор — GUID_B.
  3. При обновлении конфигурации методом «Сравнение и объединение» (особенно если был включен флаг «Устанавливать соответствие по именам объектов») платформа сопоставляет счета по их текстовому представлению (имени), а не по внутреннему идентификатору.
  4. В результате объединения старая связь затирается. Платформа видит, что в конфигурации теперь прописан предопределенный счет с идентификатором GUID_B, и создает под него новую запись в базе данных. При этом старая запись с GUID_A также остается физически существовать в базе данных и сохраняет в поле ИмяПредопределенныхДанных привязку к метаданным.
  5. На выходе в режиме предприятия мы получаем два абсолютно одинаковых счета с одним кодом, и оба система считает предопределенными.

Давайте проанализируем три основных способа решения этой проблемы в зависимости от того, на каком этапе обнаружена ошибка и насколько критично восстанавливать базу из резервной копии.

Способ 1. Правильное обновление (рекомендуемый метод с откатом на бэкап)

Если с момента неудачного обновления прошло немного времени, в базе не велся активный ввод документов и у вас есть резервная копия (бэкап) до обновления — этот метод является самым чистым и безопасным.

Разберем алгоритм правильного обновления измененной конфигурации:

  1. Восстановите базу данных из резервной копии, сделанной до обновления.
  2. Откройте Конфигуратор и перейдите в меню «Конфигурация — Поддержка — Обновить конфигурацию». Настоятельно рекомендуем использовать именно штатный механизм поддержки через файлы обновлений (.cfu) или полные файлы дистрибутивов (.cf), а не простое сравнение/объединение файлов конфигураций.
  3. Если вы все же вынуждены использовать инструмент «Сравнить, объединить с конфигурацией из файла», то в открывшемся окне сравнения обязательно выполните следующие действия:
    • Нажмите кнопку «Параметры».
    • Найдите настройку «Устанавливать соответствие по именам объектов» и убедитесь, что для предопределенных данных этот флаг отключен. Сопоставление должно происходить строго по внутренним идентификаторам (GUID).
  4. Выполните объединение и обновите конфигурацию базы данных (клавиша F7). Платформа корректно сопоставит счета по их реальным ссылкам, и дублирования не произойдет.

Способ 2. Программное снятие предопределенности и слияние дублей

Что делать, если откат к резервной копии невозможен, так как в системе уже работают пользователи и заносить документы заново нельзя? В этом случае нам придется прибегнуть к программному исправлению непосредственно в рабочей базе.

Поскольку платформа не позволяет редактировать или удалять предопределенные элементы вручную, нам нужно временно «превратить» один из дублирующихся счетов в обычный (пользовательский), очистив у него свойство ИмяПредопределенныхДанных. После этого мы сможем воспользоваться стандартным механизмом поиска и замены дубликатов.

Для реализации этого метода создадим внешнюю обработку и напишем следующий код:


&НаСервере
Процедура СнятьПризнакПредопределенностиНаСервере(СсылкаНаНеправильныйСчет)
    
    // Получаем объект счета для редактирования
    ОбъектСчета = СсылкаНаНеправильныйСчет.ПолучитьОбъект();
    
    Если ОбъектСчета = Неопределено Тогда
        Сообщить("Не удалось получить объект счета. Возможно, он заблокирован.");
        Возврат;
    КонецЕсли;
    
    // Очищаем имя предопределенных данных. 
    // Именно это свойство отвечает за связь записи БД с метаданными конфигуратора.
    ОбъектСчета.ИмяПредопределенныхДанных = "";
    
    // В планах счетов также часто предопределены виды субконто.
    // Очистим признак предопределенности для строк табличной части субконто.
    Для Каждого СтрокаСубконто Из ОбъектСчета.ВидыСубконто Цикл
        СтрокаСубконто.Предопределенное = Ложь;
    КонецЦикла;
    
    // Записываем объект в базу данных без проверок контроля предопределенности
    Попытка
        ОбъектСчета.Записать();
        Сообщить("Успешно снята предопределенность со счета: " + ОбъектСчета.Код);
    Исключение
        Сообщить("Произошла ошибка при записи счета: " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Рассмотрим, как правильно применить данный код на практике:

  1. Создайте внешнюю обработку в режиме Конфигуратора, добавьте реквизит с типом ссылки на ваш план счетов (например, ПланСчетовСсылка.Хозрасчетный). Выведите его на форму вместе с кнопкой выполнения.
  2. В режиме «1С:Предприятие» откройте вашу обработку. В поле выбора укажите тот счет-дубль, который необходимо сделать обычным. Важно: убедитесь, что вы выбрали именно «старый» счет (тот, у которого сбилась иерархия или подчиненность), чтобы актуальный счет из новой конфигурации остался нетронутым.
  3. Выполните обработку. После успешного выполнения значок «желтого шарика» у выбранного счета в плане счетов пропадет. Теперь для системы это обычный счет, созданный пользователем.
  4. Перейдите в раздел «Администрирование — Обслуживание — Поиск и удаление дублей» (или воспользуйтесь аналогичной типовой обработкой «Поиск и замена значений»).
  5. В качестве «Правильного элемента» выберите оставшийся предопределенный счет (с шариком). В качестве «Дубликата» укажите счет, с которого мы только что сняли предопределенность.
  6. Запустите процесс объединения. Платформа автоматически найдет все использования старого счета во всех проводках, операциях, документах и регистрах, перепишет ссылки на новый правильный счет и безболезненно удалит ставший ненужным дубликат.

Способ 3. Прямая корректировка в таблицах СУБД (для SQL-версий баз)

Внимание! Этот метод является недокументированным, нарушает лицензионное соглашение фирмы 1С и должен применяться только опытными администраторами баз данных в экстренных случаях. Перед проведением любых работ в СУБД обязательно создайте резервную копию базы данных средствами SQL Server или PostgreSQL!

Если база данных работает в клиент-серверном режиме, метаданные предопределенности хранятся в SQL-таблицах. Для планов счетов это обычно таблицы с именами вида _AccX (где X — порядковый номер таблицы плана счетов).

Проанализируем схему исправления через СУБД:

  1. Остановите службу сервера «1С:Предприятие», чтобы разорвать все активные сессии пользователей и монопольно заблокировать таблицы.
  2. Откройте среду управления СУБД (например, SQL Server Management Studio для MS SQL) и найдите нужную базу данных.
  3. С помощью SQL-запроса найдите записи в таблице плана счетов, где поле кода соответствует вашему задвоенному счету:
    
    SELECT _IDRRef, _Code, _Description, _PredefinedID 
    FROM _Acc15 
    WHERE _Code = '76.10'
    
  4. В полученном результате вы увидите две строки. У «правильного» счета поле _PredefinedID будет заполнено актуальным бинарным идентификатором, соответствующим конфигурации. У «неправильного» (старого) счета это поле также будет заполнено старым идентификатором.
  5. Нам нужно очистить связь старого счета с метаданными. Для этого выполните запрос обновления, установив для старого счета значение _PredefinedID в 0x00... (пустой уникальный идентификатор) по его ссылке _IDRRef:
    
    UPDATE _Acc15 
    SET _PredefinedID = 0x00000000000000000000000000000000 
    WHERE _IDRRef = <Идентификатор_Старого_Счета>
    
  6. Запустите службу сервера «1С:Предприятие», очистите локальный кэш конфигурации на сервере и у пользователей.
  7. После этого старый счет в режиме Предприятия потеряет признак предопределенного, и вы сможете слить его с новым через стандартный поиск и замену дублей, как было описано во втором способе.

Профилактика: как избежать появления дублей в будущем?

Для того чтобы проблема не повторилась при выпуске следующих релизов обновлений, соблюдайте базовые правила разработки и ведения учета:

← На главную