![]() |
![]() |
![]() |
|
COMConnector + VB.NET 2010 , Проблема с функцией "Тип()" | ☑ | ||
---|---|---|---|---|
0
Kyrill_F
03.02.16
✎
12:11
|
Здравствуйте.
Пытаюсь работать с 1С 8.3 через ComConnector (Бухучет 3.0) из VB.NET. А именно - нужно сделать запрос и получить результаты. В принципе все получается, запрос работает, данные возвращаются и т.д. Но есть проблема. Мне нужно определить тип данных в каждой колонке результата. Если я правильно понимаю, дла этого нужно использовать свойство СодержитТип(). Т.е. для первой колонки результата нужно проверять Запрос.Выполнить.Колонки.Получить(0).СодержитТип(Тип("НазваниеТипа")) Для того, чтобы это сделать, нужно сначала получить значение Тип("НазваниеТипа"), а потом уже передать его свойству СодержитТип() Вот в этом и проблема. У меня не получается задействовать функцию Тип() через COM Вот упрощенный кусок кода. Полный код с запросом не привожу чтобы не путуать, т.к. Функция "Тип" должна работать и сама по себе. Dim ConnectionString as String="....." Dim con As New COMConnector Dim BuhRoot As Object = con.Connect(connectionString) MsgBox(BuhRoot.NewObject("СистемнаяИнформация").ВерсияПриложения()) <-- тест подключения, все ок Dim TestType as Object = BuhRoot.Тип("Число") <-- Здесь возникает ошибка Public member 'Тип' on type '_ComObject' not found Пробовал через InvokeMethod - та же ерунда, не найдено. Подскажите, пожалуйста, как получить это проклятое знчение? Может быть, есть какое-то другое представление, например константа, для описания типов "Строка", "Дата", "Число", чтобы подсунуть в качестве аргумента СодержитТип() ? Спасибо. |
|||
1
mehfk
03.02.16
✎
12:14
|
Type
|
|||
2
Serginio1
03.02.16
✎
12:18
|
Используйте внешние отчеты Как через оле задать отбор?
|
|||
3
DmitrO
03.02.16
✎
12:32
|
(0)функцию Тип через COM вызвать не удастся.
Дело в том что через COM доступны только "функции глобального контекста", и недоступны "встроенные функции". Это документировано. Встроенные функции это СокрЛ, СокрП, СтрДлина и т.п. самые простые, которые вызывать в общем-то незачем. К сожалению Тип это тоже встроенная функция. Раньше в синтакс-помощнике было видно какие функции у чему относятся, теперь это не видно. |
|||
4
Карупян
03.02.16
✎
12:38
|
ВычислитьВыражение(Выражение) в базе - это ППЦ какая дыра в безопасности
|
|||
5
Kyrill_F
03.02.16
✎
12:39
|
(1) Пробовал, та же ошибка.
(3) Нда... Есть идея, как обойти проблему. У меня принципиальное ограничение - не лезть в конфигурацию. |
|||
6
DmitrO
03.02.16
✎
12:39
|
Однако значение типа Тип через COM получить можно. Теми или иными способами.
Например используя объект ОписаниеТипов: Описание = Новый ОписаниеТипов("СправочникСсылка.Номенклатура"); ТипНоменклатура = Описание.Типы().Получить(0); |
|||
7
Serginio1
03.02.16
✎
12:40
|
(4) Внешние отчеты и так дыра
(5) Смотри 2 и будет тебе счастье |
|||
8
Карупян
03.02.16
✎
12:41
|
Вот пример
v8: не получается через COM получить Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекци COMCоединение.NewObject("ОписаниеТипов","ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений").Типы().Получить(0) |
|||
9
Kyrill_F
03.02.16
✎
12:41
|
(6) Меня именно простые типыф колонок интересуют ("Строка", "Число", "Дата")
|
|||
10
Kyrill_F
03.02.16
✎
12:42
|
(8) Не уверен, что понял, но попробую.
2 All забыл сказать, я не спец по 1С :) |
|||
11
DmitrO
03.02.16
✎
12:46
|
(9)
Dim TestType as Object = BuhRoot.NewObject("ОписаниеТипов", "Число").Типы().Получить(0) |
|||
12
Kyrill_F
03.02.16
✎
12:53
|
(11) (8) Спасибо огромное! Сейчас попробую. Вчитался в справочник, тоже увидел, что конструктор ОписаниеТипов допускает передачу типа в виде строки. Должно сработать.
|
|||
13
Kyrill_F
03.02.16
✎
16:01
|
Сработало.
Вот какая функция получилась, может пригодится кому... Всем спасибо! ----------------- ''' <summary> ''' Выполнение запроса в 1С ''' </summary> ''' <param name="QueryText">Текст запроса на языке запросов 1С</param> ''' <returns>Возвращает результат запроса в виде System.Data.DataSet c единственной таблицей внутри</returns> ''' <remarks>Перед вызовом должен существовать корневой объект 1С в переменной BuhRoot</remarks> Public Function ExecuteQuery(QueryText As String) As DataSet Dim ResultDataSet As New DataSet Dim ResultTable As DataTable = ResultDataSet.Tables.Add Dim BuhTypeStr As Object = GetBuhType("Строка") Dim BuhTypeNum As Object = GetBuhType("Число") Dim BuhTypeDat As Object = GetBuhType("Дата") Dim BuhQuery As Object = BuhRoot.NewObject("Запрос") BuhQuery.Текст = QueryText Dim BuhExecQuery As Object = BuhQuery.Выполнить() Dim BuhResultColumns As Object = BuhExecQuery.Колонки() Dim BuhColumnCount As Integer = BuhResultColumns.Количество() Dim BuhCurrentColumn As Object Dim BuhColumnTypes As Object Dim NewDataRow As DataRow Dim ColumnType As System.Type For idx As Integer = 0 To BuhColumnCount - 1 BuhCurrentColumn = BuhResultColumns.Получить(idx) LogWrite(BuhCurrentColumn.Имя) BuhColumnTypes = BuhCurrentColumn.ТипЗначения With BuhColumnTypes If .СодержитТип(BuhTypeStr) Then ColumnType = Type.GetType("System.String") ElseIf .СодержитТип(BuhTypeDat) Then ColumnType = Type.GetType("System.DateTime") ElseIf .СодержитТип(BuhTypeNum) Then ColumnType = Type.GetType("System.Decimal") Else ColumnType = Type.GetType("System.String") End If End With ResultTable.Columns.Add(BuhCurrentColumn.Имя, ColumnType) Next Dim BuhResultRows As Object = BuhExecQuery.Выбрать() Dim RowCount As Integer Integer.TryParse(BuhResultRows.Количество(), RowCount) For i As Integer = 1 To RowCount BuhResultRows.Следующий() NewDataRow = ResultTable.NewRow For idx As Integer = 0 To BuhColumnCount - 1 Try NewDataRow(idx) = BuhResultRows.Получить(idx) Catch ex As Exception End Try Next ResultTable.Rows.Add(NewDataRow) Next Return ResultDataSet End Function |
|||
14
Serginio1
03.02.16
✎
16:14
|
(13) Как создать DataTable из 1С
Функция ПолучитьОписаниеТиповСтроки(ДлинаСтроки) Экспорт Возврат Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(ДлинаСтроки, ДопустимаяДлина.Переменная)); КонецФункции // ПолучитьОписаниеТиповСтроки() // Служебная функция, предназначенная для получения описания типов числа, заданной разрядности. // // Параметры: // Разрядность - число, разряд числа. // РазрядностьДробнойЧасти - число, разряд дробной части. // // Возвращаемое значение: // Объект "ОписаниеТипов" для числа указанной разрядности. // Функция ПолучитьОписаниеТиповЧисла(Разрядность, РазрядностьДробнойЧасти = 0, ЗнакЧисла = Неопределено) Экспорт Если ЗнакЧисла = Неопределено Тогда КвалификаторЧисла = Новый КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти); Иначе КвалификаторЧисла = Новый КвалификаторыЧисла(Разрядность, РазрядностьДробнойЧасти, ЗнакЧисла); КонецЕсли; Возврат Новый ОписаниеТипов("Число", КвалификаторЧисла); КонецФункции // ПолучитьОписаниеТиповЧисла() Функция ПолучитьОписаниеТиповДаты(ЧастиДаты) Экспорт Возврат Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты)); КонецФункции // ПолучитьОписаниеТиповДаты() Функция ПолучитьЗначение(Колонка,Сч) Тип=Колонка.ТипЗначения; Если Тип=Неопределено Тогда возврат сч КонецЕсли; Если тип.Типы().Количество()>1 Тогда возврат сч КонецЕсли; Тип1=тип.Типы()[0]; Если Тип1=Тип("Число") Тогда Квалификатор=Тип.КвалификаторыЧисла; Если Квалификатор.РазрядностьДробнойЧасти>0 Тогда возврат Окр(сч+1/сч,Квалификатор.РазрядностьДробнойЧасти); КонецЕсли; Разрядность=Квалификатор.Разрядность; Если Разрядность<10 Тогда возврат сч ИначеЕсли Разрядность<19 Тогда возврат сч Иначе возврат сч КонецЕсли; КонецЕсли; Если Тип1=Тип("Строка") Тогда возврат Строка(сч) ИначеЕсли Тип1=Тип("Дата") Тогда возврат ТекущаяДата() КонецЕсли; return сч КонецФункции // ПолучитьЗначение() Процедура КнопкаСформироватьНажатие(Кнопка) // Вставить содержимое обработчика. Тз=новый ТаблицаЗначений; Колонки=Тз.Колонки; Колонка=Колонки.Добавить("КолонкаЧисло",ПолучитьОписаниеТиповЧисла(9,0)); Сообщить(ПолучитьТипКолонкиДляДТ(Колонка)); Колонка=Колонки.Добавить("КолонкаЧисло2",ПолучитьОписаниеТиповЧисла(18,0)); Сообщить(ПолучитьТипКолонкиДляДТ(Колонка)); Колонка=Колонки.Добавить("КолонкаЧисло3",ПолучитьОписаниеТиповЧисла(20,0)); Сообщить(ПолучитьТипКолонкиДляДТ(Колонка)); Колонка=Колонки.Добавить("КолонкаЧисло4",ПолучитьОписаниеТиповЧисла(7,2)); Сообщить(ПолучитьТипКолонкиДляДТ(Колонка)); Колонка=Колонки.Добавить("КолонкаДата",ПолучитьОписаниеТиповДаты(ЧастиДаты.ДатаВремя)); Сообщить(ПолучитьТипКолонкиДляДТ(Колонка)); Колонка=Колонки.Добавить("КолонкаСтрока",ПолучитьОписаниеТиповСтроки(0)); Сообщить(ПолучитьТипКолонкиДляДТ(Колонка)); Для Сч=1 По 10 Цикл Стр=Тз.Добавить(); Для каждого Колонка Из Колонки Цикл Стр[Колонка.Имя]=ПолучитьЗначение(Колонка,сч); КонецЦикла; КонецЦикла; врап=новый COMОбъект("NetObjectToIDispatch45"); Дт=СоздатьДТ(врап,Тз,"MyTable"); КонецПроцедуры |
|||
15
Serginio1
03.02.16
✎
16:15
|
Функция ПолучитьТипКолонкиДляДТ(Колонка) Экспорт
Тип=Колонка.ТипЗначения; Если Тип=Неопределено Тогда возврат "System.Object" КонецЕсли; Если тип.Типы().Количество()>1 Тогда возврат "System.Object" КонецЕсли; Тип1=тип.Типы()[0]; Если Тип1=Тип("Число") Тогда Квалификатор=Тип.КвалификаторыЧисла; Если Квалификатор.РазрядностьДробнойЧасти>0 Тогда возврат "System.Decimal" КонецЕсли; Разрядность=Квалификатор.Разрядность; Если Разрядность<10 Тогда возврат "System.Int32" ИначеЕсли Разрядность<19 Тогда возврат "System.Int64" Иначе возврат "System.Decimal" КонецЕсли; КонецЕсли; Если Тип1=Тип("Строка") Тогда возврат "System.String" ИначеЕсли Тип1=Тип("Дата") Тогда возврат "System.DateTime" КонецЕсли; return "System.Object" КонецФункции Функция СоздатьДТ(врап,Тз,ИмяТаблицы) Экспорт Колонки=Тз.Колонки; myTable=Врап.СоздатьОбъект("System.Data.DataTable, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089",ИмяТаблицы); DataColumn=Врап.ПолучитьТип("System.Data.DataColumn"); Columns= myTable.Columns; КоличествоКолонок=Колонки.Количество(); Для каждого Колонка Из Колонки Цикл colItem =Врап.СоздатьОбъект(DataColumn,Колонка.Имя, Врап.ПолучитьТип(ПолучитьТипКолонкиДляДТ(Колонка))); Columns.Add(colItem); КонецЦикла; // rowArray =новый COMSafeArray("VT_VARIANT",КоличествоКолонок);//Врап.СоздатьМассив("System.Object",КоличествоКолонок); Rows=myTable.Rows; Для каждого стр Из Тз Цикл Row = myTable.NewRow(); Для сч=0 По КоличествоКолонок-1 Цикл сообщить(стр[сч]); Row.set_Item(сч,стр[сч]); КонецЦикла; Сообщить(Row.ToString()); //Rows.Add(Row); врап.ВыполнитьМетод(Rows,"Add",Row); КонецЦикла; возврат myTable КонецФункции |
|||
16
Serginio1
03.02.16
✎
16:16
|
||||
17
mehfk
03.02.16
✎
16:19
|
Что, опять?
|
|||
18
Serginio1
03.02.16
✎
16:20
|
(17) Не опять, а снова
|
|||
19
Kyrill_F
03.02.16
✎
16:36
|
(14) (14) (16) Очень познавательно, спасибо.
|
|||
20
Serginio1
03.02.16
✎
16:41
|
(19) На здоровье!
(17) Видишь, не зря опять. |
|||
21
Kyrill_F
03.02.16
✎
16:44
|
(13) Вверху забыл кусочек добавить (самый важный, из-за которго сыр-бор был)
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |