1с 83 com соединение передать табличный документ. Три кита работы с COM-объектами

Один из вариантов обмена данными между базами 1С это обмен через COM соединение.

С помощью COM соединения можно из одной базы 1С подключиться к другой и прочитать или записать данные. Пользоваться этим методом можно как в клиент-серверных вариантах баз, так и в файловых базах. В этой статье и разберем примеры такого рода соединений. В примерах используется платформа 8.2.

Можно создать два вида COM объектов для приложения 1С. Это V82.Application и V82.COMConnector . В случае с V82.Application запускается практически полноценный экземпляр приложения 1С. в случае использования V82.COMConnector запускается небольшая серверная часть.
Скорость работы в этом случае выше, но некоторые функции могут быть недоступны. В частности работа с формами и с общими модулями для которых не установлено свойство работы с внешними соединениями. Преимущественно надо использовать V82.COMConnector и только в случае нехватки функционала V82.Application . Особенно сильно разница в скорости работы может быть заметна на базах большого объема.

Итак, приступим

  1. Создадим COM объект
    • для V82.Application Соединение = Новый COMОбъект("V82.Application" ) ;
    • для V82.COMConnector Соединение = Новый COMОбъект("V82.COMConnector" ) ;
  2. Сформируем строку подключения
    • для серверного варианта базы СтрокаСоединения = "Srvr = " "ИмяСервера" ";Ref = " "ИмяБазы" ;
    • для файлового варианта базы СтрокаСоединения = "File = " "ПутьКБазе" "; Usr = ИмяПользователя; Pwd = Пароль" ;
  3. Выполняем подключение к базе Попытка Подключение = Соединение. Connect(СтрокаСоединения) ; Исключение Сообщение = Новый СообщениеПользователю; Сообщение. Текст = + ОписаниеОшибки() ; Сообщение. Сообщить() ; КонецПопытки ;
  4. Разрываем соединение с базой Соединение = Неопределено ;

    Для объекта V82.Application выполнять разрыв соединения обязательно, в противном случае останется висеть незавершенный сеанс, который потом придется удалять вручную. В случае с V82.COMConnector соединение разрывается автоматически при завершении процедуры в которой выполнялось подключение.И есть еще один маленький момент.

    Для пользователя под которым выполняется подключение должен быть отключен флажок «Запрашивать подтверждение при закрытии программы» в его настройках.

А теперь соберем весь код в кучу

Соединение = Новый COMОбъект("V82.Application" ) ; //Соединение = Новый COMОбъект("V82.COMConnector"); СтрокаСоединения = "Srvr = " "Server1C" ";Ref = " "MyBase" "; Usr = Петя; Pwd = 123" ; //СтрокаСоединения = "File = ""С:\MyBase""; Usr = Петя; Pwd = 123"; Попытка Подключение = Соединение. Connect(СтрокаСоединения) ; Исключение Сообщение = Новый СообщениеПользователю; Сообщение. Текст = "Не удалось подключиться к базе" + ОписаниеОшибки() ; Сообщение. Сообщить() ; КонецПопытки ; Соединение = Неопределено ;

Для вида подключения V82.Application метод применяется для COM объекта, который создавался изначально, а для V82.COMConnector метод применяется к подключению. далее работа с запросом идет стандартными средствами 1С. в коде это выглядит так:

Запрос = Подключение. NewObject("Запрос" ) ; // для V82.COMConnector Запрос = Соединение. NewObject("Запрос" ) ; // для V82.Application Запрос. Текст = "ВЫБРАТЬ | ДолжностиОрганизаций.Код, | ДолжностиОрганизаций.Наименование |ИЗ | Справочник.ДолжностиОрганизаций КАК ДолжностиОрганизаций" ; Результат = Запрос. Выполнить () ; Выборка = Результат. Выбрать() ; Пока Выборка. Следующий() Цикл КонецЦикла ;

Для версии 1С:Предприятие 8.3 все остается без изменений за исключением того, что при создании COMОбъектов надо использовать «V83.COMConnector» или «V83.Application» .

Одним из способов перенести данные из одной конфигурации 1С в другую является программное подключение с помощью COM. Многие компании используют несколько различных баз, между которыми должны быть определенные связи и зависимости. Если необходимо не только перенести данные, но и выполнить определенную обработку данных, то COM соединение будет оптимальным механизмом. Умение анализировать данные из другой базы 1С пригодиться любому разработчику.

Подключаемся через COM к базе 1С

Для реализации COM соединения в 1С используется специальный механизм под названием COMConnector. Этот объект устанавливается вместе с платформой и применяется для связи информационных баз. Следует учесть, что для версий 8.2 и 8.3 используются разные по наименованию объекты – «V82.COMConnector» и «V83.COMConnector» соответственно.

Помните, что на время COM соединения к базе тратиться лицензия – не стоит увлекаться одновременным выполнением нескольких подключений. Особенно это важно для организаций, у которых количество лицензий ограничено. Решиться этот вопрос может при помощи регламентных заданий, выполняющихся во время отсутствия активных подключений пользователей к информационной базе.

Чтобы иметь возможность подключиться к другой базе и запросить нужную информацию вы должны знать следующие данные:

  1. Какого она типа – файловая или клиент-серверная;
  2. Где она располагается;
  3. Под каким именем и паролем в нее можно зайти;
  4. Какие данные вас интересуют.

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

ПараметрыПодключенияФайловойИБ = "Filе=""Путь_к_базе""; Usr=""Имя_пользователя"";Pwd=""Пароль"""; ПараметрыПодключенияКлиентСервернойИБ = "Srvr=""Имя_Сервера""; Ref=""Имя_базы""; Usr=""Имя_пользователя""; Pwd=""Пароль""";

Функция подключения проста и не должна вызвать вопросов, если все параметры указаны верно. Для ускорения отладки и анализа возможных ошибок лучше заключить подключение в конструкцию «Попытка». Возвращать функция будет значение типа «COM объект», с которым и предстоит работать, получая нужные данные.

&НаСервере Функция ПодключитьсяКбазе() экспорт ПараметрыПодключенияИБ = "Filе=""Е:\базы 1с\ЕRР""; Usr=""Администратор"";Pwd=""1"""; V83COMCon= Новый СОMОбъект("V83.COMConnector"); Попытка Возврат V83COMCon.Connect(ПараметрыПодключенияИБ); Исключение Сообщить(ОписаниеОшибки()); Возврат Неопределено; КонецПопытки; КонецФункции

Через COM соединение вы можете не только выбирать данные, но и добавлять их в базу, к которой подключаетесь. Помните, что передавать через COM объект мы можем 4 примитивных типа данных. Другие типы придется задавать с помощью встроенных в платформу функций поиска. Учтите, что глобальные функции платформы вызываются тоже через COM-соединение.

Получаем данные из базы 1С

После того как получили нужный объект, необходимо прочитать данные из другой базы. Для этого мы применяем запрос через COM соединение в 1С 8.3 с помощью полученного значения типа «COM объект» из функции. Важно сначала подключиться к базе, а затем уже выполнять запрос. Выполнение происходит через метод NewObject с указанием в качестве параметра типа объекта в строковом виде – «Запрос».

&НаСервере Процедура ТестСОMНаСервере() Соединение = ПодключитьсяКбазе(); Если ТипЗнч(Соединение) Тип("Неопределено") Тогда ЗапросБПЗО = Соединение.NewObject("Запрос"); ЗапросБПЗО.Текст = "ВЫБРАТЬ первые 15 | СправочникПольз.Наименование КАК Наименование |ИЗ | Справочник.пользователи КАК СправочникПольз"; Выборка = ЗапросБПЗО.Выполнить().выбрать(); Пока Выборка.следующий() цикл Сообщить(Выборка.Номер); КонецЦикла; КонецЕсли; КонецПроцедуры >

К примеру, чтобы получить информацию о пользователях определенного подразделения, зададим условие в запрос через параметры. Один параметр будет простого типа – строка, а подразделение – ссылкой элемента справочника «Структура предприятия». Результат запроса является таблицей с перечисленными полями того типа, какого они существуют в базе, к которой произошло COM соединение. Если необходимо их преобразовать в другие типы – воспользуйтесь стандартными функциями платформы:

  • Строка();
  • Число();
  • Дата().
ЗапросБПЗО = Соединение.NewObject("Запрос"); ЗапросБПЗО.Текст = "ВЫБРАТЬ первые 15 | СправочникПольз.Наименование КАК Наименование |ИЗ | Справочник.Пользователи КАК СправочникПольз I ГДЕ | СправочникПольз.Подразделение = &НужноеПодразделение | И СправочникПольз.Наименование подобно ""%"" + &НужноеИмя+ ""%"""; ЗапросБПЗО.УстановитьПараметр("НужноеПодразделение",Соединение.Справочники.СтруктураПредприятия.НайтиПоКоду("00-000023")); ЗапросБПЗО.УстановитьПараметр("НужноеИмя","Екатерина"); Выборка = ЗапросБПЗО.Выполнить().выбрать(); Пока Выборка.следующий() цикл Сообщить(Выборка.Наименование); КонецЦикла;

Если нужно передать в базу массив для отбора по нескольким параметрам, например, подразделениям, тоже используется команда NewObject. Аналогично можно передавать список или таблицу значений, заполняя их элементами другой базы через соединение. Для поиска вам доступны все существующие методы объектов и механизмов платформы.

ЗапросБПЗО = Соединение.NewObject.("Запрос"); ЗапросБПЗО.Текст = "ВЫБРАТЬ первые 15 | СправочникПольз.Наименование КАК Наименование | ИЗ | Справочник.Пользователи КАК СправочникПольз I ГДЕ | СправочникПольз.Подразделение В (&НужноеПодразделение) | И СправочникПольз.Наименование подобно ""%"" + &НужноеИмя+ ""%"""; МассивПодразделений = Соединение.NewObject("Массив"); МассивПодразделений.Добавить(Соединение.Справочники.СтруктураПредприятия.НайтиПоКоду("00-000023")); МассивПодразделений.Добавить(Соединение.Справочники.СтруктураПредприятия.НайтиПоКоду("00-000038")); МассивПодразделений.Добавить(Соединение.Справочники.СтруктураПредприятия.НайтиПоКоду("00-000046")); ЗапросБПЗО.УстановитьПараметр("НужноеПодразделение", МассивПодразделений); ЗапросБПЗО.УстановитьПараметр("НужноеИмя","Екатерина"); Выборка = ЗапросБПЗО.Выполнить().выбрать(); Пока Выборка.следующий() цикл Сообщить(Выборка.Наименование); КонецЦикла;

При переносе документов или элементов справочников всегда возникает вопрос о контроле переноса определенного объекта. С помощью COM соединений можно решить подобные проблемы через уникальный идентификатор. Нужно найти объект в подключаемой базе по идентификатору из текущей ИБ с помощью функции «ПолучитьСсылку», используя идентификатор в виде строки. Если такового не нашлось, вы можете создать его с помощью COM соединения.

СтрИдент = Строка(Справочники.Пользователи.НайтиПоКоду("00-0000313").УникальныйИдентификатор()); Если НЕ ЗначениеЗаполнено(Соединение.Справочники.Пользователи.ПолучитьСсылку(Соединение.NewObject("УникальныйИдентификатор", СтрИдент))) тогда НовыйПользователь = Соединение.Справочники.Пользователи.СоздатьЭлемент(); НовыйПользователь.Наименование = Справочники.Пользователи.НайтиПоКоду("00-0000313").Наименование; НовыйПользователь.ФизическоеЛицо = Справочники.Пользователи.НайтиПоКоду("00-0000313").ФизическоеЛицо; НовыйПользователь.Записать(); КонецЕсли;

Также COM соединение имеет право использовать процедуры и функции из общих модулей 1С с включенным свойством «Внешнее соединение». Кроме этого условия, вызываемая функция или процедура должна быть экспортная и не включать интерактивные действия, выполняемые на сервере. В противоположном случае вы увидите ошибку о недопустимости операции.

Соединение..; ПеременнаяИзФункции = Соединение..; вызовфункции>имяобщегомодуля>вызовпроцедуры>имяобщегомодуля>

Возможности внешнего соединения с другой базой в 1С достаточно обширны и могут позволить выполнить множество задач. Важно уметь правильно оценить инструментарий и выбрать оптимальное решение. В большинстве случаев это умение появляется лишь с опытом или изучая примеры работ опытных специалистов.

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

  • левое;
  • правое,
  • внутреннее;
  • полное.

Каждый тип мы рассмотрим на абстрактном примере. Имеется 2 таблицы, в первой храним описательную информацию о номенклатуре, во второй о ее остатках:

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

Левое соединение

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

Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Товар,
| Номенклатура.Цвет КАК ЦветНоменклатура,
| Остатки.Цвет КАК ЦветОстатки,
| Остатки.Количество
|ИЗ

";

Для стула не нашлось сопоставлений из таблицы остатков, поэтому поля заполнились значениями NULL, которые обязательно нужно обработать функцией ЕСТЬNULL, см. Функции языка запросов 1С 8.

Левое соединение работает примерно как цикл в цикле - берется первая запись из левой таблицы и пробегаются все записи из правой на предмет удовлетворения условию связи. Затем берется вторая запись из левой таблицы и т.д. Если вдруг условию связи удовлетворяют несколько записей из правой таблицы, то в результирующую таблицу будет добавлено несколько строк (по количеству удачных связей).Как видим, полученная таблица не информативна, данные не отражают реальную суть, поэтому лучше связать эти таблицы по двум полям: Товар и Цвет, только на этот раз обработаем NULLы:

Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Товар,
| Номенклатура.Цвет,
| ЕСТЬNULL(Остатки.Количество, 0) КАК Количество
|ИЗ
| Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ Остатки КАК Остатки
| ПО Номенклатура.Товар = Остатки.Товар

Правое соединение

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

Внутреннее соединение

Используя внутреннее соединение мы говорим системе, что в результате хотим видеть только те записи, которые удовлетворяют условию связи как из правой таблицы, так и из левой. Таким образом, количество результирующих записей будет меньше или равно количеству записей самой "короткой таблицы", участвующей в соединении. Применим внутреннее соединение к полям Товар и Цвет наших таблиц:

Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Товар,
| Номенклатура.Цвет,
| Остатки.Количество КАК Количество
|ИЗ
| Номенклатура КАК Номенклатура
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Остатки КАК Остатки
| ПО Номенклатура.Товар = Остатки.Товар
| И Номенклатура.Цвет = Остатки.Цвет";

Полное соединение

Полное соединение передаст в результат все записи из обоих таблиц, те записи, которые удовлетворяет условию связи - будут связаны, те записи, которые не удовлетворяют условию связи все равно окажутся в результате запроса, но с частью NULLовых полей. Полное это как бы левое и правое соединения в одном.

Задач на эту тему может быть много, давайте попробуем решить одну из них. Наша организация является дилером 2 мебельных фабрик: "Заря" и "Рассвет". Ассортимент со стоимостью каждой из фабрик хранится в разных таблицах. Необходимо составить единый прайс лист, причем брать в него продукцию по минимальной цене:

Применим полное соединение с выборкой всех полей, связывать будем по товару:

Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураЗаря.Товар КАК ТоварЗаря,
| НоменклатураЗаря.Цена КАК ЦенаЗаря,
| НоменклатураРассвет.Товар КАК ТоварРассвет,
| НоменклатураРассвет.Цена КАК ЦенаРассвет
|ИЗ

Это не совсем то, что нам нужно, давайте соединим поле товар в одно и обработаем NULLы:

Запрос.Текст =
"ВЫБРАТЬ
//конструкция ЕСТЬNULL рассматривалась в разделе функции языка запросов
//если цена не определена, то инициализируем ее
//почему 1000000 см. пояснения ниже
| ЕСТЬNULL(НоменклатураЗаря.Цена, 1000000) КАК ЦенаЗаря,
| ЕСТЬNULL(НоменклатураРассвет.Цена, 1000000) КАК ЦенаРассвет
|ИЗ
| НоменклатураЗаря КАК НоменклатураЗаря
| ПОЛНОЕ СОЕДИНЕНИЕ НоменклатураРассвет КАК НоменклатураРассвет
| ПО НоменклатураЗаря.Товар = НоменклатураРассвет.Товар";

Осталось только выбрать минимальную цену. Итоговый тект запроса будет выглядеть следующим образом:

Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(НоменклатураЗаря.Товар, НоменклатураРассвет.Товар) КАК Товар,
| ВЫБОР
| КОГДА ЕСТЬNULL(НоменклатураЗаря.Цена, 1000000) > ЕСТЬNULL(НоменклатураРассвет.Цена, 1000000)
| ТОГДА ЕСТЬNULL(НоменклатураРассвет.Цена, 1000000)
| ИНАЧЕ ЕСТЬNULL(НоменклатураЗаря.Цена, 1000000)
| КОНЕЦ КАК Цена
|ИЗ
| НоменклатураЗаря КАК НоменклатураЗаря
| ПОЛНОЕ СОЕДИНЕНИЕ НоменклатураРассвет КАК НоменклатураРассвет
| ПО НоменклатураЗаря.Товар = НоменклатураРассвет.Товар";

Если цена не определена (NULL), то ее необходимо инициализировать каким либо значением, иначе операция сравнения на больше/меньше вывалится с ошибкой. инициализируем цену нереально большой суммой, чтобы она "проиграла" в операции сравнения, ведь по условию задачи мы подбираем наименьшую цену.

← Функции языка запросов 1C 8 | Объединения в запросах 1С 8 →

Печать (Ctrl+P)

Один из вариантов обмена данными между базами 1С это обмен через COM соединение. С помощью COM соединения можно из одной базы 1С подключиться к другой и прочитать или записать данные. Пользоваться этим методом можно как в клиент-серверных вариантах баз, так и в файловых базах. В этой статье рассматривается такого рода соединений на платформа 8.3

com соединение

Можно создать два вида COM объектов для приложения 1С. Это ole соединения V83.Application и com соединения V83.COMConnector . В случае с V83.Application запускается практически полноценный экземпляр приложения 1С. В случае использования V83.COMConnector запускается небольшая серверная часть. Скорость работы в этом случае выше, но некоторые функции могут быть недоступны. В частности работа с формами и с общими модулями для которых не установлено свойство работы с внешними соединениями. Преимущественно надо использовать V83.COMConnector и только в случае нехватки функционала V83.Application . Особенно сильно разница в скорости работы может быть заметна на базах большого объема. Для платформе 8.2 используется V82.Application или V82.COMConnector

Установить OLE соединение

Соединение = Новый COMОбъект(“V83.Application” ) ;

Установить COM соединение

Соединение = Новый COMОбъект(“V83.COMConnector” ) ;

Строка подключения

//Для варианта клиент- сервер
СтрокаСоединения = “Srvr = “ “ИмяСервера” “;Ref = “ “ИмяБазы” ;
//Для варианта файлового режима:
СтрокаСоединения = “File = “ “ПутьКБазе” “; Usr = ИмяПользователя; Pwd = Пароль” ;
Попытка
Подключение = Соединение. Connect (СтрокаСоединения) ;
Исключение
Сообщение = Новый СообщениеПользователю;
Сообщение. Текст = “Не удалось подключиться к базе” + ОписаниеОшибки() ; Сообщение. Сообщить() ;
КонецПопытки ;

Разрыв соединения

Соединение = Неопределено ;
Для объекта V83.Application выполнять разрыв соединения обязательно, в противном случае останется висеть незавершенный сеанс, который потом придется удалять вручную. В случае с V83.COMConnector соединение разрывается автоматически при завершении процедуры в которой выполнялось подключение.И есть еще один маленький момент. Для пользователя под которым выполняется подключение должен быть отключен флажок «Запрашивать подтверждение при закрытии программы» в его настройках.

Метод NewObject()

Для создания нового объекта можно воспользоваться методом NewObject(), например:

для V83.COMConnector

ЗапросCOM = Подключение. NewObject(“Запрос “ ) ;
ТаблицаCOM = Подключение. NewObject(“ТаблицаЗначений” ) ;
МассивCOM = Подключение. NewObject(“Массив” ) ;

УидCOM =Подключение.NewObject

для V83.Application

ЗапросOLE = Соединение. NewObject(“Запрос “ ) ;
ТаблицаOLE = Соединение. NewObject (“ТаблицаЗначений” ) ;
МассивOLE = Соединение.NewObject (“Массив” ) ;
УидCOM =Соединение.NewObject (“УникальныйИдентификатор”,СтрокаУИД);

ЗапросCOM. Текст = “ВЫБРАТЬ
| ДолжностиОрганизаций.Код,
| ДолжностиОрганизаций.Наименование
|ИЗ | Справочник.ДолжностиОрганизаций
КАК ДолжностиОрганизаций” ;

Результат = ЗапросCOM. Выполнить () ;
Выборка = Результат. Выбрать () ;
Пока Выборка. Следующий() Цикл
КонецЦикла ;
Можно также использовать менеджеры объектов конфигурации:
СправочникCOM = Подключение. Справочники. ИмяСправочника;
ДокументCOM = Подключение. Документы. ИмяДокумента;
РегистрCOM = Подключение . РегистрыСведений . ИмяРегистра ;

Получение и сравнение перечисления через COM соединение

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

ЭлементПеречисления = Подключение.Справочники.Справочник1.НайтиПоКоду(1).Реквизит1;

ВозможныеЗначения = ЭлементПеречисления.Метаданные().ЗначенияПеречисления;

НомерЭлементаПеречисления = ВозможныеЗначения.Индекс(ВозможныеЗначения.Найти(Соединение.XMLString(ЭлементПеречисления)));

Если НомерЭлементаПеречисления = 0 Тогда Сообщить(“ЗначениеПеречисления1” );

ИначеЕсли НомерЭлементаПеречисления = 1 Тогда Сообщить (“ЗначениеПеречисления2”);

КонецЕсли;

Получение объекта через COM по идентификатору

Через менеджеры объектов конфигурации получаем com объект, например:
ДокументCOM = Соединение. Документы. ИмяДокумента;

Затем получаем строку уникального идентификатора:

СтрокаУИД =Соединение.string (ДокументCOM.УникальныйИдентификатор ())

Идентификатор = Новый УникальныйИдентификатор(СтрокаУИД) ;
СсылкаПоИдентификатору = Документы[ИмяДокумента].ПолучитьСсылку(Идентификатор);

Если нужно найти com объект по документ по идентификатору, то тогда нужно написать так:

УидCOM = Соединение.NewObject (“УникальныйИдентификатор”,СтрокаУИД );
СсылкаПоИдентификатору = Соединение.Документы[ИмяДокумента].ПолучитьСсылку(УидCOM);