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