Всем привет!
В статье не будет обсуждений конструкций вида ЗапросCOM = COM.NewObject("Запрос")
и получать типы объектов тоже не будем.
Опишу способы использования ком-подключения для определенного круга задач - когда надо сопоставить номенклатуру, контрагентов или остатки между двумя базами.
Суть в двух словах.
В одной базе (База-1) в общем модуле будут созданы функции, возвращающие таблицу значений названий номенклатуры, контрагентов или остатков и других значений примитивных типов.
В другой базе (База-2) мы создадим ком-подключение к Базе-1, будем получать из Базы-1 таблицу значений названий номенклатуры, контрагентов, остатков. Далее в Базе-2 создадим пользовательскую форму для сопоставления названий номенклатур, контрагентов, остатков. Отдадим на откуп сопоставление номенклатуры, контрагентов, остатков пользователям.
Уточнения:
1) в Базе-2 не надо использовать ком-объект NewObject("Запрос") - с запросами мы работаем исключительно в Базе-1, конструируем их, выполняем.
Передаем в другую базу только ТаблицуЗначений. Ссылки не передаем, но если надо передать ссылки, то заменяем их на УИД.
Так как в запросе мы не можем получить УИДы (на момент написания статьи 6 мая 2020г), то потребуется пройтись в цикле по выборке, чтобы определить по каждой ссылке соответствующий УИД в возвращаемой ТаблицеЗначений.
2) Ком-подключение используется не для программной обработки данных, а для визуального сопоставления справочников и остатков именно пользователями программы 1С. Пользователи видят расхождение, и производят дальнейшую обработку номенклатуры, контрагентов, остатков исходя из смысла рабочего процесса (см. рис. ниже с примерами задач).
Примеры возникновения подобных задач:
1) Есть база Источник (например, КА) и есть база Приемник (некая база адресного хранения товаров). Номенклатура переходит из базы Источника в базу Приемник с помощью заданного плана обмена, товары сопоставляются между базами по уникальному идентификатору УИД. Одной из задач в таком случае становится сопоставить остатки товаров в базах.
2) Есть две независимые базы БП и УТ, учет ведется параллельно, обмен между базами не настроен.
Но в какой-то момент становится необходимым настроить обмен между базами. И тогда для первоначальной настройки обмена требуется сопоставить номенклатуру и контрагентов. Номенклатуру будем сопоставлять по названию и ряду дополнительных признаков (помечен на удаление, это группа, это услуга - это из стандартных признаков). Контрагентов будем сопоставлять по названию, ИНН и КПП, плюс по стандартным признакам.
3) Есть несколько баз УТ, и надо объединить базы в одну базу. Если базы находятся в одной локальной сети, то для первоначального сопоставления номенклатуры и контрагентов можно использовать прямое подключение по com-технологии (см. рис.).
На рисунке показано сравнение номенклатуры по названию. Использовано Левое соединение таблиц, но вы можете использовать Полное соединение таблиц, чтобы увидеть какая номенклатура не совпадает по названию в обеих базах.
Технология использования:
За ком-интерфейс отвечает компонента dll - comcntr.dll (переводится как "управление ком"), которая расположена в установочной папке 1с (см. рис.). Именно эту компоненту вам надо зарегистрировать в опер. системе самостоятельно, если этого не сделала платформа 1с при первоначальной установке. Помните о лицензии +1 при соединении.
В Базе-1 придется создать общий модуль, задать ему свойство "внешнее соединение" (рис. ниже).
В общем модуле Базы-1 функции условно можно разделить на две категории:
- функции, которые получают данные из этой же базы для передачи Таблицы Значений в другую базу.
- и функции, которые используются для работы с другой базой - например, та же функция получения Ком-соединения с другой базой.
Смотрите разделение функций на рис. ниже.
Остальную функциональность в Базе-2 для использования ком-подключения и сопоставления номенклатуры (контрагентов или остатков) можно разработать во внешней обработке (рис. ниже).
Таким образом, если у вас имеется не редактируемая на поддержке типовая БП и редактируемая измененная УТ, то вы можете создать экспортные функции в общем модуле УТ, а подключаться по ком-соединению из БП и видеть расхождения в номенклатуре в пользовательской форме БП. То есть, снимать с поддержки БП не придется, потому что будете использовать внешнюю обработку.
Далее будут представлены алгоритмы создания ТаблицыЗначений в Базе-1 (Листинг 1) и алгоритмы обхода ТаблицыЗначений в Базе-2 (Листинг 2).
//////////////////////////////////////////////////
//Работа с этой базой данных
//получаем таблицу Наименование, УИД, Код
Функция ПолучитьТаблицуТоваров() Экспорт
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Наименование"); //основная информация
ТЗ.Колонки.Добавить("УИД"); //вспомогательная информация
ТЗ.Колонки.Добавить("Код"); //вспомогательная информация
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование,
| Номенклатура.Код
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ПометкаУдаления = ЛОЖЬ
| И Номенклатура.ЭтоГруппа = ЛОЖЬ
|
|УПОРЯДОЧИТЬ ПО
| Ссылка
|АВТОУПОРЯДОЧИВАНИЕ";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Стр = ТЗ.Добавить();
Стр.Наименование = СокрЛП(Выборка.Наименование);
Стр.УИД = Строка(Выборка.Ссылка.УникальныйИдентификатор());
Стр.Код = СокрЛП(Выборка.Код);
КонецЦикла;
Возврат ТЗ;
КонецФункции
//получаем таблицу Склад, Номенклатура, Количество
Функция ПолучитьТаблицуОстатковТоваров() Экспорт
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Склад");
ТЗ.Колонки.Добавить("Номенклатура");
ТЗ.Колонки.Добавить("Количество");
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Склад КАК Склад,
| ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
| ТоварыНаСкладахОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
|
|УПОРЯДОЧИТЬ ПО
| Склад,
| Номенклатура
|АВТОУПОРЯДОЧИВАНИЕ";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Стр = ТЗ.Добавить();
Стр.Склад = СокрЛП(Выборка.Склад);
Стр.Номенклатура = СокрЛП(Выборка.Номенклатура);
Стр.Количество = Выборка.КоличествоОстаток;
КонецЦикла;
Возврат ТЗ;
КонецФункции
//получаем остатки по всем складам одного товара
Функция ПолучитьОстаткиПоТовару(Наименование) Экспорт
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Склад");
ТЗ.Колонки.Добавить("Количество",Новый ОписаниеТипов("Число"));
//Справочники.Номенклатура.НайтиПоНаименованию(Наименование,Истина);
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.ПометкаУдаления = ЛОЖЬ
| И Номенклатура.ЭтоГруппа = ЛОЖЬ
| И Номенклатура.Наименование = &Наименование";
Запрос.УстановитьПараметр("Наименование", Наименование);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Возврат ТЗ;
КонецЕсли;
Выборка = Результат.Выбрать();
Если Выборка.Количество() > 1 Тогда
Стр = ТЗ.Добавить();
Стр.Склад = "Проблема: найдено несколько товаров с таким наименованием";
Стр.Количество = 0;
Возврат ТЗ;
КонецЕсли;
Номенклатура = Неопределено;
Если Выборка.Следующий() Тогда
Номенклатура = Выборка.Ссылка;
КонецЕсли;
Если НЕ ЗначениеЗаполнено(Номенклатура) Тогда
Возврат ТЗ;
КонецЕсли;
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Склад");
ТЗ.Колонки.Добавить("Количество",Новый ОписаниеТипов("Число"));
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ТоварыНаСкладахОстатки.Склад КАК Склад,
| ТоварыНаСкладахОстатки.КоличествоОстаток
|ИЗ
| РегистрНакопления.ТоварыНаСкладах.Остатки(, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОстатки
|
|УПОРЯДОЧИТЬ ПО
| Склад
|АВТОУПОРЯДОЧИВАНИЕ";
Запрос.УстановитьПараметр("Номенклатура", Номенклатура);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Стр = ТЗ.Добавить();
Стр.Склад = СокрЛП(Выборка.Склад);
Стр.Количество = Выборка.КоличествоОстаток;
КонецЦикла;
Возврат ТЗ;
КонецФункции
//получаем УИД товара
Функция ПолучитьИдентификаторТовара() Экспорт
КонецФункции
//ОстаткиТоваровВДругихБазах - это ТаблицаЗначений с полями Склад (Строка), Количество (Число)
Процедура ПоказатьОстаткиТоваровВДругихБазах(ОстаткиТоваровВДругихБазах, Номенклатура) Экспорт
Попытка
УстановитьПривилегированныйРежим(Истина);
ОстаткиТоваровВДругихБазах.Очистить(); //это таблица значений на форме
Если НЕ ЗначениеЗаполнено(Номенклатура) Или Номенклатура.ЭтоГруппа Или Номенклатура.ПометкаУдаления Тогда
Возврат;
КонецЕсли;
//1. получим остатки по базе-1
Если КомСоединениеКБазе1 = Неопределено Тогда
ОбъединениеБаз.ПолучитьКомСоединениеКБазе1(); //вызов общего модуля и экспортной функции
КонецЕсли;
ТЗ_База1 = КомСоединениеКБазе1.ОбъединениеБаз.ПолучитьОстаткиПоТовару(Номенклатура.Наименование);
Для Каждого Стр из ТЗ_База1 Цикл
НоваяСтрока = ОстаткиТоваровВДругихБазах.Добавить();
НоваяСтрока.Склад = "База 1 " + Стр.Склад;
НоваяСтрока.Количество = Стр.Количество;
КонецЦикла;
//2. получим остатки по базе-2
Если КомСоединениеКБазе2 = Неопределено Тогда
ОбъединениеБаз.ПолучитьКомСоединениеКБазе2(); //вызов общего модуля и экспортной функции
КонецЕсли;
ТЗ_База2 = КомСоединениеКБазе2.ОбъединениеБаз.ПолучитьОстаткиПоТовару(Номенклатура.Наименование);
Для Каждого Стр из ТЗ_База2 Цикл
НоваяСтрока = ОстаткиТоваровВДругихБазах.Добавить();
НоваяСтрока.Склад = "База 2 " + Стр.Склад;
НоваяСтрока.Количество = Стр.Количество;
КонецЦикла;
УстановитьПривилегированныйРежим(Ложь);
Исключение
КонецПопытки;
КонецПроцедуры
В листинге 2 представлены функции: подключение к базе по ком-соединению, получение остатков из базы. Помним, что мы получаем по ком-соединению ком-таблицу - то есть это не просто таблица значений, а некий объект ком-подключения, напоминающий таблицу значений. Примитивные типы данных передаются через ком-таблицу стандартно, остальные типы значений не переносятся. После получения ком-таблицы для работы с ее данными требуется создать свою ТаблицуЗначений с полями предопределенных типов значений - см. Листинг 3 - это пример из обработки Сравнение остатков по регистрам накопления.
Функция ПолучитьТЗ(ИмяРегистра, ТЗ_КомОбъект) Экспорт
ТЗ = Новый ТаблицаЗначений;
РегистрНакопления = Метаданные.РегистрыНакопления[СокрЛП(ИмяРегистра)];
Для Каждого Измерение Из РегистрНакопления.Измерения Цикл
ТЗ.Колонки.Добавить(Измерение.Имя, Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(200)));
КонецЦикла;
Для Каждого Ресурс Из РегистрНакопления.Ресурсы Цикл
ТЗ.Колонки.Добавить(Ресурс.Имя + "Остаток", Новый ОписаниеТипов("Строка",,Новый КвалификаторыСтроки(200)));
КонецЦикла;
Для Каждого Стр из ТЗ_КомОбъект Цикл
НоваяСтрока = ТЗ.Добавить();
Для Каждого Измерение Из РегистрНакопления.Измерения Цикл
НоваяСтрока[Измерение.Имя] = СокрЛП(Стр[Измерение.Имя]);
КонецЦикла;
Для Каждого Ресурс Из РегистрНакопления.Ресурсы Цикл
НоваяСтрока[Ресурс.Имя + "Остаток"] = СокрЛП(Стр[Ресурс.Имя + "Остаток"]);
КонецЦикла;
КонецЦикла;
Возврат ТЗ;
КонецФункции
Работа с ком-подключением задается только пользователю с определенной ролью (захватывается одна лицензия платформы 1с) - в моем случае, я создал роль "КомКоннектор", вы можете использовать одну из предопределенных типовых ролей.
При работе с ТЗ надо помнить о типах значений, которые мы передаем/получаем через ТаблицуЗначений - для таблиц значений типы полей надо задавать заранее (см листинги).
При работе с ком-подключением используйте конструкцию Попытка Исключение КонецПопытки.
Принцип использования ком-подключения:
- управлять из одной базы-2 объектами другой базы-1 не нужно.
- нам не нужно даже передавать в другую базу-1 какую-либо информацию.
- нам нужно в базе-2 только получить таблицу из базы-1, которую мы проанализируем в базе-2.
Собственно, это все. Всем добра! :)
С пользой для клиентов, Рустем
- Анализ прав и ролей. Поиск подходящего профиля - алгоритмический анализ и поиск
- Оцифровка и визуализация склада - программная прорисовка склада
- Удаление документов для любых баз на управляемых формах
- Удаление справочников для любых баз на управляемых и обычных формах
- Перенумерация документов и справочников - с учетом префиксов номеров
- Свертка базы УТ 10.3 подокументно - новая концепция
- Матричное программирование - демо-стенд матричного калькулятора
- Справочное хранение товаров в КА 2.5 - кейс запуска адресного склада
- Мини-обзор разных задач - от очевидного до неочевидного
- Поиск отчета по документам - пример анализа незнакомых конфигураций
- Флажок в динамическом списке - от теории до практики "как бы простой" задачи
- Из Json в ДеревоЗначений - удобный просмотрщик json-структуры
- Внедрение адресного склада в КА 2.5 - кейс запуска адресного склада
- Фрилансеру: про цены, про клиентов, про планирование - мое исследование
- Что такое форматированный документ - прекрасная возможность раскрасить любой текст
- Программная работа с упаковками в КА 2.5 - примеры адаптаций механизмов упаковок в КА 2.5
- Универсальное сравнение регистров накопления - связь по измерениям, сравнение по ресурсам
- Обход объекта рекурсивно - просмотр реквизитов документа с бесконечным открытием подуровней