При организации регулярного обмена данными между устаревшими конфигурациями на платформе 1С:Предприятие 7.7 и современными базами 1С:Предприятие 8 (например, ЗУП 3.1 или Бухгалтерия 3.0) разработчики часто сталкиваются с человеческим фактором. Правила обмена, созданные в конфигурации «Конвертация данных 2.1» (КД2), представляют собой отдельный XML-файл. Этот файл регулярно теряется пользователями или системными администраторами при очистке каталогов, обновлении серверов или переносе баз данных. В итоге разработчику приходится раз за разом высылать файл заново.
В платформе 1С 8.3 эту проблему решить легко — достаточно загрузить файл правил в двоичный макет или макет текстового документа прямо внутри внешней обработки (.epf). Но в платформе 1С 7.7 встроенных объектов для хранения двоичных данных или произвольных текстовых файлов внутри обработки (.ert) нет. В этой статье мы подробно разберем, как решить эту проблему, упаковав XML-файл правил обмена внутрь табличного макета (MXL) или модуля обработки 1С 7.7 без потери кодировки и структуры данных.
Прежде чем перейти к реализации, проанализируем ключевое препятствие. Правила обмена КД2 выгружаются в кодировке UTF-8. Платформа 1С 7.7 работает исключительно с кодировкой Windows-1251 (ANSI). Если мы попытаемся прочитать XML-файл стандартными средствами платформы (например, объектом Текст) и просто скопировать его строки в ячейки таблицы, то столкнемся с критическими ошибками:
v7plus.dll) не смогут прочитать файл из-за нарушения кодировки и отсутствия валидного заголовка UTF-8.Для решения этой проблемы мы задействуем внешний интерфейс работы с потоками данных — Windows-компонент ADODB.Stream, который присутствует на любом компьютере с ОС Windows и позволяет корректно транслировать UTF-8 в строки 1С и обратно.
Рассмотрим подробнее три надежных метода упаковки правил обмена.
---
Этот метод является наиболее удобным. Каждая строка XML-файла записывается в отдельную строку первой колонки табличного документа макета. При запуске обмена обработка считывает строки из таблицы и воссоздает XML-файл во временном каталоге операционной системы.
Для начала создадим служебную процедуру, которая однократно прочитает наш исходный файл правил ПравилаОбмена.xml и заполнит ячейки объекта Таблица. Этот код выполняется на стороне разработчика:
Процедура ИмпортироватьПравилаВТаблицу()
Табл = СоздатьОбъект("Таблица");
Стрим = СоздатьОбъект("ADODB.Stream");
// Настраиваем поток для чтения исходного XML в UTF-8
Стрим.Type = 2; // Указываем, что работаем с текстовыми данными
Стрим.Charset = "windows-1251"; // Инициализируем базовую кодировку
Стрим.Open();
Стрим.LoadFromFile("C:\Rules\ПравилаОбмена.xml"); // Путь к вашему исходному файлу
Стрим.Charset = "utf-8"; // Переключаем поток на декодирование UTF-8
НомерСтроки = 0;
Пока Стрим.EOS = 0 Цикл
НомерСтроки = НомерСтроки + 1;
// Читаем построчно (-2 соответствует константе adReadLine)
СтрокаТекста = Стрим.ReadText(-2);
Табл.Область(НомерСтроки, 1).Текст = СтрокаТекста;
КонецЦикла;
Стрим.Close();
// Сохраняем полученную таблицу в файл MXL
Табл.Записать("C:\Rules\МакетПравил.mxl", "MXL");
Предупреждение("Импорт завершен! Создан файл макета МакетПравил.mxl");
КонецПроцедуры
Полученный файл МакетПравил.mxl необходимо открыть в конфигураторе 1С 7.7 и вставить в качестве нового макета в вашу внешнюю обработку выгрузки (назовем макет, например, ПравилаОбмена).
Теперь в самой обработке выгрузки напишем алгоритм, который при старте или по нажатию кнопки обмена будет «собирать» XML-файл обратно во временную папку:
Функция ВосстановитьПравилаИзМакета()
// Получаем доступ к встроенному макету таблицы
Табл = СоздатьОбъект("Таблица");
Табл.ИсходнаяТаблица("ПравилаОбмена"); // Имя нашего макета в обработке
// Инициализируем поток записи в кодировке UTF-8
СтримВыход = СоздатьОбъект("ADODB.Stream");
СтримВыход.Type = 2; // Текстовый режим
СтримВыход.Charset = "utf-8";
СтримВыход.LineSeparator = -1; // Стандартный перевод строки (CRLF)
СтримВыход.Open();
КоличествоСтрок = Табл.ВысотаТаблицы();
Если КоличествоСтрок = 0 Тогда
Сообщить("Ошибка: Макет правил обмена пуст!", "!");
Возврат "";
КонецЕсли;
// Переносим строки из ячеек макета обратно в поток UTF-8
Для НомерСтроки = 1 По КоличествоСтрок Цикл
ТекущийТекст = Табл.Область(НомерСтроки, 1).Текст;
СтримВыход.WriteText(ТекущийТекст);
КонецЦикла;
// Формируем путь во временном каталоге пользователя
ПутьКФайлуПравил = КаталогВременныхФайлов() + "v7_to_v8_rules.xml";
// Сохраняем файл на диск (параметр 2 означает перезапись существующего файла)
СтримВыход.SaveToFile(ПутьКФайлуПравил, 2);
СтримВыход.Close();
Возврат ПутьКФайлуПравил;
КонецФункции
При вызове этой функции мы получаем готовый путь к физическому файлу rules.xml на диске. Этот путь мы передаем стандартной обработке выгрузки (например, встроенному механизму работы с КД2): ПутьКФайлуПравил. После успешного завершения обмена этот временный файл можно безопасно удалить средствами операционной системы.
---
Если вы не хотите связываться с макетами табличных документов (MXL), существует еще один изящный способ — закодировать весь файл XML в строку формата Base64. В таком формате бинарные данные превращаются в простой набор латинских символов и цифр, который гарантированно не исказится компилятором 1С 7.7. Эту строку можно хранить непосредственно в модуле обработки в виде строковой переменной.
Для кодирования и декодирования Base64 в среде Windows без внешних компонент идеально подходит объект MSXML2.DOMDocument. Разберем этот процесс по шагам.
Выполните этот скрипт (например, в пустой базе или обработке) для генерации кода:
Функция ФайлВBase64(ПутьКФайлу)
// Читаем бинарный файл через ADODB
Стрим = СоздатьОбъект("ADODB.Stream");
Стрим.Type = 1; // Бинарный режим
Стрим.Open();
Стрим.LoadFromFile(ПутьКФайлу);
ДвоичныеДанные = Стрим.Read();
Стрим.Close();
// Используем DOMDocument для конвертации в Base64
Док = СоздатьОбъект("MSXML2.DOMDocument");
Элемент = Док.createElement("Base64Data");
Элемент.dataType = "bin.base64";
Элемент.nodeTypedValue = ДвоичныеДанные;
Возврат Элемент.text; // Возвращает готовую Base64-строку
КонецФункции
Полученную строку (она будет длинной, поэтому ее можно разбить на несколько подстрок для удобства хранения) вы объявляете в модуле вашей рабочей обработки:
Перем СтрокаПравилBase64;
Процедура ИнициализироватьСтрокуПравил()
// Разбиваем длинную строку на части, чтобы избежать ограничений длины строки в 1С 7.7
СтрокаПравилBase64 = "M3R4d...[здесь ваша закодированная строка часть 1]...";
СтрокаПравилBase64 = СтрокаПравилBase64 + "...[часть 2]...";
КонецПроцедуры
При запуске процедуры выгрузки выполняем обратное декодирование:
Функция ВосстановитьПравилаИзBase64()
ИнициализироватьСтрокуПравил();
Док = СоздатьОбъект("MSXML2.DOMDocument");
Элемент = Док.createElement("Base64Data");
Элемент.dataType = "bin.base64";
Элемент.text = СтрокаПравилBase64;
// Извлекаем бинарный массив байтов
ДвоичныеДанные = Элемент.nodeTypedValue;
// Записываем байты обратно в файл через ADODB.Stream
Стрим = СоздатьОбъект("ADODB.Stream");
Стрим.Type = 1; // Бинарный режим
Стрим.Open();
Стрим.Write(ДвоичныеДанные);
ПутьКФайлу = КаталогВременныхФайлов() + "rules_decoded.xml";
Стрим.SaveToFile(ПутьКФайлу, 2);
Стрим.Close();
Возврат ПутьКФайлу;
КонецФункции
Этот метод полностью автономен, не требует создания макетов таблиц и защищен от любых сбоев кодировок при обновлении конфигурации.
---
Если обработка обмена встроена непосредственно в саму конфигурацию 1С 7.7 (в метаданные конфигурации, а не запускается как внешняя .ert), наиболее правильным архитектурным решением будет хранить XML-код правил внутри базы данных. Это позволит обновлять правила обмена без изменения конфигурации и предотвратит их удаление пользователями.
Проанализируем шаги настройки этого механизма:
НастройкиОбмена) с реквизитом типа "Строка" неограниченной длины. Для хранения больших текстов в DBF-версии платформы будет автоматически использоваться файл .dbt, а в SQL-версии — тип поля IMAGE или TEXT.ADODB.Stream в кодировке UTF-8 и записывается в созданный реквизит справочника или константу.Этот подход обеспечивает максимальную гибкость: если правила изменятся, вам не придется пересохранять обработку или открывать конфигуратор — достаточно будет обновить элемент справочника прямо в пользовательском режиме.
Мы рассмотрели три надежных способа борьбы с человеческим фактором при потере внешних файлов правил обмена в 1С 7.7. Использование связки MXL + ADODB.Stream или технологии Base64 позволяет создавать полностью автономные внешние обработки обмена, которые работают по принципу «одного файла» и избавляют программиста от необходимости постоянной поддержки пользователей.