Переключение на Главную Страницу Страницы: [1] 2 3 4 ОтправитьПечать
Очень популярная тема (более 25 ответов) OleExSup- очередной костыль к семерке (число прочтений - 22296 )
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
OleExSup- очередной костыль к семерке
10. Февраля 2009 :: 16:15
Печать  
по мотивам проблемы обсуждаемой в ветке SOAP клиент на 7.7...

OleExSup - внешняя компонента расширяющая штатные возможности обращения к OLE-объектам
В настоящее время это касается только передачи массивов SAFEARRAY, в качестве параметров и возвращаемого значения, при вызове метода объекта через интерфейс IDispatch или при обращении к свойствам.
Цитата:
Раздел I

Краткая предыстория:
Иногда возникает необходимость передать массив в некоторый OLE-объект или получить массив из него.

Пример с использованием MSScriptControl.ScriptControl
Код
Выбрать все
//Создание скрипта и получение объекта
	ScrCtrl = СоздатьОбъект("ScriptControl");
	ScrCtrl.Language="VBScript";
	ScrCtrl.AddCode("
	|Function Method1()
	|  Method1 = Array(1.2345, ""_Строка_"", Date)
	|End Function
	|
	|Function Method2(Arr)
	|  For Each Item In Arr
	|    MsgBox Item
	|  Next
	|End Function
	|");
	CodeObject = ScrCtrl.Modules("Global").CodeObject;
//Вызов метода объекта
	Массив = CodeObject.Method1();
 


При попытке выполнить такой код получим исключение на последней строке с описанием ошибки:
"Тип переменой не поддерживается".
Оно и понятно - v7.7 не умеет хранить в своих переменных массивы типа SAFEARRAY (в отличии, кстати, от v8.X)

Вывод: нужно во-первых реализовать объект-контейнер массива.
Во-вторых реализовать возможность вызова методов IDispatch умеющую обращаться с этим контейнером.

Цитата:
Раздел II
Класс OleSafeArray
....

Цитата:
Раздел III
Класс OLEExSup
....

Цитата:
Раздел IV

Что получили.
Изменив вызов метода в коде из Раздела I получаем, изменяем и предаем массив.
Код
Выбрать все
//Вызов метода объекта
	OLEExSup = СоздатьОбъект("OLEExSup");
	Массив = OLEExSup.InvokeOLEMethod(CodeObject, "Method1");
	Для Инд = Массив.GetLBound() По Массив.GetUBound() Цикл
		Значение = Массив.GetValue(Инд);
		Сообщить(Значение);
		Массив.SetValue(Инд, Значение+1);
	КонецЦикла;
	OLEExSup.InvokeOLEMethod(CodeObject, "Method2", Массив); 


« Последняя редакция: 09. Февраля 2013 :: 05:33 - trad »  

OLEExSup_001.zip ( 34 KB | Загрузки )

1&&2&&3
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #1 - 10. Февраля 2009 :: 18:02
Печать  
А есть ли возможность получить массив в ТЗ сразу, как это делает
метод ВыполнитьИнструкцию() ? (сравнимый с ним по скорости)
В примере вроде обход по циклу.

P.S.  Можно тогда писать com-сервер и получать данные в 1С, если в сервере есть метод возвращающий массив.
http://www.1cpp.ru/forum/YaBB.pl?num=1216110955/6#6
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #2 - 11. Февраля 2009 :: 06:15
Печать  
kiruha писал(а) 10. Февраля 2009 :: 18:02:
А есть ли возможность получить массив в ТЗ сразу, как это делает
метод ВыполнитьИнструкцию() ? (сравнимый с ним по скорости)

Предложи принцип перегрузки N-мерного массива в ТЗ.
  

1&&2&&3
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #3 - 11. Февраля 2009 :: 06:19
Печать  
kiruha писал(а) 10. Февраля 2009 :: 18:02:
P.S.  Можно тогда писать com-сервер и получать данные в 1С, если в сервере есть метод возвращающий массив.
собственно для этого и сделаны OleExSup+OleSafeArray

kiruha писал(а) 10. Февраля 2009 :: 18:02:
думаю для начала стоит проверить такой код:
Код
Выбрать все
OLEExSup=CreateObject("OLEExSup");
ComServer=CreateObject("myserver.t1")
myArray=OLEExSup.InvokeOLEMethod(ComServer, "GetMyArray"); 

  

1&&2&&3
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #4 - 11. Февраля 2009 :: 08:28
Печать  
trad писал(а) 11. Февраля 2009 :: 06:19:
kiruha писал(а) 10. Февраля 2009 :: 18:02:
P.S.  Можно тогда писать com-сервер и получать данные в 1С, если в сервере есть метод возвращающий массив.
собственно для этого и сделаны OleExSup+OleSafeArray

kiruha писал(а) 10. Февраля 2009 :: 18:02:
думаю для начала стоит проверить такой код:
Код
Выбрать все
OLEExSup=CreateObject("OLEExSup");
ComServer=CreateObject("myserver.t1")
myArray=OLEExSup.InvokeOLEMethod(ComServer, "GetMyArray"); 



Отработало на ура - правильно и быстро.
(вывел дополнительно данные в цикле)
Видимо метод подходит для работы с произвольными com-серверами.

Как двумерный массив выводить?

P.S> Непонятный эффект - при первой загрузке компоненты окно 1С стало неактивным.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #5 - 11. Февраля 2009 :: 08:52
Печать  
trad писал(а) 11. Февраля 2009 :: 06:15:
kiruha писал(а) 10. Февраля 2009 :: 18:02:
А есть ли возможность получить массив в ТЗ сразу, как это делает
метод ВыполнитьИнструкцию() ? (сравнимый с ним по скорости)

Предложи принцип перегрузки N-мерного массива в ТЗ.


Сам я не писал компонент никогда - вот Dmitro для ADO делал выгрузку в ТЗ
GameWithFire
Обсуждение компоненты
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #6 - 11. Февраля 2009 :: 09:04
Печать  
kiruha писал(а) 11. Февраля 2009 :: 08:28:
Как двумерный массив выводить?
ну вы блин даете...

Вывод двумерного массива:
Код
Выбрать все
Для Инд1=Массив.GetLBound(1) По Массив.GetUBound(1) Цикл
	Для Инд2=Массив.GetLBound(2) По Массив.GetUBound(2) Цикл
		Сообщить(Массив.GetValue(Инд1,Инд2));
	КонецЦикла;
КонецЦикла;
 

  

1&&2&&3
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #7 - 11. Февраля 2009 :: 09:09
Печать  
Обход N-мерного массива (рекурсивный, три варианта)
Код
Выбрать все
Процедура ОбойтиМассив1(Массив, Измерение=1, Индексы="")
	Если Измерение = 1 Тогда
		Индексы = СоздатьОбъект("СписокЗначений");
	КонецЕсли;
	Если Индексы.РазмерСписка()<Измерение Тогда
		Индексы.ДобавитьЗначение("");
	КонецЕсли;
	Для Инд = Массив.GetLBound(Измерение) По Массив.GetUBound(Измерение) Цикл
		Индексы.УстановитьЗначение(Измерение, Инд);
		Если Измерение < Массив.GetDim() Тогда
			ОбойтиМассив1(Массив, Измерение+1, Индексы);
		Иначе
			Значение = Массив.GetValue(Индексы);
			Сообщить(ТипЗначенияСтр(Значение)+" "+Значение);
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Процедура ОбойтиМассив2(Массив, Измерение=1, Индексы="")
	Если Измерение = 1 Тогда
		Индексы = СоздатьОбъект("ТаблицаЗначений");
		Индексы.КоличествоКолонок(1);
		Индексы.КоличествоСтрок(Массив.GetDim());
	КонецЕсли;
	Для Инд = Массив.GetLBound(Измерение) По Массив.GetUBound(Измерение) Цикл
		Индексы.УстановитьЗначение(Измерение, 1, Инд);
		Если Измерение < Массив.GetDim() Тогда
			ОбойтиМассив2(Массив, Измерение+1, Индексы);
		Иначе
			Значение = Массив.GetValue(Индексы);
			Сообщить(ТипЗначенияСтр(Значение)+" "+Значение);
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Процедура ОбойтиМассив3(Массив, Измерение=1, Индексы="")
	Если Измерение = 1 Тогда
		Индексы = СоздатьОбъект("OLESafeArray");
		Индексы.Create(Индексы.VarTypes.VT_I2, Массив.GetDim());
	КонецЕсли;
	Для Инд = Массив.GetLBound(Измерение) По Массив.GetUBound(Измерение) Цикл
		Индексы.SetValue(Измерение-1, Инд);
		Если Измерение < Массив.GetDim() Тогда
			ОбойтиМассив3(Массив, Измерение+1, Индексы);
		Иначе
			Значение = Массив.GetValue(Индексы);
			Сообщить(ТипЗначенияСтр(Значение)+" "+Значение);
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

ОбойтиМассив1(Массив);
ОбойтиМассив2(Массив);
ОбойтиМассив3(Массив);
 

  

1&&2&&3
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #8 - 11. Февраля 2009 :: 09:13
Печать  
kiruha писал(а) 11. Февраля 2009 :: 08:28:
P.S> Непонятный эффект - при первой загрузке компоненты окно 1С стало неактивным.

уверен что это связано с компонентой?
  

1&&2&&3
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #9 - 11. Февраля 2009 :: 09:15
Печать  
kiruha писал(а) 11. Февраля 2009 :: 08:52:
Сам я не писал компонент никогда - вот Dmitro для ADO делал выгрузку в ТЗ

что касается GameWithFire...
Разницу между древовидными и многомерными структурами данных чувствуешь?
  

1&&2&&3
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #10 - 11. Февраля 2009 :: 09:23
Печать  
trad писал(а) 11. Февраля 2009 :: 09:13:
kiruha писал(а) 11. Февраля 2009 :: 08:28:
P.S> Непонятный эффект - при первой загрузке компоненты окно 1С стало неактивным.

уверен что это связано с компонентой?


Повторить не получилось.
Но вспоминаю, что при работе с com (например V77.Application  ) 1С иногда теряет фокус.
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #11 - 11. Февраля 2009 :: 09:26
Печать  
kiruha писал(а) 11. Февраля 2009 :: 09:23:
trad писал(а) 11. Февраля 2009 :: 09:13:
kiruha писал(а) 11. Февраля 2009 :: 08:28:
P.S> Непонятный эффект - при первой загрузке компоненты окно 1С стало неактивным.

уверен что это связано с компонентой?


Повторить не получилось.
Но вспоминаю, что при работе с com (например V77.Application  ) 1С иногда теряет фокус.

не исключаю возможности такого поведение, но оно скорее связано с работой OLE-сервера, а не этой компоненты.
  

1&&2&&3
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #12 - 11. Февраля 2009 :: 09:49
Печать  
Провел тест обхода массива - у меня получилось
0.032 сек на чтение 3000 значений - достаточно мало - можно конструировать сервер и без ТЗ  Улыбка
Большой фэнкс за разработку  Улыбка
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #13 - 11. Февраля 2009 :: 10:03
Печать  
kiruha писал(а) 11. Февраля 2009 :: 09:49:
Провел тест обхода массива - у меня получилось
0.032 сек на чтение 3000 значений - достаточно мало - можно конструировать сервер и без ТЗ  Улыбка

Нужно сказать что при получении массива от OLE-сервера данные не копируются в OleSafeArray. OleSafeArray только агрегирует указатель на массив и лочит его. И получение данных происходит непосредственно из первично размещенного массива.
  

1&&2&&3
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: OleExSup (beta) - очередной костыль к семерке
Ответ #14 - 11. Февраля 2009 :: 13:33
Печать  
kiruha писал(а) 11. Февраля 2009 :: 08:52:
Сам я не писал компонент никогда - вот Dmitro для ADO делал выгрузку в ТЗ
GameWithFire
Обсуждение компоненты

Собственно причем тут GameWithFire? ADO ведь не возвращает результат запроса в виде SafeArray. ADO возвращает значение длинного (BLOB) поля в виде SafeArray.

В виде SafeArray(VT_UI1) в OLE обычно обмениваются двоичными данными (картинки, тамбнейлы например, и прочая такая хрень), так что желательно иметь метод выгрузки в файл, или передачу в конструктор прикладного объекта (Картинка, ДвоичныеДанные например), чего 8ка кстати не умеет.
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 3 4
ОтправитьПечать