В современных версиях 1С:ERP (начиная с 2.5.7 и выше) архитектура учета валютных курсов претерпела значительные изменения. Появился новый регистр сведений ОтносительныеКурсыВалют, который стал играть ключевую роль в расчетах. Однако пользователи и программисты часто сталкиваются с проблемой: при закрытии месяца переоценка валютных остатков отрабатывает некорректно или по «непонятному» курсу. В этой статье мы подробно разберем, как данные попадают в этот регистр, почему там могут появляться лишние записи и как это исправить.
Разберем, зачем разработчики ввели этот объект. В старых версиях системы существовал только регистр КурсыВалют, где курс всегда жестко привязывался к валюте регламентированного учета. Регистр ОтносительныеКурсыВалют более универсален. Он позволяет хранить котировки между любыми парами валют (базовая и котируемая), что необходимо для:
Проблема заключается в том, что механизмы переоценки в модулях закрытия месяца (например, при проверке необходимости переоценки) соединяются с этим регистром только по полю Валюта, не всегда учитывая измерение БазоваяВалюта. Если в регистре для одной валюты (например, USD) есть запись к RUB и запись к BYN, система может выбрать неверную строку, что приведет к ошибкам в расчетах.
Выясним, каким образом данные попадают в ОтносительныеКурсыВалют. Основной способ — автоматическая синхронизация при записи данных в стандартный регистр КурсыВалют. Проанализируем работу подписки на событие, которая управляет этим процессом.
В конфигурации существует подписка на событие ПриЗаписиКурсовВалют, которая вызывает процедуру в общем модуле. Рассмотрим код обработчика:
// См. подписку на событие "ПриЗаписиКурсовВалют"
Процедура ПриЗаписиКурсовВалютПриЗаписи(Источник, Отказ, Замещение) Экспорт
Если Источник.ДополнительныеСвойства.Свойство("ЗаписьПриОбновленииИнформационнойБазы") Тогда
Возврат;
КонецЕсли;
Если Источник.ДополнительныеСвойства.Свойство("SincronizaciaKursovValut") Тогда
Возврат;
КонецЕсли;
РаботаСКурсамиВалютУТ.СинхронизоватьКурсыВалют(Источник);
КонецПроцедуры
Процедура СинхронизоватьКурсыВалют выполняет двусторонний обмен данными. Если вы вносите изменения в КурсыВалют, система автоматически обновляет ОтносительныеКурсыВалют, и наоборот. Посмотрим, как определяется базовая валюта при синхронизации:
Процедура СинхронизоватьКурсыВалют(Источник) Экспорт
БазоваяВалюта = Константы.ВалютаРегламентированногоУчета.Получить();
Если Не ЗначениеЗаполнено(БазоваяВалюта) Тогда
Возврат;
КонецЕсли;
Если ТипЗнч(Источник) = Тип("РегистрСведенийНаборЗаписей.КурсыВалют") Тогда
Приемник = РегистрыСведений.ОтносительныеКурсыВалют.СоздатьНаборЗаписей();
ИмяРегистра = Метаданные.РегистрыСведений.ОтносительныеКурсыВалют.Имя;
Иначе
// Если запись идет напрямую в ОтносительныеКурсыВалют, проверяем базу
Если Источник.Отбор.БазоваяВалюта.Значение <> БазоваяВалюта Тогда
Возврат;
КонецЕсли;
Приемник = РегистрыСведений.КурсыВалют.СоздатьНаборЗаписей();
БазоваяВалюта = Неопределено;
ИмяРегистра = Метаданные.РегистрыСведений.КурсыВалют.Имя;
КонецЕсли;
// Далее происходит вызов обновления записей...
КонецПроцедуры
Из кода видно, что система старается поддерживать соответствие между «основным» курсом и относительным курсом к валюте регл. учета. Однако это не объясняет появление записей с базовой валютой «Белорусский рубль» или «Доллар США» для других валют.
Проанализируем ситуации, при которых в измерении БазоваяВалюта оказывается значение, отличное от валюты регламентированного учета:
ОтносительныеКурсыВалют именно в этой паре (EUR к BYN).Рассмотрим, как наличие таких записей ломает процедуру закрытия месяца. В алгоритмах переоценки 1С:ERP (модули РасчетКурсовыхРазницЛокализация) система ищет актуальный курс для валюты остатка. Если запрос к регистру ОтносительныеКурсыВалют не содержит жесткого фильтра по БазоваяВалюта = ВалютаРегламентированногоУчета, то при наличии двух строк для одной валюты (например, USD/RUB и USD/BYN) СУБД вернет одну из них случайным образом (обычно по порядку индекса). Если вернется курс к BYN, переоценка будет выполнена по ошибочному коэффициенту, либо система вовсе решит, что курс не изменился. Для устранения расхождений и некорректного расчета при закрытии месяца можно использовать обработку для исправления ошибок расчета курсовых разниц.
Если вы обнаружили, что переоценка валюты ведет себя странно, выполним следующие шаги:
ОтносительныеКурсыВалют через «Все функции» (или «Функции для технического специалиста»). Установите отбор по проблемной валюте. Проверьте, есть ли там записи, где БазоваяВалюта не совпадает с вашей валютой регл. учета (обычно рубль).Валюты. Откройте карточку валюты, по которой найдены «лишние» записи. Проверьте способ установки курса. Если стоит «Наценка на курс другой валюты» или «Расчет по формуле», убедитесь, что это действительно необходимо. Часто пользователи по ошибке выбирают одну иностранную валюту базовой для другой.Валюты, а затем очистить записи в регистре.ПриЗаписиКурсовВалютПриЗаписи. Это позволит по стеку вызовов понять, какой именно процесс (регламентное задание, обработка загрузки или ручной ввод) инициирует создание некорректной записи.Важный момент: В последних патчах к релизу 2.5.10 разработчики начали исправлять запросы в модулях переоценки, добавляя более строгую фильтрацию по базовой валюте. Проверьте наличие установленных исправлений (патчей) для вашей версии конфигурации через монитор интернет-поддержки.
Таким образом, мы проанализировали механизм работы нового регистра и выяснили, что его «многогранность» (возможность хранения разных базовых валют) требует особой внимательности при настройке справочника валют. Совместная работа программной синхронизации и механизмов закрытия месяца требует, чтобы в регистре находились только актуальные и корректно настроенные пары валютных курсов.