Что делать, если задвоился предопределенный элемент плана видов расчета после обновления в 1С

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

В процессе поддержки и обновления старых или сильно кастомизированных конфигураций на платформе «1С:Предприятие» разработчики часто сталкиваются с неприятной ситуацией: после очередного обновления базы данных дублируется предопределенный элемент. Особенно болезненно это происходит в кадровых и расчетных базах, таких как «Зарплата и управление персоналом» редакции 2.5. Например, может задвоиться критически важный предопределенный элемент плана видов расчета (ПВР) «Районный коэффициент» или «Северная надбавка».

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

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

Для того чтобы понять корень проблемы, нам необходимо обратиться к архитектуре платформы «1С:Предприятие». Связь между предопределенным элементом, описанным разработчиком в конфигураторе, и реальной физической записью в таблице базы данных (в режиме «1С:Предприятие») в старых версиях платформы (до версии 8.3.3) и во всех конфигурациях, работающих в режиме совместимости с версией 8.2, осуществляется строго по внутреннему уникальному идентификатору — UUID (Universally Unique Identifier).

Когда мы обновляем конфигурацию, платформа выполняет сопоставление объектов. Сценарий возникновения дубля выглядит следующим образом:

  1. В процессе разработки обновления (либо в компании «1С», либо силами программистов обслуживающей организации) предопределенный элемент «Районный коэффициент» был удален из метаданных плана видов расчета, а затем создан заново с тем же самым именем (идентификатором).
  2. Несмотря на то что имя элемента осталось прежним, его внутренний уникальный идентификатор (UUID) в метаданных изменился.
  3. При обновлении информационной базы платформа анализирует список предопределенных элементов. Обнаружив новый UUID, она автоматически создает в базе данных новую запись ПВР с признаком предопределенного.
  4. Старая запись ПВР, которая содержала старый UUID, больше не находит соответствия в метаданных конфигуратора. Платформа снимает с нее признак предопределенности, превращая в обычный пользовательский элемент. При этом все созданные ранее документы, кадровые перемещения, начисления зарплаты и записи в регистрах расчета продолжают ссылаться именно на этот «старый» элемент.

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

Разбор типичных ошибок и заблуждений при решении проблемы

Проанализируем обсуждения специалистов и выделим ключевые ошибки, которые часто совершаются при попытке быстро исправить эту ситуацию.

Попытка восстановить предопределенность через код. Некоторые разработчики пытаются программно перезаписать имя предопределенного элемента, используя свойства ИмяПредопределенного или ИмяПредопределенныхДанных у объекта. В конфигурациях уровня ЗУП 2.5, работающих в режиме совместимости с платформой 8.2, этот код вызовет ошибку: Поле объекта не обнаружено (ИмяПредопределенныхДанных). Данный механизм управления предопределенными данными напрямую из кода был добавлен только в платформе 8.3.3 и работает исключительно при отключенном режиме совместимости. В нашем случае восстановить связь «старого» элемента с метаданными программным путем невозможно.

Заблуждение об ограничениях стандартных обработок. Существует мнение, что стандартные обработки поиска и замены дублей (например, с дисков или портала ИТС) умеют работать только со справочниками. Это абсолютно не так. Универсальная обработка «Поиск и замена значений» (ПоискИЗаменаЗначений.epf) работает напрямую со ссылочными типами данных метаданных платформы «1С:Предприятие» и способна находить и корректно заменять ссылки любого типа, включая документы, планы счетов, виды субконто и планы видов расчета.

Опасность перепроведения документов. Самая главная и критическая ошибка — это замена ссылок ручным кодом с последующим групповым перепроведением документов прошлых периодов. В таких конфигурациях, как «Зарплата и управление персоналом», перепроводить документы за закрытые периоды прошлых месяцев или лет категорически запрещено. Это неизбежно приведет к:

Правильный алгоритм решения проблемы «малой кровью»

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

Рассмотрим два основных и наиболее безопасных способа реализации этой задачи.

Способ 1. Использование универсальной обработки «Поиск и замена значений»

Этот способ является наиболее предпочтительным, так как он не требует написания кода и полностью исключает человеческий фактор при составлении алгоритмов перезаписи объектов.

  1. Найдите на портале 1С:ИТС или в каталоге шаблонов установленных конфигураций внешнюю обработку ПоискИЗаменаЗначений.epf (обратите внимание, что вам нужна версия для обычных форм, если вы работаете в ЗУП 2.5).
  2. Запустите обработку в режиме «1С:Предприятие» через меню «Файл» — «Открыть».
  3. В поле «Что заменять» выберите наш старый элемент плана видов расчета «Районный коэффициент» (который теперь отображается без золотой точки).
  4. В поле «На что заменять» выберите новый предопределенный элемент «Районный коэффициент» (с золотой точкой).
  5. Нажмите кнопку «Найти ссылки». Обработка просканирует всю базу данных и выведет список всех объектов (документов, регистров расчета, регистров сведений, настроек), где используется старая ссылка.
  6. Нажмите кнопку «Выполнить замену».

Универсальная обработка автоматически производит запись всех найденных объектов с установленным флагом ОбменДанными.Загрузка = Истина. Это гарантирует, что документы не будут перепроводиться, а записи регистров изменятся напрямую в базе данных без искажения исторических расчетов.

Способ 2. Программная замена ссылок (для разработчиков)

Если по каким-то причинам у вас нет доступа к стандартной обработке, мы можем написать небольшую самописную обработку, которая выполнит замену точечно и безопасно. Рассмотрим, как правильно спроектировать этот код.

При написании скрипта ключевое правило — использовать свойство ОбменДанными.Загрузка = Истина для каждого изменяемого объекта. Проанализируем пример кода для замены ссылок в документах:


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

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

Рассмотрим, как выглядит процедура корректного изменения записей в регистре расчета:


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

Завершение процедуры слияния

После того как замена ссылок во всех документах и движениях регистров успешно завершена одним из описанных способов, нам необходимо выполнить финальные действия по очистке базы данных:

  1. Убедитесь, что на старый (не предопределенный) элемент ПВР больше нет ссылок в системе. Для этого можно повторно запустить поиск ссылок или воспользоваться стандартной операцией удаления помеченных объектов.
  2. Пометьте старый элемент ПВР на удаление.
  3. Запустите монопольное удаление помеченных объектов (меню «Операции» — «Удаление помеченных объектов»). Платформа должна безболезненно удалить старый элемент, так как все зависимости были перенесены на новый предопределенный элемент.

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

← На главную