Перенос данных между «семеркой» и «восьмеркой» через COM-соединение — задача классическая, но полная подводных камней. Часто программисты сталкиваются с тем, что привычные методы передачи объектов не работают, а серверная версия 1С 8.3 наотрез отказывается видеть 32-битную библиотеку 7.7. В этой статье мы подробно разберем, как получить данные из таблицы значений 7.7, почему нельзя использовать внутренние строки и как настроить сервер 1С для стабильной работы.
Рассмотрим ситуацию: вы создали функцию в глобальном модуле 1С 7.7, которая формирует таблицу значений (ТЗ) с результатами запроса. На стороне 1С 8.3 вы вызываете эту функцию через COM-объект. Казалось бы, данные должны попасть в «восьмерку», но вместо привычной таблицы вы получаете неопознанный COMОбъект. Попытка преобразовать его через ЗначениеИзСтрокиВнутр приводит к ошибке «Ошибка формата потока».
Выясним причину: методы ValueToStringInternal в 7.7 и 8.3 формируют строки в абсолютно разных внутренних форматах. Они несовместимы. Поскольку ТЗ является сложным (непримитивным) типом данных, она передается через COM не как копия данных, а как ссылка на объект в памяти «семерки».
Самый простой (хотя и не самый быстрый) способ — это работа с COM-объектом таблицы значений напрямую, используя программный интерфейс 1С 7.7. Разберем по шагам, как это реализовать в коде 1С 8.3:
// 1. Создаем соединение
V77 = Новый COMОбъект("V77.Application");
Открыто = V77.Initialize(V77.RMTrade, "/d""C:\Base77"" /nAdmin", "NO_SPLASH_SHOW");
Если Открыто Тогда
// 2. Вызываем функцию из глобального модуля 7.7, возвращающую ТЗ
тзИзКлюшек = V77.глПолучитьРезультатЗапросаДля83();
// 3. Создаем пустую таблицу значений на стороне 8.3
Таблица83 = Новый ТаблицаЗначений;
Таблица83.Колонки.Добавить("НоменклатураНаименование");
Таблица83.Колонки.Добавить("Количество");
// 4. Используем методы 7.7 для обхода строк
тзИзКлюшек.ВыбратьСтроки();
Пока тзИзКлюшек.ПолучитьСтроку() = 1 Цикл
НоваяСтрока = Таблица83.Добавить();
// Важно: получаем примитивные значения (строки, числа)
// Если обратиться к тзИзКлюшек.Номенклатура, получим COMОбъект (ссылку)
НоваяСтрока.НоменклатураНаименование = тзИзКлюшек.Номенклатура.Наименование;
НоваяСтрока.Количество = тзИзКлюшек.Количество;
КонецЦикла;
КонецЕсли;
Проанализируем этот код: мы используем методы ВыбратьСтроки() и ПолучитьСтроку(), которые принадлежат объекту 1С 7.7. Это позволяет нам итерироваться по данным, не пытаясь конвертировать всю таблицу целиком.
Как мы заметили, обращение через точку к реквизитам справочников (например, тзИзКлюшек.Номенклатура.Наименование) на стороне 8.3 порождает дополнительный COM-вызов. Если в таблице тысячи строк, производительность упадет в десятки раз.
Рекомендуемая стратегия: разыменовывайте данные на стороне 7.7. Подготовьте таблицу значений в «семерке» так, чтобы в ее колонках уже лежали готовые строки, числа и даты. Вместо объекта «Номенклатура» запишите в колонку сразу Номенклатура.Наименование или Номенклатура.Код.
Если данных очень много, перебор строк через COM станет узким местом. В этом случае лучше сериализовать таблицу в строку. Рассмотрим вариант с использованием XML:
v7plus.dll или простым перебором сформируйте XML-строку из данных ТЗ.Строка.ЧтениеXML для моментальной загрузки данных в локальную таблицу значений.Этот метод работает в разы быстрее, так как происходит всего один COM-вызов для передачи всей строки данных.
Часто разработка ведется на файловой базе (32-битный клиент), где код Новый COMОбъект("V77.Application") работает идеально. Но при переносе на клиент-серверный вариант (64-битный сервер 1С) возникает ошибка или пустой результат.
Причина ситуации: 1С 7.7 — это 32-битное приложение. 64-битный процесс сервера 1С не может напрямую загрузить 32-битную DLL «семерки».
Чтобы побороть эту проблему, необходимо использовать «Службы компонентов» Windows (COM+):
1C77_COM.V77.Application.После этой настройки Windows будет запускать 1С 7.7 в отдельном процессе dllhost.exe, который послужит мостом между 64-битным сервером и 32-битным COM-объектом.
Если выполнение кода падает на строке V77.Initialize(...), проанализируем следующие моменты:
USR1CV8 (или тот, под кем работает сервер 1С) должен иметь полные права на каталог с базой 7.7, каталог программы и ветку реестра HKEY_CLASSES_ROOT.NO_SPLASH_SHOW отключает только заставку, но не модальные окна. Убедитесь, что база «семерки» находится в рабочем состоянии и не требует монопольного вмешательства.V77.Application (сетевая), V77S.Application (SQL) или V77L.Application (локальная).Важный совет по очистке памяти: После завершения работы с COM-объектом обязательно уничтожайте соединение. В «восьмерке» это делается присвоением переменной значения Неопределено:
V77 = Неопределено;
// Желательно также вызвать принудительный сбор мусора
СредстваПлатформы.ВызватьСборМусора();
Это предотвратит накопление «зависших» процессов 1cv77.exe в памяти сервера, которые могут привести к утечке ресурсов и нестабильной работе всей системы.