Имя: Пароль:
1C
1С v8
COM-соединение. передача ТЗ из базы в базу.
0 igel1969
 
17.10.19
09:32
Здравствуйте!
Есть две базы разных платформ и разных конфигураций.
Есть программа (написанная не мной) переброски данных. Программист писал программу, когда данных было мало. Фирма разрослась, данных стало много и программа работает безобразно медленно.
Итак, в первой базе есть ТЗ, которую надо заполнить данными из второй базы.
Если делать это из первой базы, то получается очень медленно, там одна операция некрасивая, которая через COM-соединение проходит медленно.
Я пробовал эту операцию провести на второй базе - все работает полсекунды.
Осталось передать из второй базы обратно результат формирования ТЗ.
Но не получается.

Вот (в упрощенном виде) плохой код, который тормозит:

Для каждого Док из Документы Цикл
   Док.ИД_УТ = Соединение.string(Док.Ссылка.УникальныйИдентификатор());
   Док.Контрагент_ИД_УТ = Соединение.string(Док.Контрагент.УникальныйИдентификатор());
   Для каждого Стр из Товары Цикл
      Стр.Номенклатура_УТ_ИД = Соединение.string(Стр.Номенклатура.УникальныйИдентификатор());
      Стр.ХарактеристикаНоменклатуры_УТ_ИД = Соединение.string(Стр.ХарактеристикаНоменклатуры.УникальныйИдентификатор());
   КонецЦикла;
КонецЦикла;

Вот это все сильно тормозит.

Я хочу во второй базе написать в общем модуле экспортную процедуру или функцию (лучше процедуру, так как требуется возврат двух ТЗ),
в которой формировались бы нужные мне ТЗ. Но как их вернуть обратно?
Я пробовал прямо передавать ссылку на ТЗ из первой базы, но получил ошибку: Переменная не определена (ГлавныйИнтерфейс).
И считаю это вполне естественным, ведь платформы совсем разные.

писал во второй базе (упрощенно):
Процедура СформироватьДанные(ТЗ1, ТЗ2) экспорт
   ТЗ1.Добавить();
   ТЗ1.Документ = Результат.Документ;

а в первой базу вызывал
СформироватьДанные(МойТЗ1, МойТЗ2);
где МойТЗ1 и МойТЗ2 - уже существующие ТЗ, со сформированными полями.

Может что другое подскажете?
1 ДенисЧ
 
17.10.19
09:33
А в тз у тебя ссылки на документы? Вряд ли ты так просто всё передашь.
2 igel1969
 
17.10.19
09:36
(1) да, в том числе и ссылки
3 Галахад
 
гуру
17.10.19
09:41
Создать таблицу значений с колонками просты типов.
Преобразовать ее в строку и передать между базами.
Тип так:
    ЗаписьXML = Новый ЗаписьXML;
    ЗаписьXML.УстановитьСтроку();
    СериализаторXDTO.ЗаписатьXML(ЗаписьXML, ТЗ);
    СтрокаXML = ЗаписьXML.Закрыть();
4 ink-nsk
 
17.10.19
09:52
(2) Что есть "ссылки", а что есть "значения"?
5 Chameleon1980
 
17.10.19
09:53
Веб сервис на отдающей стороне. Там упаковать в джейсон, иксемэль и отдать.
6 igel1969
 
17.10.19
09:59
(4) поле ТЗ типа СсылкаНаДокументы.РеализацииТоваровУслуг, заполняется из
РезультатВыборкиДокументов.Ссылка
7 Провинциальный 1сник
 
17.10.19
10:00
(3) Проще и быстрее через ЗначениеВСтрокуВнутр
8 Провинциальный 1сник
 
17.10.19
10:02
И кстати, учтите, передача через COM числовых значений в 1с - плохая идея, так как через COM не передаются напрямую числовые типы 1с, они преобразуются во флоат и теряется точность при передаче. Лучше всегда и всё сериализовать в строку при передаче, это надежнее.
9 igel1969
 
17.10.19
10:07
(8) (7) (5) :
проще видимо будет переписать программу, чтобы она опиралась не на УникальныйИдентификатор, а на коды справочников и номера документов (в пределах годового периода). Еще написать программу, которая разово перезаменит все уже сохраненные значения УникальныхИдентифиакторв на коды, чтобы не потреялась уже установленная связь между контрагентами, номенклатурой. работы на полтора дня, зато для мозгов легко. Просто хотел сделать красиво, но пошли слишком высокие материи, овчинка выделки не стоит.
10 Mikhail Volkov
 
17.10.19
10:11
(7) Именно так делал при обмене Альфа-Авто с КА1:
// Заполняет табличную часть (товары или автомобили) документа по найденному в КА документу
//
Функция ЗаполнитьТЧпоДокументуКА(Документ, ДокументКА)   Экспорт
    
    ТЗ_КА = Новый ТаблицаЗначений;
    ЦенаВключаетНДС = ЦенаВключаетНДС(Документ);
    ВидДокументаКА  = ВидДокументаКА(Документ);
    
    Запрос = ОбъектКА.NewObject("Запрос");
    Запрос.Текст =
    "ВЫБРАТЬ
    |    ДокументТовары.Номенклатура,
    |    ДокументТовары.Номенклатура.Артикул КАК Артикул,
    |    ДокументТовары.Номенклатура.Код КАК Код,
    |    ДокументТовары.Номенклатура.Услуга КАК Услуга,
    |    ДокументТовары.ХарактеристикаНоменклатуры,
    |    ДокументТовары.ЕдиницаИзмерения,
    |    ДокументТовары.Коэффициент,
    |    ДокументТовары.Количество,
    |    ДокументТовары.Цена,
    |    ДокументТовары.ПроцентСкидкиНаценки,
    |    ДокументТовары.Сумма,
    |    ДокументТовары.СуммаНДС
    |ИЗ
    |    Документ." + ВидДокументаКА + ".Товары КАК ДокументТовары
    |ГДЕ
    |    ДокументТовары.Ссылка = &Ссылка";
    
    Реализация = Найти(ТипЗнч(Документ.Ссылка), "Реализация") > 0;
    Запрос.Текст = ?(Реализация, Запрос.Текст, СтрЗаменить(Запрос.Текст, "|    ДокументТовары.ПроцентСкидкиНаценки,", ""));
    Запрос.УстановитьПараметр("Ссылка", ДокументКА);
        
    Результат = Запрос.Выполнить();
    Если Результат.Пустой() Тогда Возврат Ложь; КонецЕсли;
    ТЗ_КА     = Результат.Выгрузить();                    // COM-Объект
    ТЗ_КА.Колонки.Добавить("НоменклатураGUID");
    ТЗ_КА.Колонки.Добавить("ХарактеристикаНоменклатурыGUID");
    ТЗ_КА.Колонки.Добавить("ЕдиницаИзмеренияGUID");
    Для каждого Строка Из ТЗ_КА Цикл
        Строка.НоменклатураGUID                  = ОбъектКА.XMLСтрока(Строка.Номенклатура.Ссылка);
        Строка.ЕдиницаИзмеренияGUID              = ОбъектКА.XMLСтрока(Строка.ЕдиницаИзмерения.Ссылка);
        Строка.ХарактеристикаНоменклатурыGUID = ?(обЗначениеНеЗаполнено(Строка.ХарактеристикаНоменклатуры.Ссылка),
                                                "", ОбъектКА.XMLСтрока(Строка.ХарактеристикаНоменклатуры.Ссылка));
    КонецЦикла;

    СтрТЗ_КА = ОбъектКА.ЗначениеВСтрокуВнутр(ТЗ_КА);    // COM-Объект в строку
    ТЗ         = ЗначениеИзСтрокиВнутр(СтрТЗ_КА);            // ТЗ из строки
    Если ТЗ.Количество() = 0 Тогда Возврат Ложь; КонецЕсли;
    
    Авто = Найти(НРег(ТипЗнч(Документ.Ссылка)), "автомобилей") > 0;
    ТЗОтката = Документ[?(Авто, "Автомобили", "Товары")].Выгрузить();
    Документ[?(Авто, "Автомобили", "Товары")].Очистить();
    
    Для каждого СтрокаТЗ Из ТЗ Цикл
        Номенклатура = ПолучитьСсылкуСправочникаПоСсылкеКА(СтрокаТЗ.НоменклатураGUID, ?(Авто, "Автомобили","Номенклатура"));
        Если Номенклатура.Пустая() Тогда
            // Тогда попытаемся найти по артикулу или коду
            Номенклатура = ПолучитьСсылкуНоменклатурыПоАртикулуКодуКА(СтрокаТЗ.Артикул, СтрокаТЗ.Код, Авто, СтрокаТЗ.Услуга);
            Если Не ЗначениеЗаполнено(Номенклатура) Тогда
                Сообщить("Не найден" + ?(Авто, " автомобиль по VIN: ", "а номенклатура по коду: ") + СокрЛП(СтрокаТЗ.Код) + " и артикулу: " + СокрЛП(СтрокаТЗ.Артикул) + " с GUID: " + СтрокаТЗ.НоменклатураGUID, СтатусСообщения.Внимание);
                Продолжить;
            КонецЕсли;
        КонецЕсли;
        НоваяСтрока  = Документ[?(Авто, "Автомобили", "Товары")].Добавить();
        Если Авто Тогда
            НоваяСтрока.Автомобиль                    = Номенклатура;
            НоваяСтрока.ИдентификаторАвтомобиля        = ИдентификаторАвтомобиля(Номенклатура, ТЗОтката);
            НоваяСтрока.АвтомобильБезЗаказа            = Истина;
        Иначе
            ЕдиницаИзмерения                        = ПолучитьСсылкуСправочникаПоСсылкеКА(СтрокаТЗ.ЕдиницаИзмеренияGUID, "ЕдиницыИзмерения");
            Если ЕдиницаИзмерения.Пустая() Тогда
                ЕдиницаИзмерения                    = Номенклатура.ОсновнаяЕдиницаИзмерения;
            КонецЕсли;
            НоваяСтрока.Номенклатура                = Номенклатура;
            НоваяСтрока.ЕдиницаИзмерения            = ЕдиницаИзмерения;
            НоваяСтрока.ХарактеристикаНоменклатуры    = ПолучитьСсылкуСправочникаПоСсылкеКА(СтрокаТЗ.ХарактеристикаНоменклатурыGUID, "ХарактеристикиНоменклатуры");
            НоваяСтрока.Коэффициент                    = СтрокаТЗ.Коэффициент;
            НоваяСтрока.КоличествоБазовое            = СтрокаТЗ.Количество * СтрокаТЗ.Коэффициент;
        КонецЕсли;
        НоваяСтрока.Количество                        = СтрокаТЗ.Количество;
        НоваяСтрока.Цена                            = СтрокаТЗ.Цена;
        НоваяСтрока.Сумма                            = СтрокаТЗ.Сумма;
        НоваяСтрока.СтавкаНДС                        = ?(СтрокаТЗ.Сумма > 0 И СтрокаТЗ.СуммаНДС = 0, Справочники.СтавкиНДС.БезНДС, ?(Авто, Справочники.СтавкиНДС.ОсновнаяСтавкаНДС, Номенклатура.СтавкаНДС));
        НоваяСтрока.СуммаНДС                        = СтрокаТЗ.СуммаНДС;
        НоваяСтрока.СуммаВсего                        = СтрокаТЗ.Сумма + ?(ЦенаВключаетНДС, 0, СтрокаТЗ.СуммаНДС);
        Если Реализация Тогда
            НоваяСтрока.ПроцентСкидки                = СтрокаТЗ.ПроцентСкидкиНаценки;
        КонецЕсли;
    КонецЦикла;
    
    Если Документ[?(Авто, "Автомобили", "Товары")].Количество() = 0 Тогда
        ТекстСообщения = "Не удалось заполнить табличную часть основания по документу поставщика из КА";
        #Если Клиент Тогда
            Предупреждение(ТекстСообщения, 60);
        #Иначе
            Сообщить(ТекстСообщения, СтатусСообщения.Внимание);
        #КонецЕсли
        Документ[?(Авто, "Автомобили", "Товары")].Загрузить(ТЗОтката);
        Возврат Ложь;
    КонецЕсли;
    Возврат Истина;
КонецФункции // ЗаполнитьТЧпоДокументуКА()
11 Mikhail Volkov
 
17.10.19
10:21
Сейчас переходим на КА2, советуют забить на Com, переходить на веб и http-сервис Службы компонентов: возможно ли создать обертку OLE соединения V83.Application
Глупец, лишенный способности посмеяться над собой вместе с другими, не сможет долго выносить программирование. Фредерик Брукс-младший