В процессе поддержки и обслуживания устаревших конфигураций на платформе 1С:Предприятие 7.7 разработчики регулярно сталкиваются с техническими вызовами при интеграции с внешними веб-сервисами. Одной из критически важных задач является регулярное обновление классификатора банков (БИК). С переходом финансовых учреждений и Федерального казначейства на новые стандарты расчетов старые форматы предоставления данных (например, DBF-файлы) ушли в прошлое. Единственным достоверным и полным источником актуальных данных стал сайт Центробанка РФ, предоставляющий информацию в формате XML.
Однако при попытке скачать этот классификатор стандартными средствами платформы 1С 7.7 разработчики сталкиваются с тем, что загружаемый ZIP-архив оказывается поврежденным («битым») и его невозможно распаковать. В этой статье мы подробно разберем, почему возникает эта ошибка, проанализируем механизмы передачи данных по протоколу HTTP и рассмотрим несколько надежных способов решения проблемы.
При использовании штатной внешней компоненты V7Plus.dll и объекта AddIn.V7HttpReader для скачивания файлов с сайта ЦБ РФ часто наблюдается следующая картина: файл скачивается не полностью, его размер на диске составляет от нескольких килобайт до половины от реального объема, а при попытке разархивировать выдается ошибка повреждения архива.
Проанализируем техническую сторону вопроса. Современный веб-сервер Центробанка отдает архив с классификатором БИК, используя механизм динамической порционной передачи данных — Chunked transfer encoding (потоковое шифрование/кодирование передачи). Компонента V7HttpReader — это устаревшая библиотека, которая не умеет корректно обрабатывать спецификацию протокола HTTP/1.1 в части работы с порционными данными. Она считывает только самый первый пришедший кусок (chunk) данных, закрывает соединение и записывает этот обрубок на диск, сообщая об успешном завершении операции.
Кроме того, старая компонента v7plus.dll не поддерживает современные протоколы безопасности TLS 1.2 и TLS 1.3, которые сейчас повсеместно внедряются на государственных порталах. Поэтому использовать ее для загрузки данных из внешних источников в современных реалиях категорически не рекомендуется. В качестве альтернативы можно использовать внешнюю компоненту для выполнения HTTP- и HTTPS-запросов в 1С 7.7.
Ниже мы подробно рассмотрим три альтернативных и надежных способа обхода этого ограничения.
Для реализации полноценной поддержки протокола HTTP/1.1 и работы с двоичными данными в 1С 7.7 мы можем использовать системные COM-объекты операционной системы Windows: WinHttp.WinHttpRequest.5.1 для отправки запроса и получения ответа, а также ADODB.Stream для сохранения полученного бинарного потока в файл.
Однако здесь возникает другая проблема платформы 1С 7.7: она не умеет напрямую работать с массивами байтов (тип данных VT_UI1 | VT_ARRAY), которые возвращает свойство responseBody объекта запроса. При попытке передать эти данные напрямую платформа выдаст ошибку несовместимости типов.
Чтобы обойти это ограничение, мы применим классический прием: задействуем объект MSScriptControl.ScriptControl для выполнения кода на языке VBScript. Этот скрипт выполнит запись бинарного массива из ответа запроса в поток напрямую на уровне операционной системы, минуя интерпретатор 1С.
Разберем готовый код этого решения по шагам:
// Определяем адрес загрузки и путь сохранения файла
URL = "https://www.cbr.ru/Queries/XsltBlock/File/101478?fileId=0";
Каталог = КаталогИБ();
ИмяФайла = Каталог + "bik.zip";
// Инициализируем объект WinHttpRequest для выполнения запроса
WinHttpRequest = СоздатьОбъект("WinHttp.WinHttpRequest.5.1");
WinHttpRequest.Open("GET", URL, 0); // 0 - синхронный режим работы
WinHttpRequest.Send();
// Создаем объект выполнения скриптов для работы с бинарными данными
Скрипт = СоздатьОбъект("MSScriptControl.ScriptControl");
Скрипт.Language = "vbscript";
// Создаем ADO-поток для записи файла на диск
stream = СоздатьОбъект("ADODB.Stream");
stream.Mode = 3; // Чтение и запись
stream.Type = 1; // Бинарный режим работы
stream.Open();
// Передаем объекты внутрь VBScript-контекста
Скрипт.AddObject("stream", stream);
Скрипт.AddObject("WinHttpRequest", WinHttpRequest);
// Выполняем запись массива байтов напрямую в поток
Скрипт.Eval("stream.Write(WinHttpRequest.responseBody)");
// Сохраняем поток в файл на диске с перезаписью существующего
stream.SaveToFile(ИмяФайла, 2);
stream.Close();
Сообщить("Файл классификатора успешно скачан!");
Важное ограничение метода: Компонент MSScriptControl (библиотека msscript.ocx) является строго 32-разрядным. Хотя сама 1С 7.7 работает в 32-битном режиме, в современных 64-битных операционных системах Windows (Windows 10, Windows 11, Windows Server 2019/2022) этот компонент по умолчанию может быть отключен политиками безопасности или не зарегистрирован в системе. Если при выполнении кода вы получаете ошибку «Класс не зарегистрирован», используйте следующее решение.
Начиная с Windows 10 (сборка 17063) и во всех современных серверных ОС Windows, в систему по умолчанию встроена мощная консольная утилита curl. Она идеально подходит для скачивания любых файлов из интернета, так как на уровне ОС поддерживает все современные стандарты шифрования (TLS 1.2/1.3), сжатия данных и потоковой передачи (включая Chunked transfer encoding).
Использование curl позволяет полностью переложить задачу загрузки бинарного файла на операционную систему. Платформе 1С 7.7 остается лишь запустить процесс скачивания и дождаться его завершения. Это самый надежный способ, который гарантированно работает на современных компьютерах и серверах без регистрации устаревших ActiveX-компонент.
Рассмотрим пример реализации запуска утилиты из кода 1С:
Каталог = КаталогИБ();
ПутьКФайлу = Каталог + "bik.zip";
УрлИсточника = "https://www.cbr.ru/Queries/XsltBlock/File/101478?fileId=0";
// Инициализируем командный процессор Windows
WshShell = СоздатьОбъект("Wscript.Shell");
// Формируем командную строку для утилиты curl
// Параметр -o указывает путь сохранения файла
// Параметры запуска: 0 - скрыть окно консоли, 1 - ожидать завершения работы
Команда = "curl -L -k -o """ + ПутьКФайлу + """ """ + УрлИсточника + """";
Попытка
КодВозврата = WshShell.Run(Команда, 0, 1);
Если КодВозврата = 0 Тогда
Сообщить("Архив БИК успешно скачан с помощью curl.");
Иначе
Сообщить("Ошибка при скачивании файла. Код ошибки: " + КодВозврата);
КонецЕсли;
Исключение
Сообщить("Не удалось запустить утилиту curl. Проверьте настройки системы.");
КонецПопытки;
В данном коде параметр ключа -L указывает утилите автоматически переходить по редиректам (перенаправлениям), если сервер ЦБ временно изменит адрес отдачи файла, а ключ -k позволяет игнорировать возможные локальные проблемы с цепочкой доверенных SSL-сертификатов на стороне клиента.
Если вы хотите избежать стадии скачивания ZIP-архива, его ручной распаковки программными методами (что в 1С 7.7 также требует привлечения внешних библиотек архивации) и последующего чтения файла, можно воспользоваться альтернативным API Центробанка, которое отдает классификатор напрямую в открытом XML-виде. Для этого используется адрес https://www.cbr.ru/scripts/XML_bic.asp.
Объект работы с XML-документами Msxml2.DOMDocument умеет самостоятельно отправлять сетевые HTTP-запросы и разбирать полученный от сервера XML-текст прямо в оперативной памяти компьютера без промежуточного сохранения файлов на диск.
Проанализируем пример такого решения:
// Создаем объект для работы с XML-документом
XMLДок = СоздатьОбъект("Msxml2.DOMDocument");
XMLДок.async = 0; // Отключаем асинхронный режим, ждем загрузки
XMLДок.resolveExternals = 0;
УрлXML = "https://www.cbr.ru/scripts/XML_bic.asp";
Если XMLДок.load(УрлXML) = 1 Тогда
Сообщить("XML-данные успешно получены напрямую из сети!");
// Получаем список всех узлов банков в документе
СписокБанков = XMLДок.selectNodes("//Record");
КоличествоБанков = СписокБанков.length;
Сообщить("Найдено записей банков: " + КоличествоБанков);
// Пример обхода дерева элементов
Для Номер = 0 По КоличествоБанков - 1 Цикл
УзелБанка = СписокБанков.item(Номер);
БИК = УзелБанка.getAttribute("BIC");
Название = УзелБанка.selectSingleNode("Name").text;
// Здесь мы можем выполнять запись в справочник "Банки"
// Сообщить("БИК: " + БИК + " - " + Название);
КонецЦикла;
Иначе
Сообщить("Не удалось загрузить XML-данные с сервера ЦБ.");
КонецЕсли;
Этот способ является наиболее элегантным и лаконичным, так как исключает необходимость работать со сторонними утилитами, временными файлами и распаковкой ZIP-архивов. Однако учитывайте, что объем передаваемого несжатого XML-трафика может быть несколько выше, чем при скачивании сжатого архива. Для разбора полученных структур данных также подойдёт обработка для чтения XML-файлов в 1С 7.7.
При решении технических задач в 1С 7.7, связанных с взаимодействием с современными веб-ресурсами, крайне важно вовремя отказываться от устаревших компонент (таких как V7Plus). Резюмируем основные выводы:
curl избавляет от проблем несовместимости типов в 1С и гарантирует прохождение современных протоколов шифрования (TLS).Msxml2.DOMDocument, чтобы избежать рутинных операций по разархивированию ZIP-архива.