При выполнении обмена данными или загрузке информации через универсальную обработку «Выгрузка и загрузка данных XML» в чистую базу 1С, программисты часто сталкиваются с блокирующей ошибкой. Система выдает сообщение: «Не удалось записать валюту, так как еще не завершился фоновый пересчет курсов. Попробуйте записать валюту позже». Ситуация осложняется тем, что даже при полностью отключенных регламентных заданиях и установленном флаге ОбменДанными.Загрузка = Истина, ошибка продолжает возникать, прерывая процесс импорта данных.
В этой статье мы подробно разберем, почему возникает эта блокировка, где в системе спрятаны «рычаги» управления этим процессом и как программно или административно решить данную проблему.
Давайте разберем внутреннюю логику работы современных конфигураций на базе БСП (Библиотеки стандартных подсистем), таких как 1С:ERP, УТ 11 или Бухгалтерия предприятия 3.0. Ошибка генерируется в модуле объекта справочника Валюты. В процедуре ПриЗаписи или ПередЗаписью вызывается специализированная проверка целостности данных.
Основная причина кроется в механизме зависимых курсов валют. В 1С курсы одних валют могут рассчитываться на основании курсов других (базовых) валют по определенной формуле. Чтобы избежать ситуации, когда пользователь или внешняя обработка меняет данные в момент, когда система сама производит автоматический расчет, разработчики 1С предусмотрели «программную блокировку».
Проблема в том, что статус этой блокировки записывается в базу данных. Если предыдущий процесс пересчета был прерван аварийно или база была скопирована с «зависшим» статусом, флаг блокировки остается активным, даже если никакие фоновые задания фактически не выполняются.
Первым делом нам необходимо выяснить, где именно система хранит информацию о «якобы» идущем процессе пересчета. В большинстве случаев за это отвечает константа или запись в структуре параметров. Проанализируем состав констант вашей базы.
Рассмотрим алгоритм поиска и исправления:
ПараметрыКурсовВалют. Это структура (хранилище значений), в которой содержится поле СтатусФоновогоПересчета.СтатусФоновогоПересчетаКурсовВалют.Для сброса можно воспользоваться простым фрагментом кода:
НаборКонстант = Константы.ПараметрыКурсовВалют.СоздатьНабор();
Параметры = Константы.ПараметрыКурсовВалют.Получить().Получить();
Если ТипЗнч(Параметры) = Тип("Структура") Тогда
Параметры.Вставить("СтатусФоновогоПересчета", Перечисления.СтатусыФоновогоЗадания.Завершено);
Константы.ПараметрыКурсовВалют.Установить(Новый ХранилищеЗначения(Параметры));
Сообщить("Статус пересчета курсов успешно сброшен.");
КонецЕсли;
Иногда сброса константы недостаточно, так как система проверяет наличие заданий в техническом регистре сведений. Посмотрим на ситуацию глубже: если в регистре ОчередьПересчетаКурсовВалют (название может варьироваться в зависимости от версии конфигурации) есть записи, объект Валюта может блокироваться при записи.
Проанализируем содержимое этого регистра. Если вы производите первичную загрузку данных в чистую базу, этот регистр должен быть пуст. Выполните его очистку, если там содержатся «зависшие» записи о валютах, которые вы как раз пытаетесь загрузить.
Многие программисты удивляются, почему стандартный механизм подавления проверок ОбменДанными.Загрузка = Истина игнорируется. Разберем код в модуле объекта справочника Валюты. Часто проверка реализована следующим образом:
Процедура ПередЗаписью(Отказ)
Если ОбменДанными.Загрузка Тогда
// Казалось бы, здесь должен быть возврат, но...
КонецЕсли;
// Вызов общего модуля, который проверяет блокировку
КурсыВалют.ПроверитьВозможностьЗаписиВалюты(ЭтотОбъект);
КонецПроцедуры
Разработчики типовых решений намеренно выносят проверку возможности записи за пределы условия ОбменДанными.Загрузка, чтобы гарантировать, что формулы расчета курсов не «разойдутся» с реальностью. Чтобы обойти это при массовой загрузке, можно временно прибегнуть к расширению или модификации модуля.
Если вы уверены, что фоновые процессы не запущены, а очистка констант не дает результата из-за кэширования на стороне сервера, мы можем рассмотреть вариант временного отключения проверки в коде. Найдите строку, указанную в ошибке (обычно это вызов метода ПроверитьВозможностьЗаписиВалюты), и закомментируйте её на время загрузки.
Либо воспользуйтесь расширением с методом &Вместо для отключения этой проверки:
&Вместо("ПроверитьВозможностьЗаписиВалюты")
Процедура ИмяПрефикс_ПроверитьВозможностьЗаписиВалюты(ВалютаОбъект)
// Просто ничего не делаем, пропуская блокировку
Возврат;
КонецПроцедуры
Важно: После завершения загрузки данных через XML обязательно удалите это расширение или верните код в исходное состояние, иначе в будущем вы рискуете получить некорректные данные в курсах валют при реальном фоновом обновлении.
Подводя итог, выясним алгоритм действий при возникновении данной ошибки:
ПриЗаписи.Такой системный подход позволит вам успешно завершить миграцию данных без остановки процесса из-за технических блокировок платформы.