При написании обработок обмена между конфигурациями 1С часто возникает необходимость определения типа принимаемых данных справочник, документ, ПланСчетов или т.д. Эта информация разбросана по интернету но я решил систематизировать и показать Вам.
Для подключения и работы с ком соединением рекомендуется объявить переменную к которой будет подствлено значение соединение и проверять на данное подключение в каждой процедуре, ниже приведен текст процедуры/функции и способы подключения в конфигурациях
СтруктураПодключения — эта переменная в которой имеется Строка соединения с СОМ объектом
Перем Коннект;
Процедура ПолучитьИмяКонфигурацииИсточника()
Если Коннект = Неопределено Тогда Если Не ПодключитьИБ() Тогда Сообщить("Не удалось установить подключение к ИБ!!!"); Возврат ; КонецЕсли; КонецЕсли;
Если Коннект.Метаданные.DetailedInformation = "Бухгалтерия предприятия, редакция 2.0"
ИЛИ Коннект.Метаданные.DetailedInformation = "1С:Учет в управляющих компаниях ЖКХ, ТСЖ и ЖСК"
ИЛИ Коннект.Метаданные.DetailedInformation = "Бухгалтерия строительной организации, редакция 2.0" ТОгда
ИмяКонфигурацииИсточника = "БП20";
ИначеЕсли Коннект.Метаданные.DetailedInformation = "Комплексная автоматизация, редакция 1.1" ТОгда
ИмяКонфигурацииИсточника = "КА11";
Иначе
ИмяКонфигурацииИсточника = "БП30";
КонецЕсли;
КонецПроцедуры
Функция ПодключитьИБ(СтруктураПодключения = Неопределено) Экспорт
//Открыта = Ложь;
Если Не СтруктураПодключения = Неопределено Тогда
СтруктураНастроек = СтруктураПодключения;
Иначе
СтруктураНастроек = Новый Структура("COMАутентификацияОперационнойСистемы,COMВариантРаботыИнформационнойБазы,COMИмяИнформационнойБазыНаСервере1СПредприятия,COMИмяПользователя,COMИмяСервера1СПредприятия,COMКаталогИнформационнойБазы,COMПарольПользователя",COMАутентификацияОперационнойСистемы,COMВариантРаботыИнформационнойБазы,COMИмяИнформационнойБазыНаСервере1СПредприятия,COMИмяПользователя,COMИмяСервера1СПредприятия,COMКаталогИнформационнойБазы,COMПарольПользователя);
КонецЕсли;
Результат = УстановитьВнешнееСоединениеСБазойCOM(ЗаполнитьПараметрыПодключенияВнешнегоСоединения(СтруктураНастроек));
Коннект = Результат.Соединение;
Если Коннект = Неопределено Тогда
// Ошибка установки соединения.
Сообщить("" + Результат.КраткоеОписаниеОшибки + ". " + Результат.ПодробноеОписаниеОшибки);
Возврат Ложь;
Иначе
Если Не ЗначениеЗаполнено(ИмяКонфигурацииИсточника) Тогда
ПолучитьИмяКонфигурацииИсточника();
КонецЕсли;
Возврат Истина;
КонецЕсли;
//Возврат Открыта;
КонецФункции
// Возвращает шаблон структуры параметров для установки внешнего соединения.
// Параметрам необходимо задать требуемые значения и передать.
// В метод ОбщегоНазначения.УстановитьВнешнееСоединение().
//
Функция СтруктураПараметровДляУстановкиВнешнегоСоединения() Экспорт
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("ВариантРаботыИнформационнойБазы", 0);
СтруктураПараметров.Вставить("КаталогИнформационнойБазы", "");
СтруктураПараметров.Вставить("ИмяСервера1СПредприятия", "");
СтруктураПараметров.Вставить("ИмяИнформационнойБазыНаСервере1СПредприятия", "");
СтруктураПараметров.Вставить("АутентификацияОперационнойСистемы", Ложь);
СтруктураПараметров.Вставить("ИмяПользователя", "");
СтруктураПараметров.Вставить("ПарольПользователя", "");
Возврат СтруктураПараметров;
КонецФункции
Функция ЗаполнитьПараметрыПодключенияВнешнегоСоединения(НастройкиТранспорта)
ПараметрыПодключения = СтруктураПараметровДляУстановкиВнешнегоСоединения();
ПараметрыПодключения.ВариантРаботыИнформационнойБазы = НастройкиТранспорта.COMВариантРаботыИнформационнойБазы;
ПараметрыПодключения.КаталогИнформационнойБазы = НастройкиТранспорта.COMКаталогИнформационнойБазы;
ПараметрыПодключения.ИмяСервера1СПредприятия = НастройкиТранспорта.COMИмяСервера1СПредприятия;
ПараметрыПодключения.ИмяИнформационнойБазыНаСервере1СПредприятия = НастройкиТранспорта.COMИмяИнформационнойБазыНаСервере1СПредприятия;
ПараметрыПодключения.АутентификацияОперационнойСистемы = НастройкиТранспорта.COMАутентификацияОперационнойСистемы;
ПараметрыПодключения.ИмяПользователя = НастройкиТранспорта.COMИмяПользователя;
ПараметрыПодключения.ПарольПользователя = НастройкиТранспорта.COMПарольПользователя;
Возврат ПараметрыПодключения;
КонецФункции
Функция ИмяCOMСоединителя()
Если ПодключенияВариант = Неопределено ТОгда
Какая8 = СтрЗаменить(COMПодключенияВариант, ".", "");
Иначе
Какая8 = СтрЗаменить(ПодключенияВариант, ".", "");
КонецЕсли;
Возврат "v" + Какая8 + ".COMConnector";
КонецФункции
// Устанавливает внешнее соединение с информационной базой по переданным параметрам подключения и возвращает указатель
// на это соединение.
//
// Параметры:
// Параметры - Структура - параметры для установки внешнего соединения с информационной базой.
// Свойства см. в функции
// ОбщегоНазначенияКлиентСервер.СтруктураПараметровДляУстановкиВнешнегоСоединения):
//
// * ВариантРаботыИнформационнойБазы - Число - Вариант работы информационной базы: 0 - файловый; 1 -
// клиент-серверный;
// * КаталогИнформационнойБазы - Строка - Каталог информационной базы для файлового режима работы;
// * ИмяСервера1СПредприятия - Строка - Имя сервера1С:Предприятия;
// * ИмяИнформационнойБазыНаСервере1СПредприятия - Строка - Имя информационной базы на сервере1С:Предприятия;
// * АутентификацияОперационнойСистемы - Булево - Признак аутентификации операционной системы при создании
// внешнего подключения к информационной базе;
// * ИмяПользователя - Строка - Имя пользователя информационной базы;
// * ПарольПользователя - Строка - Пароль пользователя информационной базы.
//
// Возвращаемое значение:
// Структура -
// * Соединение - COMОбъект, Неопределено - указатель на COM-объект соединения или Неопределено в
// случае ошибки;
// * КраткоеОписаниеОшибки - Строка - краткое описание ошибки;
// * ПодробноеОписаниеОшибки - Строка - подробное описание ошибки;
// * ОшибкаПодключенияКомпоненты - Булево - флаг ошибки подключения COM.
//
Функция УстановитьВнешнееСоединениеСБазойCOM(Параметры) Экспорт
Результат = Новый Структура;
Результат.Вставить("Соединение");
Результат.Вставить("КраткоеОписаниеОшибки", "");
Результат.Вставить("ПодробноеОписаниеОшибки", "");
Результат.Вставить("ОшибкаПодключенияКомпоненты", Ложь);
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
ЭтоLinux = ОбщегоНазначения.ЭтоLinuxСервер();
КраткоеОписаниеОшибки = НСтр("ru = 'Прямое подключение к информационной базе недоступно на сервере под управлением ОС Linux.'");
#Иначе
ЭтоLinux = ЭтоLinuxКлиент();
КраткоеОписаниеОшибки = НСтр("ru = 'Прямое подключение к информационной базе недоступно на клиенте под управлением ОС Linux.'");
#КонецЕсли
Если ЭтоLinux Тогда
Результат.Соединение = Неопределено;
Результат.КраткоеОписаниеОшибки = КраткоеОписаниеОшибки;
Результат.ПодробноеОписаниеОшибки = КраткоеОписаниеОшибки;
Возврат Результат;
КонецЕсли;
Попытка
COMConnector = Новый COMObject(ИмяCOMСоединителя()); // "V83.COMConnector"
Исключение
Информация = ИнформацияОбОшибке();
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не удалось подключится к другой программе: %1'");
Результат.ОшибкаПодключенияКомпоненты = Истина;
Результат.ПодробноеОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщенияОбОшибке, ПодробноеПредставлениеОшибки(Информация));
Результат.КраткоеОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщенияОбОшибке, КраткоеПредставлениеОшибки(Информация));
Возврат Результат;
КонецПопытки;
ФайловыйВариантРаботы = Параметры.ВариантРаботыИнформационнойБазы = 0;
// Проверка корректности указания параметров.
ОшибкаПроверкиЗаполнения = Ложь;
Если ФайловыйВариантРаботы Тогда
Если ПустаяСтрока(Параметры.КаталогИнформационнойБазы) Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не задано месторасположение каталога информационной базы.'");
ОшибкаПроверкиЗаполнения = Истина;
КонецЕсли;
Иначе
Если ПустаяСтрока(Параметры.ИмяСервера1СПредприятия) Или ПустаяСтрока(Параметры.ИмяИнформационнойБазыНаСервере1СПредприятия) Тогда
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не заданы обязательные параметры подключения: ""Имя сервера""; ""Имя информационной базы на сервере"".'");
ОшибкаПроверкиЗаполнения = Истина;
КонецЕсли;
КонецЕсли;
Если ОшибкаПроверкиЗаполнения Тогда
Результат.ПодробноеОписаниеОшибки = СтрокаСообщенияОбОшибке;
Результат.КраткоеОписаниеОшибки = СтрокаСообщенияОбОшибке;
Возврат Результат;
КонецЕсли;
// Формирование строки соединения.
ШаблонСтрокиСоединения = "[СтрокаБазы][СтрокаАутентификации]";
Если ФайловыйВариантРаботы Тогда
СтрокаБазы = "File = ""&КаталогИнформационнойБазы""";
СтрокаБазы = СтрЗаменить(СтрокаБазы, "&КаталогИнформационнойБазы", Параметры.КаталогИнформационнойБазы);
Иначе
СтрокаБазы = "Srvr = ""&ИмяСервера1СПредприятия""; Ref = ""&ИмяИнформационнойБазыНаСервере1СПредприятия""";
СтрокаБазы = СтрЗаменить(СтрокаБазы, "&ИмяСервера1СПредприятия", Параметры.ИмяСервера1СПредприятия);
СтрокаБазы = СтрЗаменить(СтрокаБазы, "&ИмяИнформационнойБазыНаСервере1СПредприятия", Параметры.ИмяИнформационнойБазыНаСервере1СПредприятия);
КонецЕсли;
Если Параметры.АутентификацияОперационнойСистемы Тогда
СтрокаАутентификации = "";
Иначе
Если СтрНайти(Параметры.ИмяПользователя, """") Тогда
Параметры.ИмяПользователя = СтрЗаменить(Параметры.ИмяПользователя, """", """""");
КонецЕсли;
Если СтрНайти(Параметры.ПарольПользователя, """") Тогда
Параметры.ПарольПользователя = СтрЗаменить(Параметры.ПарольПользователя, """", """""");
КонецЕсли;
СтрокаАутентификации = "; Usr = ""&ИмяПользователя""; Pwd = ""&ПарольПользователя""";
СтрокаАутентификации = СтрЗаменить(СтрокаАутентификации, "&ИмяПользователя", Параметры.ИмяПользователя);
СтрокаАутентификации = СтрЗаменить(СтрокаАутентификации, "&ПарольПользователя", Параметры.ПарольПользователя);
КонецЕсли;
СтрокаСоединения = СтрЗаменить(ШаблонСтрокиСоединения, "[СтрокаБазы]", СтрокаБазы);
СтрокаСоединения = СтрЗаменить(СтрокаСоединения, "[СтрокаАутентификации]", СтрокаАутентификации);
Попытка
Результат.Соединение = COMConnector.Connect(СтрокаСоединения);
Исключение
Информация = ИнформацияОбОшибке();
СтрокаСообщенияОбОшибке = НСтр("ru = 'Не удалось подключиться к другой программе: %1'");
Результат.ОшибкаПодключенияКомпоненты = Истина;
Результат.ПодробноеОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщенияОбОшибке, ПодробноеПредставлениеОшибки(Информация));
Результат.КраткоеОписаниеОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(СтрокаСообщенияОбОшибке, КраткоеПредставлениеОшибки(Информация));
КонецПопытки;
Возврат Результат;
КонецФункции
// Основная функция для использования внешнего соединения при обмене.
//
// Параметры:
// СтруктураНастроек - структура настроек транспорта COM обмена.
//
Функция УстановитьВнешнееСоединениеСБазой(СтруктураНастроек) Экспорт
Результат = УстановитьВнешнееСоединениеСБазойCOM(ЗаполнитьПараметрыПодключенияВнешнегоСоединения(СтруктураНастроек));
ВнешнееСоединение = Результат.Соединение;
Если ВнешнееСоединение = Неопределено Тогда
// Ошибка установки соединения.
Возврат Результат;
КонецЕсли;
// Дополнительно проверяем возможность работы с внешней базой.
Попытка
НетПолныхПрав = Не ВнешнееСоединение.ОбменДаннымиВнешнееСоединение.РольДоступнаПолныеПрава();
Исключение
НетПолныхПрав = Истина;
КонецПопытки;
Если НетПолныхПрав Тогда
Результат.ПодробноеОписаниеОшибки = НСтр("ru = 'Пользователю, указанному для подключения к другой программе, должны быть назначены роли ""Администратор системы"" и ""Полные права""'");
Результат.КраткоеОписаниеОшибки = Результат.ПодробноеОписаниеОшибки;
Результат.Соединение = Неопределено;
Иначе
Попытка
СостояниеНеДопустимо = ВнешнееСоединение.ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы();
Исключение
СостояниеНеДопустимо = Ложь
КонецПопытки;
Если СостояниеНеДопустимо Тогда
Результат.ПодробноеОписаниеОшибки = НСтр("ru = 'Другая программа находится в состоянии обновления.'");
Результат.КраткоеОписаниеОшибки = Результат.ПодробноеОписаниеОшибки;
Результат.Соединение = Неопределено;
КонецЕсли;
КонецЕсли;
Возврат Результат;
КонецФункции
Часто возникает необходимость проверка наличия реквизита или свойства объекта, при этом понятия не имееш есть данный реквизит или нет
но использование Попытки .. Исключение .. КонецПопытки не желательно то в даном варианте можно использовать подстановку реквизита в структуру
и тем самым использовать следующую процедуру:
// Проверяет наличие реквизита или свойства у произвольного объекта без обращения к метаданным.
//
// Параметры:
// Объект - Произвольный - объект, у которого нужно проверить наличие реквизита или свойства;
// ИмяРеквизита - Строка - имя реквизита или свойства.
//
// Возвращаемое значение:
// Булево.
//
Функция ЕстьРеквизитИлиСвойствоОбъекта(Объект, ИмяРеквизита) Экспорт
КлючУникальности = Новый УникальныйИдентификатор;
СтруктураРеквизита = Новый Структура(ИмяРеквизита, КлючУникальности);
ЗаполнитьЗначенияСвойств(СтруктураРеквизита, Объект);
Возврат СтруктураРеквизита[ИмяРеквизита] <> КлючУникальности;
КонецФункции
Теперь вопрос который многих интересует: "Мы получили СОМ объект тоесть ТИП("СомОбъект"), какое значение и что с ним делать?
для этого приходят метаданные и мы можем получить любую информацию используя метаданные не только текущей конфигурации, но и конфигурации источника к примеру РеквCOM это реквизит который мы должны изучить:
_СтрокаXML = Коннект.XMLString(РеквCOM); // УникальныйИдентификатор объекта
УИД объекта имеет определенный формат даных поэтому для выяснения что мы имеем то необходимо доп проверка
т.к. _СтрокаXML имеет формат "00000000-0000-0000-0000-000000000000" то актуальна проверка
Если СтрНайти(_СтрокаXML, "-", , , 4) = 24 Тогда //Всего скорее это ГУИД
//***********
ИначеЕсли СтрДлина(_СтрокаXML) = 48 Тогда //Хранилище значения
//************
Иначе //Перечисление
//************
КонецЕсли;
Рассмотрим что можно получить от объекта если по нему есть УИД
_ПолныйТипОбъекта = РеквCOM.GetObject().Metadata().FullName();
СтрокиТипа = СтрЗаменить(_ПолныйТипОбъекта, ".", Символы.ПС);
_ТипОбъекта = СтрПолучитьСтроку(СтрокиТипа, 1);
_ИдентификаторCOM = СтрПолучитьСтроку(СтрокиТипа, 2);
//Для получения менеджера объекта нужно воспользоваться доп процедурой
_МенеджерОбъекта = ПолучитьМенеджерОбъекта(_ИдентификаторCOM);
Функция ПолучитьМенеджерОбъекта(СсылкаОб) Экспорт
Если ТипЗнч(СсылкаОб) = Тип("Строка") Тогда
СсылкаПоиска = _ПолучитьПустуюСсылкуПоИдентификаторуОбъекта(СсылкаОб);
Иначе
СсылкаПоиска = СсылкаОб;
КонецЕсли;
//Попытка
Если СсылкаПоиска <> Неопределено Тогда
ИмяОбъекта = СсылкаПоиска.Метаданные().Имя;
Иначе
Возврат Неопределено;
КонецЕсли;
//Исключение
// Возврат Неопределено;
//КонецПопытки;
ТипСсылки = ТипЗнч(СсылкаПоиска);
Если Справочники.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат Справочники[ИмяОбъекта];
ИначеЕсли Документы.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат Документы[ИмяОбъекта];
ИначеЕсли БизнесПроцессы.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат БизнесПроцессы[ИмяОбъекта];
ИначеЕсли ПланыВидовХарактеристик.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат ПланыВидовХарактеристик[ИмяОбъекта];
ИначеЕсли ПланыСчетов.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат ПланыСчетов[ИмяОбъекта];
ИначеЕсли ПланыВидовРасчета.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат ПланыВидовРасчета[ИмяОбъекта];
ИначеЕсли Задачи.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат Задачи[ИмяОбъекта];
ИначеЕсли ПланыОбмена.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат ПланыОбмена[ИмяОбъекта];
ИначеЕсли Перечисления.ТипВсеСсылки().СодержитТип(ТипСсылки) Тогда
Возврат Перечисления[ИмяОбъекта];
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Функция _ПолучитьПустуюСсылкуПоИдентификаторуОбъекта(ОбъектМетаданных) Экспорт
ТипМД = _ПолучитьТипПоИдентификатору(ОбъектМетаданных);
ПустаяСсылка = "";
Если ТипМД = "Справочник" Тогда
Команда1С = "ПустаяСсылка = Справочники."+ОбъектМетаданных+".ПустаяСсылка()";
ИначеЕсли ТипМД = "Документ" Тогда
Команда1С = "ПустаяСсылка = Документы."+ОбъектМетаданных+".ПустаяСсылка()";
ИначеЕсли ТипМД = "Перечисление" Тогда
Команда1С = "ПустаяСсылка = Перечисления."+ОбъектМетаданных+".ПустаяСсылка()";
ИначеЕсли ТипМД = "ПланВидовРасчета" Тогда
Команда1С = "ПустаяСсылка = ПланыВидовРасчета."+ОбъектМетаданных+".ПустаяСсылка()";
Иначе
Возврат Неопределено;
КонецЕсли;
Выполнить (Команда1С);
Возврат ПустаяСсылка;
КонецФункции
Имея данные объекта мы можем использовать их в конфигурациях переноса создав процедуру сопоставления объектов, здесь можно будет уже
развернуться как Вам больше нравится
В случае если наш объект является ХранилищеЗначений то для переноса данного объекта либо получение значения можно воспользоваться функцией
//*****************************
//рабочая процедура и в ней код обработки
ИначеЕсли _ТипОбъекта = "ХранилищеЗначения" Тогда
Возврат ПереносХранилища(РеквCOM);
//*****************************
Функция ПереносХранилища(РеквCOM)
Попытка
ДвоичныеДанные = РеквCOM.Get();
Исключение
Возврат Неопределено;
Конецпопытки;
Если "" + ДвоичныеДанные = "COMОбъект" Тогда
Попытка
ИмяВременногоФайла = ПолучитьИмяВременногоФайла();
ДвоичныеДанные.Write(ИмяВременногоФайла);
ДвоичныеДанныеВозврат = Новый ДвоичныеДанные(ИмяВременногоФайла);
УдалитьФайлы(ИмяВременногоФайла);
Возврат Новый ХранилищеЗначения(ДвоичныеДанныеВозврат);
Исключение
Возврат Неопределено;
КонецПопытки;
Иначе
Возврат Неопределено;
КонецЕсли;
КонецФункции
Если объект является перечислением то вместо УИД кода будет выведено наименование перечисления
Также для получения списка реквизитов объекта СОМ используется обращение
РеквCOM.Metadata().Attributes // Список реквизитов
РеквCOM.Metadata().Attributes.Find("Реквизит") // Поиск реквизита в объекте
// если реквизит не найден возвращает значение НЕОПРЕДЕЛЕНО
РеквCOM.Metadata().StandardAttributes // Список стандартных реквизитов
РеквCOM.Metadata().TabularSections // Список табличных частей
Для работы с удаленой базой через COM соединение также часто возникает необходимость получения функциональных опций объекта
для этих целей можно использовать функцию которая выведет список соответствий функциональных опций
// Доступность объектов метаданных по функциональным опциям.
Функция ДоступностьОбъектовПоОпциямCOM() Экспорт
Если Коннект = Неопределено Тогда Если Не ПодключитьИБ() Тогда Сообщить("Не удалось установить подключение к ИБ!!!"); Возврат Новый Соответствие КонецЕсли; КонецЕсли;
Параметры = Новый Структура;
ДоступностьОбъектов = Новый Соответствие;
Для Каждого ФункциональнаяОпция Из Коннект.Метаданные.ФункциональныеОпции Цикл
Значение = -1;
Для Каждого Элемент Из ФункциональнаяОпция.Состав Цикл
Если Значение = -1 Тогда
Значение = ПолучитьФункциональнуюОпцию(ФункциональнаяОпция.Имя, Параметры);
КонецЕсли;
Если Значение = Истина Тогда
ДоступностьОбъектов.Вставить(Элемент.Объект, Истина);
Иначе
Если ДоступностьОбъектов[Элемент.Объект] = Неопределено Тогда
ДоступностьОбъектов.Вставить(Элемент.Объект, Ложь);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат ДоступностьОбъектов;
КонецФункции
//Рабочая процедура
Функция ОбъектМетаданныхДоступенПоФункциональнымОпциямCOM(ОбъектМетаданныхCOM) Экспорт
Возврат ДоступностьОбъектовПоОпциямCOM()[ОбъектМетаданныхCOM] <> Ложь;
КонецФункции
Так же при работе с переносом документов возникает необходимость определения списка регистров движения данного документа
МетаданныеДокументаCOM = ДокCom.MetaData();
Регистры = ЗаполнитьТаблицуРегистровCOM(МетаданныеДокументаCOM);
УстановитьПривилегированныйРежим(Истина);
РегистрыСДвижениями = ПолучитьМассивИспользуемыхРегистровCOM(ДокCom, МетаданныеДокументаCOM.Движения);
Функция ЗаполнитьТаблицуРегистровCOM(МетаданныеДокументаCOM)
Если Коннект = Неопределено Тогда Если Не ПодключитьИБ() Тогда Сообщить("Не удалось установить подключение к ИБ!!!"); Возврат Новый ТаблицаЗначений КонецЕсли; КонецЕсли;
МетаданныеРегистровНакопленияCOM = Коннект.Metadata.РегистрыНакопления;
МетаданныеРегистровСведенийCOM = Коннект.Metadata.РегистрыСведений;
ВидРегистраОстаткиCOM = Коннект.Metadata.СвойстваОбъектов.ВидРегистраНакопления.Остатки;
Регистры = Новый ТаблицаЗначений;
Регистры.Колонки.Добавить("ТипРегистра", ОбщегоНазначения.ОписаниеТипаСтрока(20));
Регистры.Колонки.Добавить("Имя", ОбщегоНазначения.ОписаниеТипаСтрока(100));
Регистры.Колонки.Добавить("Синоним", ОбщегоНазначения.ОписаниеТипаСтрока(100));
Регистры.Колонки.Добавить("ЕстьДвижения", Новый ОписаниеТипов("Булево"));
Регистры.Колонки.Добавить("РегистрОстатков", Новый ОписаниеТипов("Булево"));
Регистры.Колонки.Добавить("Записывать", Новый ОписаниеТипов("Булево"));
Для каждого МетаданныеРегистраCOM Из МетаданныеДокументаCOM.Движения Цикл
Если Лев(МетаданныеРегистраCOM.Имя, 7) = "Удалить" Тогда Продолжить КонецЕсли;
//Если Не ОбъектМетаданныхДоступенПоФункциональнымОпциямCOM(МетаданныеРегистраCOM) Тогда
// Продолжить;
//КонецЕсли;
СтрокаРегистра = Регистры.Добавить();
СтрокаРегистра.Имя = МетаданныеРегистраCOM.Имя;
ПолноеИмя = МетаданныеРегистраCOM.ПолноеИмя();
ПозицияТочки = Найти(ПолноеИмя, ".");
ТипРегистра = Лев(ПолноеИмя, ПозицияТочки - 1);
СтрокаРегистра.ТипРегистра = ТипРегистра;
СтрокаРегистра.Синоним = МетаданныеРегистраCOM.Синоним;
Если ТипРегистра = "РегистрНакопления" Тогда
СтрокаРегистра.РегистрОстатков = МетаданныеРегистраCOM.ВидРегистра = ВидРегистраОстаткиCOM;
КонецЕсли;
КонецЦикла;
// Сначала показывается регистр бухгалтерии, затем регистры накопления, затем - сведений
Регистры.Сортировать("ТипРегистра, Синоним");
Возврат Регистры;
КонецФункции
Функция ПолучитьМассивИспользуемыхРегистровCOM(Регистратор, Движения, МассивИсключаемыхРегистров = Неопределено) Экспорт
Если Коннект = Неопределено Тогда Если Не ПодключитьИБ() Тогда Сообщить("Не удалось установить подключение к ИБ!!!"); Возврат Новый ТаблицаЗначений КонецЕсли; КонецЕсли;
Запрос = Коннект.NewObject("Query");
Запрос.УстановитьПараметр("Регистратор", Регистратор);
Результат = Новый Массив;
МаксимумТаблицВЗапросе = 256;
СчетчикТаблиц = 0;
СчетчикДвижений = 0;
ВсегоДвижений = Движения.Количество();
ТекстЗапроса = "";
Для Каждого Движение Из Движения Цикл
СчетчикДвижений = СчетчикДвижений + 1;
ПропуститьРегистр = МассивИсключаемыхРегистров <> Неопределено
И МассивИсключаемыхРегистров.Найти(Движение.Имя) <> Неопределено;
Если Не ПропуститьРегистр Тогда
Если СчетчикТаблиц > 0 Тогда
ТекстЗапроса = ТекстЗапроса + "
|ОБЪЕДИНИТЬ ВСЕ
|";
КонецЕсли;
СчетчикТаблиц = СчетчикТаблиц + 1;
ТекстЗапроса = ТекстЗапроса +
"
|ВЫБРАТЬ ПЕРВЫЕ 1
|""" + Движение.Имя + """ КАК ИмяРегистра
|
|ИЗ " + Движение.ПолноеИмя() + "
|
|ГДЕ Регистратор = &Регистратор
|";
КонецЕсли;
Если СчетчикТаблиц = МаксимумТаблицВЗапросе Или СчетчикДвижений = ВсегоДвижений Тогда
Запрос.Текст = ТекстЗапроса;
ТекстЗапроса = "";
СчетчикТаблиц = 0;
Если Результат.Количество() = 0 Тогда
Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("ИмяРегистра");
Иначе
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Результат.Добавить(Выборка.ИмяРегистра);
КонецЦикла;
КонецЕсли;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Все процедуры, используемые в статье, являются работающими и готовы к использованию.
Надеюсь, кому-нибудь данная статья будет полезна!
Спасибо за внимание) !!!
При копировании процедур из БСП следует указывать, что они из БСП.
Вот КД уже сколько лет существует, а люди все свои костылики пишут для обмена, да ещё и по ком, мде в общем..
Почему вы так решили? СтрокаXML от хранилища значения — это сырые данные (строка в формате base64). Её длина может быть какой угодно.
Для определения типа КомОбъекта следует пользоваться процедурами и функциями работы с XML (XMLТип, XMLТипЗнч, ИзXMLТипа).
Чтобы получить метаданные, объект получать не обязательно. У любой ссылки есть метод Метаданные.
Получить менеджер можно проще:
Получение пустой ссылки логичнее делать через менеджер.
Хранилище значения переносится через XMLСтрока / XMLЗначение
(3) У любой ссылки есть Метаданные Вы правы но через COM соединение не все можно получить
ИначеЕсли СтрДлина(_СтрокаXML) = 48 Тогда //Хранилище значения
если рассматривать как просто отдельная строка то да сказать точно что это хранилище невозможно, но первое стоит проверка на наличие 4 дефисов что говорит о формате строки УИД, если не УИД то хранилище, иначе перечисление по другому я не сталкивался.
Что касаемо определение Менеджера, то в Вашем примере Вы должны точно знать уже имя менеджера ссылки чтоб произвести замену
в моем случае мы его знать не должны он определится автоматически.
Что касаемо самой статьи то я много искал и изучал вопрос и сталкивался с проблемами которые порой не описаны в инете, поэтому и решил поделится информацией. Никто не спорит что коды совершенны и их дорабатывать нельзя)
(2) вы еще мал и глуп, бывает ситуация разовых омбенов, когда проще и много быстрее реализовать костыльный обмен через ком.
Сложная статья для прочтения.
Когда-то тоже писал про это —https://infostart.ru/public/164976/
Как по мне, GetObject().Metadata().FullName() — здесь и в других аналогичных местах нужно использовать наименования на русском, глаз режет.
(5) Очень приятно 🙂 А Вы собственно кто будете? Большой и умный заядлый велосипидист, тот что делает «быстрые одноразовые» обмены ?:)
К сожалению, повидал на своем маленьком веку такие штуки, надеюсь не скоро еще увижу.
Ком-соединение для сравнения остатков и оборотов тоже требует и поиска и идентификации объектов, иногда по тем же правилам, которые описаны в конвертации данных.
Ссылка с гуидом на данные не всегда сохраняется.
Статья очень полезная, спасибо.
(7) абсолютно так. Написал быстренько обработку, загрузил нужные данные, помог заказчику, взял деньги, взял лесопед и пошел кататься. Все довольны — и я и заказчик. А вы сидите, отлаживайте днями ваши обмены, корпите значит. Видал я обмены таких корпунов, когда затирали данные в рабочей базе, надеюсь еще не скоро увижу.
(2), (5) ИМХО глупый спор коллеги, этому холивару (что лучше КД или Com) уж скоро *цать лет будет, это всё равно что спорить что лучше — микроволновка или холодильник) Разные инструменты, требующие вдумчивого применения есть плюсы и минусы у обоих, в каждом конкретном случае надо подумать что проще/быстрее/лучше/универсальнее применить. Статья хорошая, действительно всё вместе в одном месте собрано. По поводу (6) хотел тоже отметить что сталкивался в своей работе с ситуациями когда .Метаданные() — вызывает ошибку, а .Metadata() нет.. И с обратными тоже сталкивался (причём с обратными ситуациями чаще после 2-й точки.. блин как лучше сформулировать-то, ну типа например РеквCOM.Metadata().TabularSection() — вызывает ошибку, а РеквCOM.Metadata().ТабличныеЧасти() — нет, точно не помню уже ситуаций), в общем так и не понял от чего это зависит, приходится идти иногда на такой «зоопарк»( Если кто знает — поделитесь, буду рад получению новых знаний.
com-соединения лучше не использовать вообще. (википедия Стандарт COM был разработан в 1993 году корпорацией Microsoft как основа для развития технологии OLE.) Технология 1993 года.
https://infostart.ru/public/955078/
Переходить на http-сервис
Ё-моё… И вот за такое — столько плюсов? Мдя. Зря я сюда лет 10 назад все исходники свои не выложил, вот точно хит был бы…
Пишешь про ком — так хотя б не баянь. Хотя бы интересные моменты опиши. А это, извините, из серии хелло ворлд.
Холиварчик, кстати, демонстрирует, что опыта маловато у некоторых. Потому как, и это верно было замечено, случаи весьма разные, иногда ПКО накатать быстрее, а иногда ком воткнуть удобнее. И это ооочень разные случаи. Ну и потом, интеграцию с другими приложениями и ранее популярное обращение к служебкам самой 1С — их никто не отменял.