powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / [игнор отключен] [закрыт для гостей] / Как перебрать коллекцию через COM соединение
24 сообщений из 24, страница 1 из 1
Как перебрать коллекцию через COM соединение
    #37778732
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте. Получаю во внешнем приложении (написанном на C#) ссылку на объект «СправочникиМенеджер». В хелпе сказано, что это коллекция. Но вот, как ее перебрать во внешнем приложении, чтобы например, получить имена всех справочников? Методов или свойств в стиле «Количество» у этого объекта не нашел. Обертка для com-вызовов самописная, так что ссылка возвращается в типе object. Помогите, пожалуйста, если кто в курсе. Было бы интересно узнать, как поступают с коллекциями в таких случаях?
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37778794
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37778860
AHDP
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
foreach - ?
ЗЫ 7 реакторный блок - это курчатник?
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37778952
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
The Dim! спасибо за ссыль, я могу получить список справочников из метаданных, даже обработку писал для их выгрузки (по примеру правда). Но вот, как обратиться к метаданным из COM-соединения, я не представляю и так пробовал и эдак, не выходит, вдумчивое чтение справки на нужную мысль не навело.

AHDP думаю, об foreach, только как бы перебрать им результат. Пробовал преобразовать к массиву объектов, не выходит. Может быть к какому-нибудь типу интерфеса?
Простите, я просто нуб =) З.Ы. 7-реакторный блок, на самом деле это Саров, надо бы переименовать на досуге =)
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37779050
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то так...

Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
v8 = new ActiveXObject("V82.COMConnector");
Cnn = v8.Connect('File="E:\\DataBase\\СФ - оригинал";Usr="Usr";Pwd="Pwd"');

Ref = new Enumerator(Cnn.Метаданные.Справочники);

for (Ref.moveFirst();!Ref.atEnd();Ref.moveNext()){
	
	r = Ref.item();
	
	WScript.Echo(r.Имя);
	
}
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37779056
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это был JScript
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37779145
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
The Dim! , спасибо большое, мысль понятна. Просто не знаю, как попросить эти самые "Метаданные". У меня используется позднее связывание и просто через точку в тексте программы члены 1С-а не видно. А исполняя что-то вроде:
Код: c#
1.
connection1C.GetType().InvokeMember("Метаданные", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static, null, connection1C, null);

получаю эксепшн, об отсутствии такого члена.
Попробовал выполнить метод NewObject с параметром "СправочникиМенеджер" результат пришел, а перебрать его никак. Один конкретный справочник по имени выудить могу, а так чтобы все и не зная имен заранее, не получается.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37779157
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Возможно, дело в русскоязычном написании?

Попробуйте вместо Метаданные указывать Metadata
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37779178
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Читаем хэлп.
СправочникиМенеджер (CatalogsManager)
Элементы коллекции:

СправочникМенеджер
Для объекта доступен обход коллекции посредством оператора Для каждого … Из … Цикл. При обходе выбираются менеджеры справочников.
Возможно обращение к менеджеру справочника посредством оператора [...]. В качестве аргумента передается имя справочника, как оно задано в конфигурации.

Свойства:

<Имя справочника> (<Catalog name>)

Методы:

ТипВсеСсылки (AllRefsType)

Описание:

Предназначен для управления справочниками и предоставляет доступ к значениям типа СправочникМенеджер.<Имя справочника>. Доступ к объекту осуществляется через свойство глобального контекста Справочники.

Доступность:

Сервер, толстый клиент, внешнее соединение.
Возможен обмен с сервером.
Пример:

Для каждого Справочник из Метаданные.Справочники Цикл
ИмяСправочника = Справочник.Имя;
МенеджерСправочника = Справочники[ИмяСправочника];
ВыборкаСправочника = МенеджерСправочника.Выбрать();
Если ВыборкаСправочника.Следующий() Тогда
Текст = "ru = ""В информационной базе есть заполненные справочники!"""
+ "; en = ""There are filled catalogs in the infobas!""";
Предупреждение(НСтр(Текст));
Возврат;
КонецЕсли;
КонецЦикла;


См. также:

Глобальный контекст, свойство Справочники
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37779348
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Простите, но что я должен был там увидеть? Я прочитал эту страницу два раза, но мне это ничего не дало. Использование англоязычных названий также не дает результата. А вот такое сообщение выдает среда, когда пытаюсь получить ссылку на "Метаданные" или еще на какой-нибудь объект из соединения 1С: Method 'System.__ComObject.Metadata' not found. Уже и так и сяк пробовал. При этом пытаясь получить свойство, сообщение об ошибке ровно такое же.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37779395
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из описания, следует что "СправочникиМенеджер" - это класс.
Метаданные.Справочники - это экземпляр класса"СправочникиМенеджер", созданный уже самой средой. В моем примере я создавал еще один экземпляр. Или, вернее сказать, реализация пространства имен 1С на свой лад - в виду одноименности возникает путаница. Путаница: в среде есть объект с именем "Метаданные.Справочники" и в тоже время, это "имя" можно использовать как имя класса в пространстве имен, указывая его в конструкторах.

Так же из описания следует что никаких Count() у указанного выше класса нет. Была какая-то особенность работы с перечислениями на предмет получения размерности(в JScript точно)... щас не вспомню...

Я не знаком с C# но рискну предположить, что код
Код: c#
1.
connection1C.GetType().InvokeMember("Метаданные", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static, null, connection1C, null);

пытается вызвать метод с именем "Метаданные". Но это, по локике, не метод, а свойство который возвращает экземпляр класса "Метаданные...

В примере на JSscript я обращялся к конструктору, создавая коллекцию, а вы обращаетесь к чему?
То что было написано на JS, насколько я понимаю, просто использовало составное имя как некий аналог пространства имен...

В примере кода, было
Код: javascript
1.
Ref = new Enumerator(Cnn.Метаданные.Справочники);

, вероятно поэтому вы и хотите получить ссылку на некий объект вызывая метод(?) "Метаданные" но это не метод, а свойство. Насколько я могу судить, то его вызов должен выглядеть несколько иначе.

Такие вот расужедния под конец рабочего дня...
Не думал, что пример на JScript так сложно переложить на C#.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37780874
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
The Dim! , спасибо за помощь. Получилось стребовать из COM-соединения имена справочников, но правда как-то не очень красиво.
Сначала я создал методом NewObject() , объект СправочникиМенеджер . Потом привел его к виду интерфейса IEnumerable , который позволяет перебирать коллекции с помощью foreach. Элементами коллекции является тип СправочникМенеджер , у него вызывал метод ПолучитьСсылку() , получил объект СправочникСсылка , на нем вызвал метод Метаданные и получил метаданные справочника. А уже из них выудил Имя и Синоним .

Я не понимаю, почему не могу получить ссылку на "Метаданные" системы сразу. Та строчка кода, которую привел, пытается получить свойство, об этом говорит флаг "BindingFlags.GetProperty", да и метод получения свойства работает, я же получил имена с синонимами. Пробовал и просто получить свойство "Справочники" и свойство "Метаданные" и методами их выполнить, на подключении, не получается.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37781245
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Сначала я создал методом NewObject(), объект СправочникиМенеджер. Потом привел его к виду интерфейса IEnumerable, который >> позволяет перебирать коллекции с помощью foreach. Элементами коллекции является тип СправочникМенеджер, у него вызывал >> метод ПолучитьСсылку(), получил объект СправочникСсылка, на нем вызвал метод Метаданные и получил метаданные справочника. А уже из них выудил >> Имя и Синоним.

Ну так а что смущает-то? с Элементами коллекции так и работают. Сначала создаю объект, а потом через items() обращаются. На JS тоже самое. Приведение к типу... ну так это "фишка" языка, вероятно...

Как .Net работает с COM интерфейсами вообще? Ведь .Net имеет свою виртуальную среду, вороятно, все эти сложности из-за этого. Хотя... не профильный вопрос, может в ветке по шарпу дадут разьяснения..


В э... Win32, при работе с COM, объект можно было создавать - CreateObject, а можно было получать ссылку на уже созданный ранее объект - GetObject.
В разных языка/средах реализация различна. Где-то можно указывать имя хоста на котором создавать объект и имя файла в котором содержится описание класса... а где-то только имя объекта.
Наверное, и в шарпе должна быть поддержка этого функционала. Хотя... COM для него ведь не "родной"...
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37781261
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может мы ведем речь о разном...?

В 1С есть функционал работы с метаданными. Он позволяет получить... ну что-то вроде описание классов. Естественно, ни метод вызвать, не свойство посмотреть у класса нельзя. Есть исключение - метод/свойство реализованные в модуле менеджера объекта конфигурации.

Пример создания класса по-средствам перебора объектов метаданных.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
Для каждого ВидДокумента Из Метаданные.Документы Цикл
		
		Состояние(ВидДокумента.Имя);
		
		Выборка = Документы[ВидДокумента.Имя].Выбрать();
		
		Пока Выборка.Следующий() Цикл
			
			Объект = Выборка.ПолучитьОбъект();
			Объект.Удалить();
			
		КонецЦикла;
			
	КонецЦикла;



Если нужны будут комментарии - завтра напишу.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37782116
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, я так собственно и хотел сделать что-то вроде: Метаданные.Справочники . Затем перебрать их и из элементов вытянуть Имя и Синоним. Собственно создав вручную СправочникиМенеджер и проделав все, что написал выше, это получилось. Но как я понял, я бы мог получить ссылку на метаданные справочников из метаданных среды.
Делаю подключение по COM по шагам, как в хелпе 1С-а написано:
создается менеджер COM-соединений, с помощью которого производится установка соединения;
Код: c#
1.
2.
3.
// Из кода убраны лишние try\catch-и...
Type t = Type.GetTypeFromProgID("V82.COMConnector");
object instance1C = System.Activator.CreateInstance(t);



производится обращение к методу Connect менеджера COM-соединений. Метод Connect возвращает внешнее соединение с информационной базой 1С:Предприятия 8;
Код: c#
1.
2.
3.
4.
object[] args = new object[1];
args[0] = connectionString;
connection1C = t.InvokeMember("Connect", BindingFlags.Public | BindingFlags.InvokeMethod |
                    BindingFlags.Static, null, instance1C, args);



через внешнее соединение производится обращение к допустимым методам, свойствам и объектам информационной базы, с которой установлено соединение.
Вот на этом пункте собственно и начинается работа. По идее из объекта connection1C через свойства можно получить ссылки на справочники, документы и т.п. Но по факту получается только вызвать его метод NewObject() , который, как написано в справке "создает объект, для которого предусмотрен конструктор, и возвращает ссылку на него".
К сожалению в моем случае, я не могу обращаться к свойствам в таком стиле "connection1C.Справочники.Контрагенты" (через точку). Каждый раз мне приходится исполнять InvokeMember на объекте из которого хочу вызвать метод или свойство. Например, чтобы получить ссылку на "Справочники.Контрагенты" я должен на объекте connection1C вызвать InvokeMember с параметрами (получить свойство, Справочники), на Справочниках вызывать метод InvokeMember с параметрами (получить свойство, контрагенты). Но компилятор сообщает об ошибке при попытке получить ссылку на "Справочники", говоря, что имя не существует.

Наверное, я что-то делаю не так и этот вопрос более профильный и стоит больше внимания уделить докам по COM. В любом случае, спасибо за помощь.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37783127
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jang... А вот такое сообщение выдает среда, когда пытаюсь получить ссылку на "Метаданные" или еще на какой-нибудь объект из соединения 1С: Method 'System.__ComObject.Metadata' not found...

Х.м... а почему пространство имен 'System.__ComObject.Metadata', разве так и должно быть? Наверное должно быть как-то ...connection1C.Metadata - нет?
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37783650
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
System.__ComObject это тип любого COM-объекта, среда выполняет на нем методы и свойства (если они там определены) и возвращает значения в этом типе, его можно привести к уже известному (ну, если ожидаемо например возвращается строка) и дальше уже работать. В справке 1C говориться, что результат выполнения метода Connect() является ссылка на "Внешнее соединение". И вроде как в нем уже должно быть видно все, что есть в глобальном контексте и по мимо этого метод NewObject(), который позволяет создать какой-нибудь объект, если у него есть конструктор. Фишка в том, что NewObject() я могу использовать, а что-то из глобального контекста получить фиг =(. Т.е. возможно даже теоретически не надо отдельно ссылку на "Метаданные" получать, а сразу просить свойство "Справочники" (или "Справочник") но не так, не сяк не выходит.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37787850
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
The Dim! , спасибо за помощь. Нашел решение проблемы. Я ступил, при вызове методов и свойств из глобального контекста. На самом деле все нормально. После исполнения метода Connect получаем ссылку на внешнее соединение. Прямо в нем находятся все нужные свойства и методы. Например ссылку на справочники можно получить из свойства "Справочники". Я немного в коде напортачил и не с того объекта вызывал свойства и методы, когда для NewObject, обертка была написана правильно.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37788189
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jang, было-бы не плохо привести код, потому как вы не первый кто приходит с таким вопросом - интеграция 1С и .Net.
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37788790
olegves
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
For each elem from ComObj
print elem. Property
EndFor

ComObj - объект 1С, полученный во внешнем соединении
Property - свойство элемента объекта

сори за незнание языка C#
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37788795
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
olegves, это что это?
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37788799
olegves
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
The Dim!,

это ответ на вопрос темы - как перебрать коллекцию
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37788804
The Dim!
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
olegves, язык, среда ?

ТС говорил о .Net и C#(насколько я понял), если эта пара строк решение проблемы, то почему ТС писал ну совсем иначе...
...
Рейтинг: 0 / 0
Как перебрать коллекцию через COM соединение
    #37789481
Jang
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Привет! Вот пример работы с 1С из .Net (на C#) используя позднее связывание. Возможно есть и другие, оптимальные способы, но я пока их не открыл для себя :) Конечно вызовы методов и свойств из объекта стоит спрятать внутри класса-обертки, чтобы писать чуть короче.
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
                public void WorkWith1C(string connectionString)
        {
            object obj1C = null; // Ссылка на объект 1С.
            try
            {
                Type t = Type.GetTypeFromProgID("V82.COMConnector");
                obj1C = System.Activator.CreateInstance(t); // Создаем экземпляр.
                object[] args = new object[1];
                args[0] = connectionString; // Строка подключения к БД, в качестве параметра.
                object connection1C = t.InvokeMember("Connect", BindingFlags.Public | BindingFlags.InvokeMethod |
                    BindingFlags.Static, null, obj1C, args); // Вызываем метод Connect() для создания подключения к базе 1С.
                // Для примера изменим и прочитаем константу "ЗаголовокСистемы".
                object constantsRef = connection1C.GetType().InvokeMember("Константы", BindingFlags.GetProperty, null, 
                    connection1C, null); // Данные глобального контекста доступны в объекте внешнего соединения.
                object constZagolovok = connection1C.GetType().InvokeMember("ЗаголовокСистемы", BindingFlags.GetProperty, null, 
                    constantsRef, null);
                connection1C.GetType().InvokeMember("Установить", BindingFlags.InvokeMethod, null, constZagolovok, 
                    new object[] { DateTime.Now.ToShortDateString() });
                string zagolovok = (string)connection1C.GetType().InvokeMember("Получить", BindingFlags.InvokeMethod, null, 
                    constZagolovok, null);
                MessageBox.Show(zagolovok);
                // Выполним запрос данных из справочника
                string querryText = @"ВЫБРАТЬ * ИЗ Справочник.ДоговорыКонтрагентов;";
                object[] parameters = new object[2];
                parameters[0] = "Запрос";
                parameters[1] = querryText;
                object querry = connection1C.GetType().InvokeMember("NewObject", BindingFlags.InvokeMethod, null, 
                    connection1C, parameters); // NewObject метод внешнего соединения, для создания объектов в среде 1С.
                object querryResult = connection1C.GetType().InvokeMember("Выполнить", BindingFlags.InvokeMethod, null, querry, null); 
                // Переберем колонки результата запроса.
                IEnumerable columns = (IEnumerable)connection1C.GetType().InvokeMember("Колонки", BindingFlags.GetProperty, null, 
                    querryResult, null);
                string columnName="";
                foreach (object column in columns)
                {
// Таким образом можно получить имена колонок.
                    columnName = (string)connection1C.GetType().InvokeMember("Имя", BindingFlags.GetProperty, null, column, null);
                    
                }
                // Получим результаты запроса.
                object records = connection1C.GetType().InvokeMember("Выбрать", BindingFlags.InvokeMethod, null, querryResult, null);
                // Переберем результаты.
                while ((bool)connection1C.GetType().InvokeMember("Следующий", BindingFlags.InvokeMethod, null, records, null))
                {
                    // Получаем значение ячейки.
                    object value = connection1C.GetType().InvokeMember(columnName, BindingFlags.GetProperty, null, records, null);
                    // Что-нибудь делаем с этой ценной информацией.
                }
            }
            catch (Exception ex)
            {
                string message = ex.Message;
                if (ex.InnerException != null)
                    message += Environment.NewLine + ex.InnerException.Message;

                MessageBox.Show(message);
            }
            finally 
            {
                // Уничтожаем объект 1С.
                if (obj1C != null)
                {
                    Marshal.Release(Marshal.GetIDispatchForObject(obj1C));
                    Marshal.ReleaseComObject(obj1C);
                    obj1C = null;
                }
            }
        }
...
Рейтинг: 0 / 0
24 сообщений из 24, страница 1 из 1
Форумы / [игнор отключен] [закрыт для гостей] / Как перебрать коллекцию через COM соединение
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]