При работе с конфигурацией «Бухгалтерия государственного учреждения 2.0» (БГУ 2.0), особенно в режиме разделения данных (областей), программисты и администраторы часто сталкиваются с критической остановкой обновления. Ошибка в журнале регистрации вида Запись с такими ключевыми полями существует! : КЭК: 401.40 (Регистр сведений: КЭК счетов) блокирует вход в область данных, а попытки открыть форму списка регистра стандартными средствами приводят к тому, что форма оказывается пустой. Рассмотрим детально, почему это происходит и как восстановить работоспособность базы.
Разберем ситуацию, когда программист пытается открыть форму регистра через ОткрытьФорму, но не видит записей, хотя они точно есть в базе. В конфигурации БГУ 2.0 для многих регистров сведений, включая КЭКСчетов, в коде формы списка прописаны жесткие алгоритмы фильтрации. Проанализируем, почему это происходит:
Для корректного открытия формы списка из программного кода (если вход в предприятие все же выполнен) необходимо использовать только клиентские методы. Выясним, как выглядит правильный вызов:
&НаКлиенте
Процедура ОткрытьРегистр(Команда)
// Не используйте серверные вызовы для открытия форм!
// Правильный путь к форме через точку "Форма"
ОткрытьФорму("РегистрСведений.КЭКСчетов.Форма.ФормаСписка");
КонецПроцедуры
Рассмотрим подробнее техническую сторону ошибки «Запись с такими ключевыми полями существует». Ключевые поля (измерения) регистра сведений — это уникальный идентификатор строки. В регистре КЭКСчетов измерениями обычно являются Счет, КЭК и, в некоторых случаях, дополнительные разрезы. Если система пытается записать строку с комбинацией, которая уже есть в базе, возникает исключение.
Выясним причину возникновения дублей именно во время обновления. Чаще всего это связано с тем, что в новом релизе БГУ 2.0 меняется логика заполнения КЭК (КОСГУ) для определенных счетов (например, счета 401.40 «Доходы будущих периодов»). Обработчик обновления считывает старые данные, трансформирует их и пытается записать обратно. Если в исходных данных были «мусорные» записи или если алгоритм трансформации ошибочно приводит разные старые записи к одной новой — обновление падает.
Проанализируем ситуацию: в базу зайти нельзя, так как обновление прерывается ошибкой, а консоль запросов не работает, потому что область не инициализирована. В этом случае мы воспользуемся механизмом запуска внешней обработки через окно технической информации.
Шаг 1: Подготовка внешней обработки очистки
Нам необходимо создать внешнюю обработку, которая принудительно удалит дублирующие записи или очистит регистр перед запуском обновления. Рассмотрим пример кода для поиска и удаления дублей:
// В модуле объекта внешней обработки
Процедура ВыполнитьОчистку() Экспорт
Запрос = Новый Запрос;
Запрос.Text =
"ВЫБРАТЬ
| КЭКСчетов.Счет КАК Счет,
| КЭКСчетов.КЭК КАК КЭК,
| КОЛИЧЕСТВО(*) КАК КолВо
|ИЗ
| РегистрСведений.КЭКСчетов КАК КЭКСчетов
|СГРУППИРОВАТЬ ПО
| КЭКСчетов.Счет,
| КЭКСчетов.КЭК
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(*) > 1";
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
// Набор записей для удаления дублей
Набор = РегистрыСведений.КЭКСчетов.СоздатьНаборЗаписей();
Набор.Отбор.Счет.Установить(Выборка.Счет);
Набор.Отбор.КЭК.Установить(Выборка.КЭК);
Набор.Записать(); // Очищает все записи по этому сочетанию
Сообщить("Удалены дубли по счету: " + Выборка.Счет + " и КЭК: " + Выборка.КЭК);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Шаг 2: Запуск в аварийном режиме
Когда при входе в область данных появляется окно с ошибкой обновления, выполним следующие действия:
/C ЗапуститьОбновлениеИнформационнойБазы. Это принудительно вызовет процедуру обновления, но иногда позволяет перешагнуть через блокировку интерфейса.Если внешняя обработка не помогает из-за ограничений разделения данных, применим метод внедрения через Расширение конфигурации. Рассмотрим этот вариант как наиболее надежный для программиста:
ОбновлениеИнформационнойБазы (или аналогичный модуль БГУ, где происходит работа с КЭК).НаборЗаписей.Записать()), используя аннотацию &Перед.
&Перед("ЗаписатьНаборКЭК") // Имя процедуры из вашего стека ошибки
Процедура Расш1_ЗаписатьНаборКЭК(НаборЗаписей)
ТЗ = НаборЗаписей.Выгрузить();
ТЗ.Свернуть("Счет, КЭК, Квалификатор", "Сумма, Количество"); // Указываем измерения
НаборЗаписей.Загрузить(ТЗ);
КонецПроцедуры
Этот метод позволяет «на лету» исправлять ошибки самого кода обновления, который пытается записать некорректные данные. Важно помнить: после успешного завершения обновления расширение необходимо отключить, чтобы не маскировать возможные логические ошибки учета в будущем.
Подводя итоги, отметим, что ошибка дублей в регистре КЭКСчетов — это чаще всего следствие некорректных данных, накопленных до обновления. Для предотвращения таких ситуаций рекомендуем:
<Объект не найден>) в измерениях.Еще — Установить стандартные настройки.Помните, что работа в разделенной базе (областях) накладывает свои ограничения на использование стандартных инструментов типа консоли запросов, поэтому навык написания корректирующих обработок «вслепую» является критически важным для специалиста 1С.