Имя: Пароль:
1C
1С v8
Проблемы с COM-объектами
, ,
0 DimoXa
 
16.04.15
16:33
Доброго всем времени суток. Пользую чудную обработку "Монитор лицензий", которая показывает кол-во занятых лицензий. На сервере крутятся две базы - одна 8.2, другая 8.3.
8.2 висит на 1541 порту, 8.3 - на 1741. Каким образом можно реализовать переключение между ними в обработке? Я пробовал внутри процедуры задавать условия, но она постоянно вываливается с ошибками. Может я что-то неправильно подключаю?
Код подключения прилагаю

Процедура ВывестиЛицензии(ТабДок) Экспорт
    
    
    
Если ПустаяСтрока(Сервер) Тогда
        Возврат;
    КонецЕсли;

    ТаблицаЛицензий = Новый ТаблицаЗначений;
    ТаблицаЛицензий.Колонки.Добавить("ServerName",ПолучитьОписаниеТиповСтроки(50));
    ТаблицаЛицензий.Колонки.Добавить("BaseName",ПолучитьОписаниеТиповСтроки(50));
    ТаблицаЛицензий.Колонки.Добавить("MainPort",ПолучитьОписаниеТиповЧисла(5));
    ТаблицаЛицензий.Колонки.Добавить("AppID",ПолучитьОписаниеТиповСтроки(50));
    ТаблицаЛицензий.Колонки.Добавить("userName",ПолучитьОписаниеТиповСтроки(50));
    ТаблицаЛицензий.Колонки.Добавить("Host",ПолучитьОписаниеТиповСтроки(50));
    ТаблицаЛицензий.Колонки.Добавить("ShortPresentation",ПолучитьОписаниеТиповСтроки(50));
    ТаблицаЛицензий.Колонки.Добавить("FullPresentation",ПолучитьОписаниеТиповСтроки(50));
    ТаблицаЛицензий.Колонки.Добавить("Net",Новый ОписаниеТипов("Булево"));
    ТаблицаЛицензий.Колонки.Добавить("LicenseType",ПолучитьОписаниеТиповЧисла(1));
    ТаблицаЛицензий.Колонки.Добавить("MaxUsersAll",ПолучитьОписаниеТиповЧисла(3));
    ТаблицаЛицензий.Колонки.Добавить("Quantity",ПолучитьОписаниеТиповЧисла(1));
Если Версия = "8.2" Тогда
    Попытка
        Соединитель = Новый COMОбъект("V82.COMConnector");
        Соединение = Соединитель.ConnectAgent(Сервер);
        Кластеры = Соединение.GetClusters();
        МаксимальныйИндексКластеров = Кластеры.GetUpperBound();
        //Для Каждого ТекущийИндексКластера Из Кластеры.GetLowerBound() По МаксимальныйИндексКластеров  Цикл
            //ТекущийКластер = Кластеры.GetValue(ТекущийИндексКластера);
        Для Каждого ТекущийКластер Из Кластеры Цикл
            Соединение.Authenticate(ТекущийКластер, АдминистраторКластера, ПарольАдминистратора);
            Базы = Соединение.GetInfoBases(ТекущийКластер);
            МаксимальныйИндексБаз = Базы.GetUpperBound();
            //Для ТекущийИндексБазы = Базы.GetLowerBound() По МаксимальныйИндексБаз Цикл
            //    ОписаниеБазы = Базы.GetValue(ТекущийИндексБазы);
            Для Каждого ОписаниеБазы Из Базы Цикл
                Sessions = Соединение.GetInfoBaseSessions(ТекущийКластер,ОписаниеБазы);
                Для каждого Session из Sessions Цикл
                    Лицензия = Session.License;
                    Если Лицензия <> Неопределено Тогда
                        СтрокаСоединения = ТаблицаЛицензий.Добавить();
                        ЗаполнитьЗначенияСвойств(СтрокаСоединения,Session);
                        ЗаполнитьЗначенияСвойств(СтрокаСоединения,Лицензия);
                        СтрокаСоединения.BaseName = ОписаниеБазы.Name;
                        СтрокаСоединения.ServerName = Сервер;
                        СтрокаСоединения.MainPort = ТекущийКластер.MainPort;
                        СтрокаСоединения.Quantity = 1;
                        СтрокаСоединения.MaxUsersAll = Лицензия.MaxUsersAll;
                    КонецЕсли;    
                КонецЦикла;    
            КонецЦикла;
        КонецЦикла;
    Исключение
        ВызватьИсключение ОписаниеОшибки();
    КонецПопытки;
Иначе
Попытка
        Соединитель = Новый COMОбъект("V83.COMConnector");
        Соединение = Соединитель.ConnectAgent(Сервер);
        Кластеры = Соединение.GetClusters();
        МаксимальныйИндексКластеров = Кластеры.GetUpperBound();
        //Для Каждого ТекущийИндексКластера Из Кластеры.GetLowerBound() По МаксимальныйИндексКластеров  Цикл
            //ТекущийКластер = Кластеры.GetValue(ТекущийИндексКластера);
        Для Каждого ТекущийКластер Из Кластеры Цикл
            Соединение.Authenticate(ТекущийКластер, АдминистраторКластера, ПарольАдминистратора);
            Базы = Соединение.GetInfoBases(ТекущийКластер);
            МаксимальныйИндексБаз = Базы.GetUpperBound();
            //Для ТекущийИндексБазы = Базы.GetLowerBound() По МаксимальныйИндексБаз Цикл
            //    ОписаниеБазы = Базы.GetValue(ТекущийИндексБазы);
            Для Каждого ОписаниеБазы Из Базы Цикл
                Sessions = Соединение.GetInfoBaseSessions(ТекущийКластер,ОписаниеБазы);
                Для каждого Session из Sessions Цикл
                    Лицензия = Session.License;
                    Если Лицензия <> Неопределено Тогда
                        СтрокаСоединения = ТаблицаЛицензий.Добавить();
                        ЗаполнитьЗначенияСвойств(СтрокаСоединения,Session);
                        ЗаполнитьЗначенияСвойств(СтрокаСоединения,Лицензия);
                        СтрокаСоединения.BaseName = ОписаниеБазы.Name;
                        СтрокаСоединения.ServerName = Сервер;
                        СтрокаСоединения.MainPort = ТекущийКластер.MainPort;
                        СтрокаСоединения.Quantity = 1;
                        СтрокаСоединения.MaxUsersAll = Лицензия.MaxUsersAll;
                    КонецЕсли;    
                КонецЦикла;    
            КонецЦикла;
        КонецЦикла;
    Исключение
        ВызватьИсключение ОписаниеОшибки();
    КонецПопытки;
КонецЕсли;
1 sapphire
 
16.04.15
17:01
Так на чем валится-то?
2 DimoXa
 
17.04.15
07:34
(1) Валится при смене версии. Т.е. допустим, сначала я сформировал список лицензий по 8.3, после этого выбрал 8.2, начинаю формировать список - вываливается ошибка - Ошибка при получении значения атрибута контекста (License): Метод не найден.

Если сначала формирую по 8.2, а затем по 8.3, выпадает с ошибкой - Ошибка при вызове метода контекста (ЗаполнитьЗначенияСвойств): Недопустимое значение параметра (параметр номер '2')

У меня складывается ощущение, что это из-за незакрытого подключения происходит. Пробовал в конец добавлять Соединитель = Null, все равно не помогает. Что еще можно сделать в этой ситуации?
3 sapphire
 
17.04.15
07:50
(2) Смотри.
В принципе, всё просто:
и та, и другая ошибка возникает из-за того, что часть инфы это COMSafeArray, а не объект.
4 sapphire
 
17.04.15
07:52
т.е. если тебе откуда-то прилетает COMSafeArray оно не обязано быть объектом и к нему не применимо получение свойств и прочее.
Скорее всего это именно так.
5 sapphire
 
17.04.15
07:52
И еще, дефрагментируй код.
Одно и то же только коннектор разный.
Некрасиво.
6 DimoXa
 
17.04.15
07:52
(1) При смене 8.2 на 8.3 валится здесь:

Попытка
        Соединитель = Новый COMОбъект("V83.COMConnector");
        Соединение = Соединитель.ConnectAgent(Сервер);
        Кластеры = Соединение.GetClusters();
        МаксимальныйИндексКластеров = Кластеры.GetUpperBound();
        //Для Каждого ТекущийИндексКластера Из Кластеры.GetLowerBound() По МаксимальныйИндексКластеров  Цикл

            //ТекущийКластер = Кластеры.GetValue(ТекущийИндексКластера);

        Для Каждого ТекущийКластер Из Кластеры Цикл
            Соединение.Authenticate(ТекущийКластер, АдминистраторКластера, ПарольАдминистратора);
            Базы = Соединение.GetInfoBases(ТекущийКластер);
            МаксимальныйИндексБаз = Базы.GetUpperBound();
            //Для ТекущийИндексБазы = Базы.GetLowerBound() По МаксимальныйИндексБаз Цикл

            //    ОписаниеБазы = Базы.GetValue(ТекущийИндексБазы);

            Для Каждого ОписаниеБазы Из Базы Цикл
                Sessions = Соединение.GetInfoBaseSessions(ТекущийКластер,ОписаниеБазы);
                Для каждого Session из Sessions Цикл
                    Лицензия = Session.License;
                    Если Лицензия <> Неопределено Тогда
                        СтрокаСоединения = ТаблицаЛицензий.Добавить();
                        ЗаполнитьЗначенияСвойств(СтрокаСоединения,Session);
                        ЗаполнитьЗначенияСвойств(СтрокаСоединения,Лицензия); // Вот здесь валится
                        СтрокаСоединения.BaseName = ОписаниеБазы.Name;
                        СтрокаСоединения.ServerName = Сервер;
                        СтрокаСоединения.MainPort = ТекущийКластер.MainPort;
                        СтрокаСоединения.Quantity = 1;
                        СтрокаСоединения.MaxUsersAll = Лицензия.MaxUsersAll;
                    КонецЕсли;    
                КонецЦикла;    
            КонецЦикла;
        КонецЦикла;
    Исключение
        ВызватьИсключение ОписаниеОшибки();
    КонецПопытки;
КонецЕсли;
7 sapphire
 
17.04.15
07:53
(6) Я догадался :))))
8 DimoXa
 
17.04.15
07:54
(4) Хорошо, а как можно это обойти?
9 DimoXa
 
17.04.15
07:55
(5) Само собой, прост так проще отлаживать))
10 sapphire
 
17.04.15
07:55
(6) Убери ЗаполнитьЗначенияСвойств
11 sapphire
 
17.04.15
07:55
(9) Да ничего подобного.
Где же это проще простыню отлаживать?!
12 DimoXa
 
17.04.15
07:57
(11) Ну для меня это так) Я ж только учусь))
13 DimoXa
 
17.04.15
07:58
(10) ЗаполнитьЗначенияСвойств(СтрокаСоединения,Session);
                        ЗаполнитьЗначенияСвойств(СтрокаСоединения,Лицензия);


Это убрать?
14 sapphire
 
17.04.15
07:59
(12) Надо учиться писать код грамотно сразу.
Раз ты его вываливаешь, ну не удобно искать в такой простыне.
15 DimoXa
 
17.04.15
08:02
(14) Хорошо, будем учиться) Спасибо за помощь, буду пробовать. А ЗаполнитьЗначенияСвойств() вообще выкинуть, или их можно заменить на что-нибудь аналогичное?
16 sapphire
 
17.04.15
08:04
(13) Да.
И еще, попробуй для начала, заполнять сессии в итераторе сессий, и только потом лицензии.
Я бы сделал так:
Выделить код:
создания COM коннектора в отдельную функцию, возвращающую COM коннектор
соединения с кластером в отдельную функцию, возвращающую кластер
инициализацию таблицы значений в функцию, возвращающую таблицу значений
далее процедуры типа добавить информацию о сессии
, добавить информацию о лицензии.

Увидишь, валится будет скорее всего только в одном месте
17 sapphire
 
17.04.15
08:06
+ (16) При таком подходе копипаста не нужна, и побороть надо будет строки 3 кода, а то и меньше :)
18 DimoXa
 
17.04.15
08:09
(17) Спасибо, займусь переделкой)) По результатам отпишусь)
19 sapphire
 
17.04.15
08:11
(15) Если найдешь аналогичное - расскажешь :)))))
20 DimoXa
 
17.04.15
08:13
(19) Обязательно)) Еще раз спасибо)
Требовать и эффективности, и гибкости от одной и той же программы — все равно, что искать очаровательную и скромную жену... по-видимому, нам следует остановиться на чем-то одном из двух. Фредерик Брукс-младший