При работе в программе 1С:Бухгалтерия 3.0 пользователи и программисты могут столкнуться с ситуацией, когда стандартный документ, например "Поступление наличных", отказывается проводиться. Система выдает сообщение: "Документ ... не может быть проведен. Не задана кратность валюты на дату ...". На первый взгляд, проблема кажется простой, но иногда ее решение требует более глубокого анализа. Разберем по шагам, как диагностировать и устранить эту ошибку, пройдя путь от простых проверок до анализа кода конфигурации.
Первый и самый главный вопрос, который возникает: где именно в программе хранится эта "кратность"? Ошибка может ввести в заблуждение, так как интуитивно хочется искать реквизит "Кратность" непосредственно в справочнике "Валюты". Однако это неверно. Все исторические данные о курсах и кратностях валют хранятся в специальном объекте — регистре сведений "Курсы валют".
Рассмотрим, что нужно проверить в первую очередь:
В большинстве случаев этих действий достаточно, чтобы решить проблему. Однако, если вы проверили регистр, убедились, что данные корректны, а ошибка все равно появляется, значит, причина кроется глубже.
Иногда, особенно если в базе много проблемных периодов, проще и быстрее установить курс и кратность программно. Это также помогает убедиться, что запись в регистр действительно создается. Рассмотрим пример простой обработки, которая устанавливает курс и кратность для рубля на определенную дату (для массовой правки движений также удобно использовать универсальный редактор регистров).
&НаКлиенте
Процедура УстКратность(Команда)
СервУстКратность();
Сообщить("Кратность валюты рубль установлена!");
КонецПроцедуры
&НаСервере
Процедура СервУстКратность()
// Создаем менеджер записи для регистра сведений "КурсыВалют"
РегистрКурсыВалют = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();
// Устанавливаем ключевые поля (измерения)
РегистрКурсыВалют.Период = Дата(2022, 01, 01); // Дата, на которую устанавливаем курс
РегистрКурсыВалют.Валюта = Справочники.Валюты.НайтиПоКоду("643"); // Находим рубль по коду
// Устанавливаем значения ресурсов
РегистрКурсыВалют.Курс = 1;
РегистрКурсыВалют.Кратность = 1;
// Записываем изменения в базу данных
РегистрКурсыВалют.Записать();
КонецПроцедуры
Важное замечание: этот код добавляет запись в РегистрыСведений.КурсыВалют. Он не меняет сам справочник Справочники.Валюты, так как у справочника нет реквизитов "Курс" и "Кратность". После выполнения такой обработки можно проверить наличие записи в регистре, например, с помощью "Консоли запросов", чтобы убедиться, что данные успешно сохранены.
Самая сложная ситуация — когда данные в регистре есть, дублей нет, а ошибка не исчезает. Это верный признак того, что нужно обратиться к отладчику и посмотреть, что происходит "под капотом" в момент проведения документа.
Проанализируем алгоритм поиска проблемы:
"Не задана кратность валюты".
// ... код в модуле проведения документа ...
СтруктураКурсаДокумента = РаботаСКурсамиВалют.ПолучитьКурсВалюты(Реквизиты.ВалютаДокумента, Реквизиты.Дата);
Если СтруктураКурсаДокумента.Кратность = 0 Тогда
Отказ = Истина;
ШаблонСообщения = НСтр("ru = 'Документ %1 не может быть проведен.
|Не задана кратность валюты %2 на дату %3'");
// ... дальнейшая обработка и вывод сообщения ...
КонецЕсли;
// ... код в общем модуле РаботаСКурсамиВалют ...
Функция ПолучитьКурсВалюты(Валюта, ДатаКурса) Экспорт
Результат = РегистрыСведений.КурсыВалют.ПолучитьПоследнее(ДатаКурса, Новый Структура("Валюта", Валюта));
Результат.Вставить("Валюта", Валюта);
Результат.Вставить("ДатаКурса", ДатаКурса);
Возврат Результат;
КонецФункции
Рассмотрим, что здесь происходит. Система вызывает функцию ПолучитьКурсВалюты, передавая в нее валюту и дату из документа. Внутри этой функции используется метод РегистрыСведений.КурсыВалют.ПолучитьПоследнее(). Этот метод ищет в регистре самую последнюю запись на указанную дату (ДатаКурса) или раньше нее. Если запись найдена, метод возвращает структуру с ее данными. Если не найдена — возвращается структура с нулевыми значениями для ресурсов, в том числе и для кратности.
Таким образом, условие СтруктураКурсаДокумента.Кратность = 0 становится истинным в двух случаях:
ПолучитьПоследнее не нашел ни одной записи для указанной валюты на дату документа или раньше.Ключ к решению проблемы находится в проверке входных параметров функции ПолучитьКурсВалюты. Поставьте точку останова на строке вызова этой функции и посмотрите в отладчике, какие именно значения содержатся в переменных Реквизиты.ВалютаДокумента и Реквизиты.Дата.
Наиболее вероятная причина — в Реквизиты.ВалютаДокумента находится ссылка на "неправильный" элемент справочника "Валюты" (тот самый дубль, у которого не заданы курсы). Система пытается найти курс для этой "пустой" валюты, ничего не находит, получает кратность равную нулю и прерывает проведение.
Таким образом, полный алгоритм решения проблемы выглядит так:
Следуя этим шагам, вы сможете не только быстро исправить ошибку "Не задана кратность валюты", но и глубже понять механизмы работы с валютами в 1С.