Работа с 1С через OLE 8.* (V81.Application, V81.COMConnector)

07.04.11

Разработка - Математика и алгоритмы

Решил серьезно заняться изучением OLE. Конечно OLE это не КД, но все же...

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

Введение

При установке 1С на компьютер в реестре регистрируется ряд компонент. Это

  • V81.Application
  • V81.COMConnector
  • V81.InfoBaseList
  • V81.InfoBaseListLink
  • V81.ServerAbout
  • V81.ServerAdminScope

Данная статья рассматривает два из этих объектов V81.Application, V81.COMConnector, служащих для подключения с использованием COM-технологий к базе 1С 8.1 не зависимо от того находится ли данная база на сервере или представлена в виде файлового варианта.

Так же мы рассмотрим нюансы подключения к базе из 1C v7.7.

К данной статье будет приложен иллюстративный материал в виде конфигурации с демо-обработкой, входящей в состав данной базы, и обработка для 7.7, демонстрирующая соединение с данной базой.

Создание каркасной базы

Создадим новую конфигурацию

В ней мы создадим ПараметрСеанса МиниЛогЗапуска и глобальный модуль с атрибутами

  • Глобальный
  • Клиент
  • Сервер

Приведу код глобального модуля

#Если Клиент Тогда
Функция ВернутьТипПодключения() Экспорт
    Возврат("Клиент");
КонецФункции
#Иначе
Функция ВернутьТипПодключения() Экспорт
    Возврат("Сервер");
КонецФункции
#КонецЕсли


Функция ВернутьНеопределено() Экспорт
    Возврат Неопределено;
КонецФункции

Функция ВернутьNULL() Экспорт
    Возврат Null;
КонецФункции

Функция ВернутьИстину() Экспорт
    Возврат Истина;
КонецФункции

Функция ВернутьЛожь() Экспорт
    Возврат Ложь;
КонецФункции

Функция ВернутьСистемноеПеречисление()Экспорт
    Возврат(ВидДвиженияНакопления.Расход);
КонецФункции

Функция ВернутьПараметр(ИмяПараметра)Экспорт
    Попытка
        Зн=ПараметрыСеанса[ИмяПараметра];
    Исключение
        Возврат Неопределено;
    КонецПопытки;
    Возврат Зн;
КонецФункции

Кроме этих функций добавим функцию возвращающую по имени справочник в виде ТаблицыЗначений

Функция ЗапросКСправочнику(ИмяСправочника) Экспорт
    Попытка
        МетСпр=Метаданные.Справочники[ИмяСправочника];
    Исключение
        Возврат Неопределено
    КонецПопытки;
    Запрос=Новый Запрос;
    ТекстЗапроса="";
    ТекстЗапроса="Выбрать Спр.Ссылка,Спр.ПометкаУдаления,Спр.Предопределенный,";
    Если МетСпр.Иерархический Тогда
        ТекстЗапроса=ТекстЗапроса+"Спр.Родитель,Спр.ЭтоГруппа,";
    КонецЕсли;
    Если МетСпр.ДлинаКода<>0 Тогда
        ТекстЗапроса=ТекстЗапроса+"Спр.Код,";
    КонецЕсли;
    Если МетСпр.ДлинаНаименования<>0 Тогда
        ТекстЗапроса=ТекстЗапроса+"Спр.Наименование,";
    КонецЕсли;
    Для Каждого Рекв из МетСпр.Реквизиты Цикл
        ТекстЗапроса=ТекстЗапроса+"Спр."+Рекв.Имя+",";
    КонецЦикла;
    ТекстЗапроса=ТекстЗапроса+"Спр.Представление
    |ИЗ Справочник."+ИмяСправочника+" КАК Спр";
    Запрос.Текст=ТекстЗапроса;
    Возврат(Запрос.Выполнить().Выгрузить());
КонецФункции

Также определим процедуру в модуле внешнего соединения

Процедура ПриНачалеРаботыСистемы()
    Попытка
        ПараметрыСеанса.ПараметрСеанса1=СокрЛП(ПараметрыСеанса.ПараметрСеанса1)+"
        |Внешнее Соединение";
    Исключение
        ПараметрыСеанса.ПараметрСеанса1="Внешнее Соединение";
    КонецПопытки;
КонецПроцедуры

И процедуру в модуле приложения

Процедура ПриНачалеРаботыСистемы()
    Попытка
        ПараметрыСеанса.ПараметрСеанса1=СокрЛП(ПараметрыСеанса.ПараметрСеанса1)+"
        |Приложение";
    Исключение
        ПараметрыСеанса.ПараметрСеанса1="Приложение";
    КонецПопытки;
КонецПроцедуры

Также добавим ещё один не глобальный модуль с атрибутами

  • Клиент
  • Сервер

И с единственной функцией

Функция ВозвратСтроки() Экспорт
    Возврат("ОбщийМодуль1");
КонецФункции

Application и ComConnector сравнение соединение из 1С 8

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

Для целого ряда методов в синтаксис помощнике указанно "Не используется в модуле внешнего соединения". Это упоминание не даёт полной картины.

Объект V81.Application соответствует объекту V77.Aplication, а именно происходит загрузка сервера с интерфейсными библиотеками в режиме клиент, объект же V81.COMConnector при загрузке не имеет ничего из того что отвечает за интерфейс с пользователем, что повышает производительность при работе с внешним соединением.

Создаём обработку в нашей конфигурации, для проверки вызова наших методов.

В обработке объявляем две переменных и функцию установления соединения с базой

Перем cntr,connection;
Функция ОткрытиеБазы(ТипОткрытия)
    cntr = Новый COMObject(ТипОткрытия);
    connection=Истина;
    Попытка
        Если ЭлементыФормы.Панель1.ТекущаяСтраница.Заголовок="Файловая версия" Тогда
            connection = cntr.Connect("File="""+СокрЛП(ПутьКбазе)+""";Usr="""+СокрЛП(Логин)+""";Pwd = """ + СокрЛП(Пасворд) + """;");
        Иначе
            connection = cntr.Connect("Srvr="""+СокрЛП(ИмяСервера)+""";Ref="""+СокрЛП(ИмяБазы)+""";Usr="""+СокрЛП(Логин)+""";Pwd = """ + СокрЛП(Пасворд) + """;");
        КонецЕсли;
    Исключение
        Предупреждение(ОписаниеОшибки());
        connection=Ложь;
    КонецПопытки;
    Возврат connection;
КонецФункции

В переменной открытия мы передаём либо строку "V81.Application", либо строку "V81.ComConnector"

При этом для V81.Application возвращается Истина в connection, а cntr является нашим объектом через который мы обращаемся к базе

Для ComConnector в connection возвращается объект для обращения к базе, а cntr является объектом описанным в синтаксис помощнике как COM-соединитель.

Свойства и методы COM-соединителя.
HighBoundDefault Свойство, только чтение, Тип: Число. Содержит верхнюю границу диапазона IP портов сервера кластера по умолчанию.
LowBoundDefault Свойство, только чтение, Тип: Число. Содержит нижнюю границу диапазона IP портов сервера кластера по умолчанию.
MaxConnections Свойство, только чтение, Тип: Число. Определяет максимальное число одновременно существующих объектов COM-соединение, созданных через данный COM-соединитель. Число одновременно существующих соединений включает также число соединений, находящихся в пуле COM-соединений. Значением по умолчанию 0 (число одновременно существующих объектов COM-соединение не ограничено). Устанавливать свойству не нулевое значение можно только в том случае, если сам объект COM-соединитель был создан в Multithreaded Apartment (MTA), что обеспечивает реальное функционирование самого COM-соединителя и созданных им объектов COM-соединение в многопотоковой (multithreaded) среде. Это условие соблюдается в частности, если COM-соединитель был создан в приложении ASP.NET. Если же объект COM-соединитель был создан в Singlethreaded Apartment (STA), то реально все действия с COM-соединителем и созданными им объектами COM-соединение будут выполняться в одном потоке. В этом случае, если метод Connect не сможет на первом проходе найти подходящее или создать новое COM-соединение, то выполнение этого метода зациклится, так как освободить уже, возможно, ненужное другое COM-соединение будет нельзя по той причине, что операция освобождения объекта COM-соединение должна быть выполнена в том же потоке, в котором уже выполняется метод Connect. Следует помнить, что создание COM-объектов из приложения 1C:Предприятие 8.1 выполняется из STA. Это же справедливо для большинства GUI-приложений Windows.
PoolCapacity Свойство, только чтение, Тип: Число. Максимальное количество соединений с информационной базой, которые могут одновременно находиться в пуле.
PoolTimeout Свойство, только чтение, Тип: Число. Максимальное время нахождения в пуле неиспользуемого соединения с информационной базой. После истечения этого времени неиспользуемое соединение освобождается.
RAgentPortDefault Свойство, только чтение, Тип: Число. Содержит номер IP порта агента сервера по умолчанию.
RMngrPortDefault Свойство, только чтение, Тип: Число. Содержит номер IP порта менеджера кластера по умолчанию.
Connect (Connect) Синтаксис:
Connect(<Строка соединения>)
Параметры:
<Строка соединения> (обязательный)
Тип: Строка. Строка параметров, используемая 1С:Предприятием для соединения с информационной базой. Строка соединения представляет собой набор параметров, каждый из которых является фрагментом вида: <Имя параметра=><Значение>, где Имя параметра — имя параметра, а Значение — его значение. Фрагменты отделяются друг от друга символами ';'. Если значение содержит пробельные символы, то оно должно быть заключено в двойные кавычки ("). Для файлового варианта определен параметр: File — каталог информационной базы (файловый режим); Для клиент-серверного варианта определены параметры: Srvr — имя сервера 1С:Предприятия; Ref — имя информационной базы на сервере; Для всех вариантов определены параметры: Usr — имя пользователя; Pwd — пароль и UC<Код доступа> позволяет выполнить установку соединения с информационной базой, на которую установлена блокировка установки соединений. Если при установке блокировки задан непустой код доступа, то для установки соединения необходимо в параметре /UC указать этот код доступа. Возвращаемое значение:
Тип: COM-соединение.
Описание:
Создает соединение с информационной базой 1С:Предприятия 8.1.
Устанавливает соединение с информационной базой 1С:Предприятия 8.1 и возвращает ссылку на объект COM-соединение.
Установка соединения выполняется по следующему алгоритму:
  1. COM-соединение с требуемыми параметрами ищется в пуле соединений. Если найдено, то используется оно.
  2. Если COM-соединение с требуемыми параметрами не найдено, то анализируется не исчерпан ли лимит по числу одновременно существующих соединений. Если не исчерпан, то создается новое COM-соединение.
  3. Если лимит исчерпан, но при этом в пуле имеются неиспользуемые COM-соединение, то соединение, дольше всех находящееся в пуле, удаляется и создается новое COM-соединение.
  4. Если никаким способом найти подходящее или создать новое COM-соединение не удалось, то происходит ожидание освобождения COM-соединение другим потоком, после чего весь процесс повторяется, начиная с пункта 1.
ConnectAgent(<Идентификатор>) Синтаксис:
ConnectAgent(<Идентификатор>)
Параметры:
<Идентификатор> (обязательный)
Тип: Строка. Идентификатор протокола (по умолчанию tcp), имя компьютера или IP адрес агента сервера (обязательно), номер IP порта агента сервера (по умолчанию 1540). Например, значением параметра могут быть следующие строки: «server1», «tcp://server1», «tcp://server1:1540», «server1:1540».
Возвращаемое значение:
Тип: Соединение с агентом сервера.
Описание:
Выполняет подсоединение к агенту сервера 1С:Предприятия 8.1, работающему на указанном серверном компьютере.
Примечание:
Если подсоединение невозможно, то вызывается исключение.
ConnectWorkingProcess (ConnectWorkingProcess) Синтаксис:
ConnectWorkingProcess(<Имя>)
Параметры:
<Имя> (обязательный)
Тип: Строка. Имя или IP адрес рабочего процесса, с которым должно быть установлено соединение, в формате: <протокол>://<адрес_или_имя>:<порт> Например:
testcomp
tcp://testcomp
tcp://testcomp:2354
tcp://43.73.34.11:5342.
Возвращаемое значение:
Тип: Соединение с рабочим процессом.
Описание:
Создает административное соединение с рабочим процессом кластера серверов 1С:Предприятия 8.1.


Для установки соединения с базой надо методу Connect нашего объекта передать строку соединения.

Для файловой версии данная строка содержит параметры:

  • File с указанием пути к папке с файлом базы
  • Usr с указанием имени прользователя
  • Pwd с указанием пароля прользователя

Для соединения с сервером Usr и Pwd прежние параметры, а вот вместо File два параметра Srvr с указанием имени сервера и Ref с указанием имени Базы

Вызовы из восьмёрки через Application и ComConnector

Пробуем организовать вызов функций нашей конфигурации из обработки на 8.1

Пишем процедуру вызова функций с определением, что возвращается при вызове

Процедура ОсновныеДействияФормыВызовФункции(Кнопка)
    Если Не ОткрытиеБазы("V81.Application") Тогда Возврат; КонецЕсли;
    Сообщить("Вернули неопределено? "+(cntr.ВернутьНеопределено()=Неопределено));
    Сообщить("Вернули NULL? "+(cntr.ВернутьNULL()=NULL));
    Сообщить("Вернули Истину? "+(cntr.ВернутьИстину()=Истина));
    Сообщить("Вернули Ложь? "+(cntr.ВернутьЛожь()=Ложь));
    Сообщить("Вернули параметр "+cntr.ВернутьПараметр("ПараметрСеанса1"));
    Сообщить("Не глобальный модуль "+cntr.ОбщийМодуль1.ВозвратСтроки());
    Сообщить("ТипПодключения="+cntr.ВернутьТипПодключения());
    cntr = "";
КонецПроцедуры

Рассмотрим лог сообщений:

 Вернули неопределено? истина
 Вернули NULL? истина
 Вернули Истину? истина
 Вернули Ложь? истина
 Вернули параметр Приложение
 Не глобальный модуль ОбщийМодуль1
 ТипПодключения=Клиент

Что это нам даёт?

Значения типа неопределено,NULL,Истина,Ложь передаются в соединение с базой корректно.

Модуль внешнего соединения при подключении через V81.Application не отрабатывает.

Модуль приложения при подключении через V81.Application отрабатывает.

Тип подключения, в котором мы подключаемся к базе, соответствует типу подключения клиент

Пишем аналогичную процедуру, но уже с использованием ComConnector

Процедура ОсновныеДействияФормыВызовФункции2(Кнопка)
    Если ОткрытиеБазы("V81.ComConnector")<>Ложь Тогда
        Сообщить("Вернули неопределено? "+(connection.ВернутьНеопределено()=Неопределено));
        Сообщить("Вернули NULL? "+(connection.ВернутьNULL()=NULL));
        Сообщить("Вернули Истину? "+(connection.ВернутьИстину()=Истина));
        Сообщить("Вернули Ложь? "+(connection.ВернутьЛожь()=Ложь));
        Сообщить("Вернули параметр "+connection.ВернутьПараметр("ПараметрСеанса1"));
        Сообщить("Не глобальный модуль "+connection.ОбщийМодуль1.ВозвратСтроки());
        Сообщить("ТипПодключения="+connection.ВернутьТипПодключения());
        cntr = "";connection="";
    КонецЕсли;
КонецПроцедуры

Лог сообщений у нас отличается в строчках

Вернули Параметр Внешнее Соединение
ТипПодключения=Сервер

То есть, при обращении через объект V81.ComConnector подключение осуществляется в режиме север, даже если мы подключаемся к локальной файловой базе.

Теперь попробуем обратиться к нашим объектам, ну хотя бы к V81.Application из 1С 7.7

Пишем примерно тот же код

Перем НомерЗакладки;
Перем connection,cntr;
Перем Истина,Ложь;
Функция ОткрытиеБазы(ТипОткрытия)
    cntr = СоздатьОбъект(ТипОткрытия);
    Попытка
        Если НомерЗакладки=1 Тогда
            connection = cntr.Connect("File="""+СокрЛП(ПутьКбазе)+""";Usr="""+СокрЛП(Логин)+""";Pwd = """ + СокрЛП(Пасворд) + """;");
        Иначе
            connection = cntr.Connect("Srvr="""+СокрЛП(ИмяСервера)+""";Ref="""+СокрЛП(ИмяБазы)+""";Usr="""+СокрЛП(Логин)+""";Pwd = """ + СокрЛП(Пасворд) + """;");
        КонецЕсли;
    Исключение
        Предупреждение(ОписаниеОшибки());
    КонецПопытки;
КонецФункции
Функция ВызовФункций()
    ОткрытиеБазы("V81.Application");
    Если connection=Истина Тогда
        Сообщить("Вернули неопределено= "+cntr.ВернутьНеопределено());
        Сообщить("Вернули NULL= "+cntr.ВернутьNULL());
        Сообщить("Вернули Истину= "+cntr.ВернутьИстину());
        Сообщить("Вернули Ложь= "+cntr.ВернутьЛожь());
    КонецЕсли;
    cntr = "";
КонецФункции

Истина=-1;Ложь=0;

Лог сообщений выглядит так

Вернули неопределено=
Вернули NULL=
Вернули Истину= -1
Вернули Ложь= 0

Так мы убеждаемся что Ложь соответствует 0, Истина -1, а NULL и неопределено ничего в стандартах 1Cv7.7 не возвращают

Как же отличить NULL от неопределено?

Для этого у объекта cntr в случае V81.Application и у connection в случае V81.ComConnector есть метод String

В описание данного метода сказано "Получает строковое представление значения произвольного типа".

Пробуем использовать этот метод из 7.7

Добавив в нашу Функцию ВызовФункций() несколько строк кода

Сообщить("ВернулиНеопределено="+cntr.String(cntr.ВернутьНеопределено()));
Сообщить("ВернулиNULL="+cntr.String(cntr.ВернутьNULL()));
Сообщить("ВернулиСистемноеПеречисление="+cntr.String(cntr.ВернутьСистемноеПеречисление()));

Результат в логе сообщений

ВернулиНеопределено=Неопределено
ВернулиNULL=
ВернулиСистемноеПеречисление=Расход

Так мы отмечаем, что NULL возвращается пустой строкой, неопределено строкой "Неопределено" и системное перечисление своим представлением

Итак, у нас есть конфигурация с модулем, но у неё нет метаданных.

Добавим перечисление, справочник, и три константы одну типа строка, одну типа перечисления и одну составного типа

Разбор метаданных через ОЛЕ

Добавим в обработку на 1С 7.7 и 8.1 функцию работы с метаданными

Функция РаботаСметаданными()
    ОткрытиеБазы("V81.Application");
    Если connection=Истина Тогда
        Сообщить("Версия "+cntr.Метаданные.Версия);
        Сообщить("==================Константы==================");
        Для Инд=0 по cntr.Метаданные.Константы.Количество()-1 Цикл
            Конст=cntr.Метаданные.Константы.Получить(Инд);
            Сообщить(Конст.Имя);
            Сообщить("Тип:");
            Массив = Конст.Тип.Типы();
            Типов = Массив.Количество() - 1;
            для а = 0 по Типов цикл
                сообщить(cntr.String(Массив.Получить(а)));
            конеццикла;
        КонецЦикла;
        cntr = "";
    КонецЕсли;
КонецФункции

Сохраним обработки и запустив просмотрим лог сообщений

Версия V81.Application
==================Константы==================
Константа1
Тип:
Строка
Константа2
Тип:
Справочник ссылка: Справочник1
Константа3
Тип:
Справочник ссылка: Справочник1
Перечисление ссылка: Перечисление1

Мы можем получить тип любых метаданных используя этот пример и описание работы с метаданными

Использование менеджеров для работы с данными через ОЛЕ

Мы прояснили процесс работы с метаданными, а теперь обратимся к работе с данными

Функция РаботаСБазой()
    ОткрытиеБазы("V81.Application");
    Если connection=Истина Тогда
        Стр="";
        Если ВвестиСтроку(Стр,"Наименование",40)=1 Тогда
            Эл=cntr.Справочники.Справочник1.НайтиПоНаименованию(СокрЛП(Стр));
            Если Эл.Пустая()=Истина Тогда
                Эл=cntr.Справочники.Справочник1.СоздатьЭлемент();
                Эл.Наименование=СокрЛП(Стр);
                Эл.Записать();
                Сообщить("ЗначениеВСтрокуВнутр="+cntr.ЗначениеВСтрокуВнутр(Эл.Ссылка));
                Сообщить("XMLСтрока="+cntr.XMLСтрока(Эл.Ссылка));
                Сообщить("=======XMLТипЗнч======");
                XMLРез=cntr.XMLТипЗнч(Эл.Ссылка);
                Сообщить("URIПространстваИмен="+XMLРез.URIПространстваИмен);
                Сообщить("ИмяТипа="+XMLРез.ИмяТипа);
            КонецЕсли;
            cntr.Константы.Константа3.Установить(Эл.Ссылка);
        КонецЕсли;
    КонецЕсли;
    cntr = "";
КонецФункции

В данной процедуре мы указываем наименование справочника, и если такого наименования нет, то мы создаём элемент справочника. Выводим всю информацию которую можем получить и присваиваем значение элемента справочника нашей константе

Создадим элемент и просмотрим лог сообщений

ЗначениеВСтрокуВнутр={"#",3395433c-d726-4c7e-ae3a-45f785811756,1:a68d00142a16c0f211de2d7a6de7a9eb}
XMLСтрока=6de7a9eb-2d7a-11de-a68d-00142a16c0f2
=======XMLТипЗнч======
URIПространстваИмен=
ИмяТипа=CatalogRef.Справочник1


Запросы,Конструкторы запросов и произвольные объекты 8.* через ОЛЕ

Мы использовали работу менеджеров для получения и изменения, данных базы,но более высокой производительностью в восьмёрке обладают запросы и их мы так же можем использовать.

Пишем функцию:

Функция РаботаСЗапросами()
    ОткрытиеБазы("V81.Application");
    Если connection=Истина Тогда
        Констр=cntr.NewObject("КонструкторЗапроса");
        Если Констр.ОткрытьМодально()=Истина Тогда
            ТекстЗапроса=Констр.Текст;
            cntr = "";
            ОткрытиеБазы("V81.ComConnector");
            Запрос=connection.NewObject("Запрос");
            Запрос.Текст=ТекстЗапроса;
            Рез=Запрос.Выполнить().Выгрузить();
            Таб=СоздатьОбъект("Таблица");
            Для Инд=0 по Рез.Колонки.Количество()-1 Цикл
                Кол=Рез.Колонки.Получить(Инд);
                Обл=Таб.Область("R1C"+Строка(Инд+1));
                Обл.Текст=Кол.Имя;
            Конеццикла;
            Для Инд=0 по Рез.Количество()-1 Цикл
                Стр=Рез.Получить(Инд);
                Кол=0;
                Для Кол=0 по Рез.Колонки.Количество()-1 Цикл
                    Обл=Таб.Область("R"+Строка(Инд+2)+"C"+Строка(Кол+1));
                    Обл.Текст=connection.String(Стр.Получить(Кол));
                КонецЦикла;
            КонецЦикла;
            Таб.Показать();
        Иначе
            Сообщить("!Запрос не создан");
        КонецЕсли;
    КонецЕсли;
    cntr = "";
    connection = "";
КонецФункции

В данном примере мы сначала пользуемся V81.Application, у которого есть интерфейсные библиотеки и методом NewObject (являющимся конструкцией языка 1С 8.* Новый) для вызова конструктора запроса.

Потом мы закрываем базу, и подключившись через V81.ComConnector создаём сам запрос и результат запроса в линейном порядке выводим в объект 7.7 таблица.

В принципе такой порядок использования запроса необязателен, но из ComConnector мы не сможем вызвать метод ОткрытьМодально() по причине отсутствия интерфейсных библиотек.

Проблема булева типа из 7.7 (можем передать, но не можем вернуть)

Изменим структуру нашей базы, а именно. Для Константы Константа1 изменим тип с простого типа Строка на составной Булево,Число

Разместим в глобальном модуле функцию, которая нам вернет значение в виде строки.

Так же предположим, что мы не хотим, что бы код нашей функции компилировался при запуске в режиме приложения, а хотим что бы наш код работал только в режиме внешнего соединения независимо от того подключаемся мы через V81.ComConnector или через V81.Application.

Функция РаботаСЗапросами()
    ОткрытиеБазы("V81.Application");
    Если connection=Истина Тогда
        Констр=cntr.NewObject("КонструкторЗапроса");
        Если Констр.ОткрытьМодально()=Истина Тогда
            ТекстЗапроса=Констр.Текст;
            cntr = "";
            ОткрытиеБазы("V81.ComConnector");
            Запрос=connection.NewObject("Запрос");
            Запрос.Текст=ТекстЗапроса;
            Рез=Запрос.Выполнить().Выгрузить();
            Таб=СоздатьОбъект("Таблица");
            Для Инд=0 по Рез.Колонки.Количество()-1 Цикл
                Кол=Рез.Колонки.Получить(Инд);
                Обл=Таб.Область("R1C"+Строка(Инд+1));
                Обл.Текст=Кол.Имя;
            Конеццикла;
            Для Инд=0 по Рез.Количество()-1 Цикл
                Стр=Рез.Получить(Инд);
                Кол=0;
                Для Кол=0 по Рез.Колонки.Количество()-1 Цикл
                    Обл=Таб.Область("R"+Строка(Инд+2)+"C"+Строка(Кол+1));
                    Обл.Текст=connection.String(Стр.Получить(Кол));
                КонецЦикла;
            КонецЦикла;
            Таб.Показать();
        Иначе
            Сообщить("!Запрос не создан");
        КонецЕсли;
    КонецЕсли;
    cntr = "";
    connection = "";
КонецФункции

Вызов из 77 я описывать не буду, он уже для вас довольно тривиален.

В принципе вместо напсиания данного кода мы можем, запустив восьмёрку, вычислить выражение в табло и убедиться, что

ЗначениеВстрокуВнутр(Истина)={"B",1}
ЗначениеВстрокуВнутр(Ложь)={"B",0} 

Определим функцию работы с нашей константой в обработке вызываемой из 7.7

Функция УстановитьИстина()
    ОткрытиеБазы("V81.Application");
    Если connection=Истина Тогда
        cntr.Константы.Константа1.Установить(cntr.ЗначениеИзСтрокиВнутр("{""B"",1}"));
        Сообщить(cntr.Константы.Константа1.Получить());
        Сообщить(cntr.ЗначениеВстрокуВнутр(cntr.Константы.Константа1.Получить()));
        cntr = "";
    КонецЕсли;
КонецФункции

Функция УстановитьЛожь()
    ОткрытиеБазы("V81.Application");
    Если connection=Истина Тогда
        cntr.Константы.Константа1.Установить(cntr.ЗначениеИзСтрокиВнутр("{""B"",0}"));
        Сообщить(cntr.Константы.Константа1.Получить());
        Сообщить(cntr.ЗначениеВстрокуВнутр(cntr.Константы.Константа1.Получить()));
        cntr = "";
    КонецЕсли;
КонецФункции

Функция УстановитьЧисло()
    ОткрытиеБазы("V81.Application");
    Если connection=Истина Тогда
        Чис=0;
        Если ВвестиЧисло(Чис,"Константа1",12,2)=1 Тогда
            cntr.Константы.Константа1.Установить(Чис);
            Сообщить(cntr.Константы.Константа1.Получить());
            Сообщить(cntr.ЗначениеВстрокуВнутр(cntr.Константы.Константа1.Получить()));
            cntr = "";
        КонецЕсли;
    КонецЕсли;
КонецФункции

Функция РаботаСконстантой()
    Меню=СоздатьОбъект("СписокЗначений");
    Меню.ДобавитьЗначение("УстановитьИстина()","Установить Истина");
    Меню.ДобавитьЗначение("УстановитьЛожь()","Установить Ложь");
    Меню.ДобавитьЗначение("УстановитьЧисло()","Установить Число");
    Зн="";
    Поз=0;
    Если Меню.ВыбратьЗначение(Зн,,Поз,,1)=1 Тогда
        Шаблон("["+Зн+"]");
    КонецЕсли;
КонецФункции

Рассмотрим лог сообщений после вызова всех трех вариантов функций и просмотра базы в режиме предпрития

-1
{"N",-1}
0
{"N",0}
56
{"N",56}

Какой вывод мы можем сделать из этого лога

Что тип булево возвращается стороннему приложению как число.

Мы можем установить значение булева и любого неизвестного 7.7 типа через ЗначениеИзСтрокиВнутр, но как минимум в случае с булевым типом мы не сможем его прочитать обратно иначе чем число.

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

Проблема времени из 7.7 (не можем передать)

Добавляем в нашу базу регистр накопления и документ регистратор и пишем в 7.7 простую функцию, формирующую движения данного документа

Функция ТипаПереносОстатков()
    Попытка
        ОткрытиеБазы("V81.ComConnector");
    Исключение
        Сообщить("Не удалось открыть базу с заданными параметрами");
        Возврат "";
    КонецПопытки;
    Стр="";
    Если ВвестиСтроку(Стр,"Справочник",50)=1 Тогда
        Спр=connection.Справочники.Справочник1.НайтиПоНаименованию(Стр);
        Если Спр.Ссылка=connection.Справочники.Справочник1.ПустаяСсылка() Тогда
            Спр=connection.Справочники.Справочник1.СоздатьЭлемент();
            Спр.Наименование=Стр;
            Спр.Записать();
        КонецЕсли;
        Док=connection.Документы.Документ1.СоздатьДокумент();
        Док.Дата=connection.ЗначениеИзСтрокиВнутр("{""D"",20081231235959}");
        Док.Реквизит1=Спр.Ссылка;
        Док.Записать();
        Движение=Док.Движения.РегистрНакопления1.ДобавитьПриход();
        Движение.Период=connection.ЗначениеИзСтрокиВнутр("{""D"",20081231235959}");
        Движение.Измерение1=Спр.Ссылка;
        Движение.Ресурс1=15;
        Док.Движения.РегистрНакопления1.Записать();
        Сообщить(connection.String(Док.Ссылка));
    КонецЕсли;
    connection = "";
    cntr = "";
КонецФункции

Рассмотрим лог сообщений

Документ1 000000001 от 31.12.2008 0:00:00

Вывод из этого лога прост. Время даже при передаче через ЗначениеИзСтрокиВнутр теряется.

Класс не существует

И в заключение - если выскакивает ошибка с "Класс не существует", значит, что не зарегистрирован COM-объект 1С:Предприятия.

Для регистрации V81.COMConnector необходимо выполнить:
regsvr32 "C:\Program Files\1cv81\bin\comcntr.dll"

Для регистрации V81.Application необходимо выполнить:
"C:\Program Files\1cv81\bin\1cv8.exe" /regserver

http://1cniku.ru/Articles/V8OLE.html

См. также

Перенос данных 1C Программист Платформа 1С v7.7 Платформа 1С v8.3 1С:Торговля и склад 7.7 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 Россия Бухгалтерский учет Управленческий учет Платные (руб)

Обработка позволяет выгружать данные из ТиС 7.7 в конфигурации 8.3 для сдачи отчетности, для переноса данных при переходе на 8.3, для организации обмена внутри компании при использовании разных версий 1С в структурных подразделениях или формирования отгрузочных накладных для клиентов.

6000 руб.

18.05.2020    23474    62    39    

36

Файловый обмен (TXT, XML, DBF), FTP Перенос данных 1C Программист Платформа 1С v8.3 Оперативный учет 7.7 1С:Торговля и склад 7.7 1С:Бухгалтерия 3.0 Бухгалтерский учет Управленческий учет Абонемент ($m)

Обработка и правила обмена данными для выгрузки документов и всех связанных с ними справочников из 1С7.7 ТиС 9.2 в 1С8.3 БП 3.0 через файл XML. В типовых конфигурациях уже есть такое решение. Это немного доработанные правила и сама обработка выгрузки, добавлена возможность устанавливать отбор по выгружаемым документам по Фирме, Контрагенту, Складу, Проекту, Автору, ЮрЛицу. А также это внешняя обработка, что даёт возможность адаптировать её под нетиповую ТиС. Обработка и правила тестировались на платформах: 1С: Предприятие 7.7 и 1С: Предприятие 8.3.18.1334. На типовых конфигурациях: «Торговля + склад», редакция 9.2 (7.70 1004) и «Бухгалтерия предприятия» редакция 3.0 (3.0.96.30).

1 стартмани

13.08.2021    9058    55    Kuzya_brаtsk    8    

11

Перенос данных 1C Программист Платформа 1С v7.7 Платформа 1С v8.3 Платформа 1C v8.2 1С:Управление торговлей 10 1С:Комплексная 7.7 Россия Управленческий учет Платные (руб)

Начните вести учет в УТ 10.3! Перенесите все свои данные в УТ 10.3 в любом месяце года и продолжите вести учет! Программа перенесёт любое количество баз с документами и остатками в больших количествах. Обработка выгрузки выполнит проверку исходных данных и сформирует отчет о найденных ошибках в справочниках и документах. Партии переносятся с себестоимостью. Штрихкоды номенклатуры загружаются. Цена переносится. Автор консультирует.

8400 руб.

17.03.2021    15949    5    13    

6

Зарплата Перенос данных 1C Программист Бухгалтер Бухгалтерский учет 7.7 Сложные периодические расчеты 1С:Бухгалтерия 7.7 1С:Зарплата и Управление Персоналом 3.x Россия Бухгалтерский учет Платные (руб)

Как известно, Бухгалтерия 7.7 не имеет штатной возможности для обмена с ЗУП 3.1. Данная разработка пригодится тем, кто перешел с ЗиК 2.3 на ЗУП 3.1, но вынужден по каким-то своим причинам оставаться на Бухгалтерии 7.7.

18000 руб.

29.09.2020    13774    2    0    

5

SALE! 10%

Файловый обмен (TXT, XML, DBF), FTP Перенос данных 1C Программист Платформа 1С v7.7 Платформа 1С v8.3 1С:Бухгалтерия 7.7 1С:Бухгалтерия 3.0 Россия Бухгалтерский учет Платные (руб)

Перенос данных из 1С:Бухгалтерия 7.7 в БП 3.0 | Продукт является развитием и исправлением ошибок стандартной обработки для выгрузки данных из 1С Бухгалтерии 7.7 в Бухгалтерию 3.0 | Перенос из 7.7 является сложным, и на рынке сложно найти специалистов 1С по "семерке" - сотрудники помогут вам выполнить переход в рамках техподдержки предлагаемого переноса данных!

50722 45650 руб.

26.05.2020    34958    10    72    

16

Перенос данных 1C Программист Платформа 1С v7.7 Платформа 1С v8.3 1С:Конвертация данных Бесплатно (free)

При переходе на новую версию 1С в период параллельной эксплуатации может возникнуть необходимость обратной конвертации данных (по правилам КД версии 2.1) из 1С:Предприятие 8.3 в 1С:Предприятие 7.7 для переноса данных из 1С:Предприятие 8.3 в 7.7. Сделать это поможет следующая инструкция по КД2 о том, как создать новую конвертацию из 8.3 в 7.7, сохранить модуль и правила загрузки данных, сделать загрузку данных. КД2.

17.10.2019    15001    ksnik    0    

16

Файловый обмен (TXT, XML, DBF), FTP Перенос данных 1C Программист Платформа 1С v7.7 Платформа 1С v8.3 1С:Комплексная 7.7 1С:ERP Управление предприятием 2 1С:Комплексная автоматизация 2.х Абонемент ($m)

Разработка позволяет перенести остатки по всем счетам бух. учета из "1С:Комплексная конфигурация, редакция 4.5 (7.7)" в программу "1С:Управление предприятием ERP 2.0", на выбранную дату начала ведения учета. Также переносятся документы за период и вся необходимая справочная информация. Конфигурация "1С:Управление предприятием ERP 2.0" является полностью типовой.

5 стартмани

11.01.2019    15964    39    sulig    14    

13
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
0. artspeed 179 07.04.11 22:43 Сейчас в теме
Решил серьезно заняться изучением OLE. Конечно OLE это не КД, но все же...

Перейти к публикации

1. mirco 74 07.04.11 22:43 Сейчас в теме
Перед тем как публиковать - прочтите вот это
http://infostart.ru/public/66592/
2. artspeed 179 08.04.11 00:53 Сейчас в теме
3. mirco 74 08.04.11 09:52 Сейчас в теме
уже лучше, ну только отступы осталось :D
сейас почитаем.
4. lamer19 54 08.04.11 15:26 Сейчас в теме
Можно мое авторство указать при желании
5. Alraune 1504 08.04.11 15:30 Сейчас в теме
Авторство надо указать обязательно, а не "по желанию"
Necytij; lamer19; +2 Ответить
7. lamer19 54 13.04.11 17:01 Сейчас в теме
(5) Хорошо ссылку на исходный материал дал, так посещаемость сайта резко увеличилась
6. volsh77 17 11.04.11 02:53 Сейчас в теме
У меня все перебросы через ОЛЕ, пытаюсь получше усвоить конвертацию данных :)
8. nafa 661 15.04.11 12:20 Сейчас в теме
[quote]Попалась в интернете хорошая статья и решил ее поместить сюда. Думаю будет полезна как для начинающих, так и для продвинутых, что бы закрепить свои знания.[/quote]
Просто статья, попавшаяся в интернете - это то же самое, что и ОБС (одна баба сказала). Достаточно лишь внимательно посмотреть на ее начало
[quote]Приведу код глобального модуля
#Если Клиент Тогда
Функция ВернутьТипПодключения() Экспорт
Возврат("Клиент");
КонецФункции
#Иначе
Функция ВернутьТипПодключения() Экспорт
Возврат("Сервер");
КонецФункции
#КонецЕсли[/quote]
чтобы предположить, что писал ее "профессиональный писатель" - т.е. человек, зарабатывающий на жизнь написанием книг о предмете, в котором он понятия не имеет. (Каковых среди писателей технической литературы в последнее время, к сожалению, стало большинство).
Во-первых, в 8ке нет "глобального" модуля, есть модули приложения/соединения... и есть общие модули
Во-вторых, в инструкции #Если Клиент и Сервер описывают место выполнения кода а не тип подключения.
В третьих, читая выводы типа
[quote]То есть при обращении через объект V81.ComConnector подключение осуществляется в режиме север, даже если мы подключаемся к локальной файловой базе.[/quote]
думаю что пора учредить приз - 'Серебряную утку' или что-то вроде этого.
Пояснение при вызове через Комконнектор данная функция всегда будет возвращать "Сервер", потому что в ней вообще забыли что кроме 'Клиента' и 'Сервера', есть еще и 'Внешнее соединение'.
Остальную часть комментировать просто времени нет.
9. KHoroshulinAV 174 15.04.11 17:48 Сейчас в теме
ну че тут такого необычного написано? Общеизвестные факты выложили в оч. раз в интернету.
10. internetname 02.12.11 11:22 Сейчас в теме
11. sonuchin3 29.01.12 21:20 Сейчас в теме
Лучший способ проверить работу функций УстановитьИстина(), УстановитьЛожь() - посмотреть, что произошло в каркасной базе. Обращаюсь к 8.2 из 7.7. У меня после выполнения команды:

Base8.Константы.Константа1.Установить(Base8.ЗначениеИзСтрокиВнутр("{""B"",1}"));

- в каркасной базе установилось именно то, что потом возвращается в логе сообщений, т.е. число -1.
Установить же булевское значение Истина удалось только вызывая экспортную функцию общего модуля в 8.2, возвращающую Истина.
Так что для меня вопрос о том, можно ли извне из 7.7 установить булевское значение в 8.2, не прибегая к заранее написанным функциям в конфигурации 8.2, остался открытым.
12. m2d3 20.04.12 14:05 Сейчас в теме
13. Alex1Cnic 150 02.10.13 14:56 Сейчас в теме
хороший ликбез... супер!
15. Arguleon 23.03.17 18:13 Сейчас в теме
Классная статья но как перечисления выгружать не понял.
16. Gennadiy83 24.03.17 00:49 Сейчас в теме
(15) с помощью функции XMLString получаешь строку-значение перечисления и передаешь ее в качестве параметра в функцию. В коде описываешь функцию, где по значению строки возвращаешь требуемое перечисление из базы-приемника.

Например, обработка запускается из БП и подключается к УТ:

НовыйТовар = Справочники.Номенклатура.СоздатьЭлемент();
НовыйТовар.СтавкаНДС = НайтиПеречислениеНДС(УТ.XMLString(Товар.СтавкаНДС));

.......................

Функция НайтиПеречислениеНДС(значениеПеречисления)
      Если значениеПеречисления = "НДС18" Тогда
             Возврат Перечисления.СтавкиНДС.НДС18;
      КонецЕсли;
КонецФункции
Показать


Думаю смысл понятен.
17. Arguleon 24.03.17 08:17 Сейчас в теме
Спасибо большое, да теперь понятно.
Оставьте свое сообщение