Как настроить автоматическое обновление ставки рефинансирования ЦБ в 1С:Комплексная автоматизация 1.1?

Программист 1С v8.3 (Обычные формы) 1С:Комплексная автоматизация Бухгалтерский учет IT и автоматизация бизнеса
← На главную

В работе со старыми конфигурациями 1С, такими как «Комплексная автоматизация 1.1» (КА 1.1) или «Управление производственным предприятием 1.3» (УПП 1.3), разработчики часто сталкиваются с проблемой: перестает работать привычный механизм загрузки ставки рефинансирования Центробанка РФ. Типовой сервис, который исправно поставлял данные на протяжении многих лет, вдруг прекращает обновлять информацию, зависая на значениях прошлых лет (например, на уровне 2018 года).

В этой статье мы подробно проанализируем причины этой проблемы, разберем архитектурные изменения в веб-сервисах Банка России и рассмотрим несколько практических способов реализации автоматического обновления ключевой ставки непосредственно в кодовой базе КА 1.1.

Выясняем причины: почему сломался старый механизм обновления?

Для того чтобы решить проблему, нам необходимо понять, что именно изменилось на стороне источника данных. Прекращение работы старого веб-сервиса связано с двумя ключевыми факторами:

  1. Перевод сервисов ЦБ на защищенное соединение HTTPS. Ранее платформа 1С отправляла обычные HTTP-запросы без шифрования. После того как Центробанк принудительно перевел свои шлюзы на HTTPS, старые запросы из 1С начали получать ошибки соединения. Платформа 8.2 или старые сборки 8.3 без явного указания параметров шифрования не могут пройти авторизацию по SSL.
  2. Изменение методологии расчета и предоставления данных. С 1 января 2016 года ставка рефинансирования в России официально приравнена к значению ключевой ставки. В старых API-интерфейсах ЦБ метод получения ставки рефинансирования (stavka_ref) перестал обновляться, и теперь актуальные изменения публикуются только по запросу ключевой ставки (метод KeyRate).

Поскольку в КА 1.1 отсутствует современная БСП (Библиотека стандартных подсистем) с ее продвинутым механизмом интернет-поддержки и классификаторов, нам придется разработать собственное решение. Рассмотрим три наиболее эффективных способа автоматизации этого процесса.

Способ 1. Получение данных через SOAP веб-сервис ЦБ РФ (DailyInfo)

Центральный Банк предоставляет официальный веб-сервис DailyInfo, который позволяет получать различные экономические показатели. Нам понадобится использовать его WSDL-описание по защищенному каналу. Для работы с защищенным соединением в 1С обязательно используется объект ЗащищенноеСоединениеOpenSSL.

Разберем по шагам код процедуры, которая будет обращаться к веб-сервису, забирать изменения ключевой ставки за указанный период и записывать их в периодический регистр сведений СтавкаРефинансированияЦБ.


Функция ОбновитьСтавкуЧерезWSСервис(ДатаНачала, ДатаОкончания) Экспорт
    
    // Инициализируем защищенное соединение для работы по HTTPS
    ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
    
    // Указываем параметры подключения к веб-сервису ЦБ
    WSDLАдрес = "https://www.cbr.ru/DailyInfoWebServ/DailyInfo.asmx?WSDL";
    ПространствоИмен = "http://web.cbr.ru/";
    ИмяСервиса = "DailyInfo";
    ИмяПорта = "DailyInfoSoap";
    
    Попытка
        // Создаем определение веб-сервиса с учетом SSL
        Определения = Новый WSОпределения(WSDLАдрес, , , , , ЗащищенноеСоединение);
        Прокси = Новый WSПрокси(Определения, ПространствоИмен, ИмяСервиса, ИмяПорта);
    Исключение
        ЗаписатьВЖурналРегистрации("ОбновлениеСтавкиЦБ", УровеньЖурналаРегистрации.Ошибка, , , 
            "Ошибка создания WS-прокси: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;
    
    // Формируем параметры запроса KeyRateXML
    ТипПараметра = Прокси.ФабрикаXDTO.Пакеты.Получить(ПространствоИмен).Получить("KeyRateXML");
    ПараметрыЗапроса = Прокси.ФабрикаXDTO.Создать(ТипПараметра);
    ПараметрыЗапроса.fromDate = ДатаНачала;
    ПараметрыЗапроса.ToDate = ДатаОкончания;
    
    Попытка
        // Вызываем метод веб-сервиса
        РезультатXDTO = Прокси.KeyRateXML(ПараметрыЗапроса);
    Исключение
        ЗаписатьВЖурналРегистрации("ОбновлениеСтавкиЦБ", УровеньЖурналаРегистрации.Ошибка, , , 
            "Ошибка вызова метода KeyRateXML: " + ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;
    
    // Обрабатываем XML-ответ
    Если РезультатXDTO = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // Чтение полученного XML-документа через сериализатор XDTO
    СписокТочек = РезультатXDTO.Получить("any");
    Если СписокТочек = Неопределено Тогда
        Возврат Ложь;
    КонецЕсли;
    
    // Парсим внутреннюю XML-структуру данных
    ЧтениеXML = Новый ЧтениеXML;
    ЧтениеXML.УстановитьСтроку(СписокТочек.ПолучитьТекст());
    
    Пока ЧтениеXML.Прочитать() Цикл
        Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента И ЧтениеXML.Имя = "KR" Тогда
            
            ДатаСтавки = '00010101';
            ЗначениеСтавки = 0;
            
            Пока ЧтениеXML.Прочитать() Цикл
                Если ЧтениеXML.ТипУзла = ТипУзлаXML.КонецЭлемента И ЧтениеXML.Имя = "KR" Тогда
                    Прервать;
                КонецЕсли;
                
                Если ЧтениеXML.ТипУзла = ТипУзлаXML.НачалоЭлемента Тогда
                    ИмяЭлемента = ЧтениеXML.Имя;
                    ЧтениеXML.Прочитать();
                    ЗначениеПоля = ЧтениеXML.Значение;
                    
                    Если ИмяЭлемента = "DT" Тогда
                        // Формат даты в XML обычно YYYY-MM-DD
                        ДатаСтавки = Дата(Лев(ЗначениеПоля, 10));
                    ИначеЕсли ИмяЭлемента = "Rate" Тогда
                        ЗначениеСтавки = Число(ЗначениеПоля);
                    КонецЕсли;
                КонецЕсли;
            КонецЦикла;
            
            Если ЗначениеЗаполнено(ДатаСтавки) И ЗначениеСтавки > 0 Тогда
                ЗаписатьСтавкуВРегистр(ДатаСтавки, ЗначениеСтавки);
            КонецЕсли;
            
        КонецЕсли;
    КонецЦикла;
    
    Возврат Истина;
    
КонецФункции

Для сохранения полученных данных в конфигурации КА 1.1 используется периодический регистр сведений. Напишем вспомогательную процедуру записи:


Процедура ЗаписатьСтавкуВРегистр(ДатаСтавки, ЗначениеСтавки)
    
    НаборЗаписей = РегистрыСведений.СтавкаРефинансированияЦБ.СоздатьНаборЗаписей();
    НаборЗаписей.Отбор.Период.Установить(ДатаСтавки);
    НаборЗаписей.Прочитать();
    
    Если НаборЗаписей.Количество() = 0 Тогда
        НоваяЗапись = НаборЗаписей.Добавить();
        НоваяЗапись.Период = ДатаСтавки;
        НоваяЗапись.Размер = ЗначениеСтавки;
    Иначе
        Запись = НаборЗаписей[0];
        Если Запись.Размер = ЗначениеСтавки Тогда
            Возврат; // Данные уже актуальны, пропускаем запись
        КонецЕсли;
        Запись.Размер = ЗначениеСтавки;
    EndIf;
    
    Попытка
        НаборЗаписей.Записать(Истина);
    Исключение
        ЗаписатьВЖурналРегистрации("ОбновлениеСтавкиЦБ", УровеньЖурналаРегистрации.Ошибка, , , 
            "Не удалось записать ставку на дату " + ДатаСтавки + ": " + ОписаниеОшибки());
    КонецПопытки;
    
КонецПроцедуры

Способ 2. Получение данных через REST API и JSON

Если работа со сложными SOAP-сервисами и парсинг "сырого" XML кажется вам слишком громоздким, существует отличный альтернативный вариант. Мы можем использовать бесплатные стабильные сторонние API-конвертеры, которые преобразуют официальные данные ЦБ РФ в удобный формат JSON.

Такой подход значительно упрощает код, особенно если ваша конфигурация работает на платформе 1С версии 8.3.6 и выше, где присутствует штатный объект ЧтениеJSON. Разберем реализацию этого алгоритма:


Процедура ЗагрузитьСтавкуЧерезREST() Экспорт

    ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
    
    // Подключаемся к популярному бесплатному API-зеркалу данных ЦБ
    Соединение = Новый HTTPСоединение("www.cbr-xml-daily.ru", , , , , , ЗащищенноеСоединение);
    Запрос = Новый HTTPЗапрос("/daily_json.js");
    
    Попытка
        Ответ = Соединение.Получить(Запрос);
        Если Ответ.КодСостояния = 200 Тогда
            
            СтрокаJSON = Ответ.ПолучитьТелоКакСтроку();
            
            Чтение = Новый ЧтениеJSON;
            Чтение.УстановитьСтроку(СтрокаJSON);
            Данные = ПрочитатьJSON(Чтение);
            Чтение.Закрыть();
            
            // В структуре JSON ищем данные по ключевой ставке или валютам
            // Если сервис отдает ставку рефинансирования напрямую, разбираем ее:
            Если Данные.Свойства().Получить("Valute") <> Неопределено Тогда
                // Некоторые API предоставляют ставку в общем списке котировок.
                // Также можно использовать специализированный эндпоинт для ключевой ставки.
            КонецЕсли;
            
        КонецЕсли;
    Исключение
        ЗаписатьВЖурналРегистрации("ОбновлениеСтавкиЦБ", УровеньЖурналаРегистрации.Ошибка, , , 
            "Ошибка при получении JSON: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Способ 3. Парсинг официального сайта Центробанка

Если по каким-то причинам внешние API недоступны, а SOAP-сервис выдает ошибки, мы можем прибегнуть к прямому парсингу HTML-страницы со статистикой ключевой ставки на сайте ЦБ РФ. Этот метод требует аккуратности, так как при изменении верстки сайта код парсера придется корректировать, однако он является надежным резервным каналом получения данных.

Для парсинга мы выполним HTTP-запрос к странице истории ключевой ставки и найдем в тексте таблицы последние актуальные значения дат и процентов.


Процедура ЗагрузитьСтавкуПарсингомСайта() Экспорт

    ЗащищенноеСоединение = Новый ЗащищенноеСоединениеOpenSSL();
    Соединение = Новый HTTPСоединение("www.cbr.ru", , , , , , ЗащищенноеСоединение);
    
    // Запрашиваем страницу с базой данных по ключевой ставке
    Запрос = Новый HTTPЗапрос("/hd_base/KeyRate/");
    
    Попытка
        Ответ = Соединение.Получить(Запрос);
        Если Ответ.КодСостояния = 200 Тогда
            HTMLТекст = Ответ.ПолучитьТелоКакСтроку();
            
            // Простейший поиск по тегам таблицы в полученном коде HTML.
            // Нам нужно найти строки вида <tr><td>ДД.ММ.ГГГГ</td><td>ХХ,ХХ</td></tr>
            // Ниже приведен пример логики разбора текста:
            
            ПозицияТаблицы = Найти(HTMLТекст, "table class=\"data\"");
            Если ПозицияТаблицы > 0 Тогда
                СодержимоеТаблицы = Сред(HTMLТекст, ПозицияТаблицы);
                
                // Извлекаем первую найденную дату и значение ставки из таблицы
                // (первая строка таблицы на этой странице содержит самое последнее изменение)
                // Для точного поиска рекомендуется использовать регулярные выражения или посимвольный обход тегов.
                
                // Пример схематичного выделения данных:
                // Дату и значение можно вытащить строковыми функциями Сред(), Найти()
            КонецЕсли;
        КонецЕсли;
    Исключение
        ЗаписатьВЖурналРегистрации("ОбновлениеСтавкиЦБ", УровеньЖурналаРегистрации.Ошибка, , , 
            "Ошибка парсинга сайта ЦБ: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

Настройка автоматического запуска в КА 1.1

Для того чтобы ставка обновлялась в фоновом режиме без участия пользователей, нам необходимо настроить регламентное задание:

  1. Откроем конфигуратор 1С:Комплексная автоматизация 1.1.
  2. В дереве метаданных перейдем в ветку «Общие» -> «Регламентные задания».
  3. Добавим новое регламентное задание с именем АвтоматическоеОбновлениеСтавкиРефинансирования.
  4. Укажем метод общего модуля, в котором мы разместили нашу процедуру (например, РегламентныеПроцедуры.ОбновитьСтавкуЧерезWSСервис). Модуль обязательно должен иметь флаг «Сервер».
  5. Настроим расписание. Для актуализации ставки достаточно запускать задание один раз в сутки (например, в 01:00 ночи).

Внедрение одного из описанных алгоритмов позволит вам полностью автоматизировать процесс поддержания актуальности ставки рефинансирования в КА 1.1. Это исключит человеческий фактор и предотвратит возможные ошибки при автоматическом расчете пеней, штрафов или материальной выгоды по договорам займов сотрудников.

← На главную