Интеграция устаревшей, но все еще популярной платформы 1С:Предприятие 7.7 (так называемых «клюшек») с современными конфигурациями на платформе 1С:Предприятие 8.х («снеговиком») через COM-соединение — это классическая задача автоматизации. При её реализации разработчики часто сталкиваются со специфическими ошибками, связанными с различиями в архитектуре и синтаксисе двух платформ. В этой статье мы подробно разберем, как правильно обращаться к справочникам 1С 8 из кода 1С 7.7, и решим проблему обработки булевых значений.
Рассмотрим ситуацию, когда разработчик пытается использовать привычный синтаксис «семерки» для работы с объектом «восьмерки». Попытка выполнить следующий код:
Заказчик = База8.Справочники.Заказчики;
Заказчик.ВыбратьЭлементы("01.01.2016", ТекущаяДата);
приводит к ошибке выполнения: «Поле агрегатного объекта не обнаружено (ВыбратьЭлементы)». Выясним причину этой проблемы:
ВыбратьЭлементы(). В платформе 1С 8 периодических справочников нет — вся история изменений хранится в регистрах сведений. Соответственно, метод Выбрать() в 1С 8 не принимает параметры дат начала и окончания периода.Разберем по шагам, как правильно построить выборку. Для получения элементов справочника 1С 8 используется метод Выбрать(). На стороне 1С 7.7 этот механизм реализуется следующим образом:
// Получаем менеджер справочника из COM-соединения
Выборка = База8.Справочники.Заказчики.Выбрать();
// Обходим элементы выборки
Пока Выборка.Следующий() <> 0 Цикл
Сообщить(Выборка.Наименование);
КонецЦикла;
Обратите внимание на конструкцию цикла. В оригинальном синтаксисе 1С 8 мы пишем просто Пока Выборка.Следующий() Цикл. Однако в 1С 7.7 такая запись вызовет ошибку «Выражение должно иметь логический тип». Это связано с особенностями обработки типов данных OLE/COM.
Проанализируем важнейшую деталь: в платформе 1С 7.7 отсутствует встроенный тип данных Булево. Вместо него используются числа (1 — Истина, 0 — Ложь). При передаче булевых значений из 1С 8 через COM-порт происходят следующие преобразования:
Истина (True) преобразуется интерфейсом Windows в число -1.Ложь (False) преобразуется в число 0.Именно поэтому попытка написать Пока Выборка.Следующий() = 1 Цикл приведет к тому, что цикл просто не выполнится — метод вернет значение -1, которое не равно 1. Чтобы избежать этой проблемы, мы рекомендуем использовать проверку на неравенство нулю:
Пока Выборка.Следующий() <> 0 Цикл
// Код будет успешно выполняться для каждого найденного элемента
Сообщить("Элемент: " + Выборка.Наименование);
КонецЦикла;
Этот способ универсален, не мозолит глаза отрицательными числами и стабильно работает во всех версиях операционных систем.
Если вам требуется не просто прочитать данные, а записать булево значение обратно в базу 1С 8 (например, установить признак «ПометкаУдаления» или провести документ), прямое присвоение чисел 1 или -1 вызовет ошибку несоответствия типов. Решить эту задачу можно двумя путями:
Способ 1. Использование внутреннего представления XML-сериализации
В платформе 1С 8 булевы значения можно воссоздать через чтение системной строки XML. Посмотрим на пример:
Истина8 = База8.ЗначениеИзСтрокиВнутр("{""B"",1}");
Ложь8 = База8.ЗначениеИзСтрокиВнутр("{""B"",0}");
// Теперь передаем эти переменные в реквизиты объекта 1С 8:
НовыйЭлемент = База8.Справочники.Заказчики.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Новый контрагент";
НовыйЭлемент.ПометкаУдаления = Ложь8; // Передали "Ложь" в формате 1С 8
НовыйЭлемент.Записать();
Способ 2. Функции-обертки в конфигурации 1С 8
Если у вас есть доступ к изменению конфигурации 1С 8, вы можете создать в общем модуле (с флагом «Внешнее соединение») простую экспортную функцию:
Функция ПолучитьБулевоЗначение(ЗначениеЧислом) Экспорт
Возврат ?(ЗначениеЧислом = 1, Истина, Ложь);
КонецФункции
В коде 1С 7.7 вызов этой функции будет выглядеть так: Объект8.Реквизит = База8.ИмяМодуля.ПолучитьБулевоЗначение(1);.
Использование метода Выбрать() для получения данных через COM-соединение сильно нагружает систему, так как при этом через сеть передаются тяжелые ссылочные объекты. Гораздо эффективнее и быстрее использовать механизм запросов 1С 8.
Поскольку в 1С 7.7 нет ключевого слова Новый для создания объектов внешней базы, мы задействуем метод NewObject(). Посмотрим на пример реализации запроса:
// Инициализируем объект запроса в контексте 1С 8
Запрос = База8.NewObject("Запрос");
// Пишем текст запроса по правилам синтаксиса 1С 8
Запрос.Текст = "
|ВЫБРАТЬ
| Заказчики.Код КАК Код,
| Заказчики.Наименование КАК Наименование
|ИЗ
| Справочник.Заказчики КАК Заказчики
|ГДЕ
| Заказчики.ПометкаУдаления = ЛОЖЬ";
// Выполняем и обходим выборку результатов
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() <> 0 Цикл
Сообщить("Код: " + Выборка.Код + " | Наименование: " + Выборка.Наименование);
КонецЦикла;
Важное ограничение: Мы настоятельно не рекомендуем выгружать результат запроса в ТаблицаЗначений методом Выгрузить(), если планируете обрабатывать её на стороне 1С 7.7. Передача сложных типов коллекций через COM-соединение работает крайне медленно и нестабильно. Обход выборки через Следующий() в цикле — самый надежный и быстрый вариант.
При инициализации подключения разработчики часто сталкиваются с ошибкой «Класс не зарегистрирован» при попытке создать объект V83.COMConnector.
Разберем причины возникновения этой проблемы и методы устранения:
regsvr32 "C:\Program Files (x86)\1cv8\<РелизПлатформы>\bin\comcntr.dll"