![]() |
![]() |
![]() |
|
Внешняя компонента. Метод объекта не обнаружен. | ☑ | ||
---|---|---|---|---|
0
alexkozin
16.10.15
✎
10:06
|
Коллеги, приветствую!
Встал в ступор. По шаблону "накатал" внешнюю компоненту. Инициализируется нормально, никаких проблем, IInitDone отрабатывается нормально, но вот беда - ни одного определенного мной метода 1С не видит. То есть в компоненте есть мой метод methTest, но 1С при вызове метода ВК.methTest() пишет "Метод объекта не обнаружен". Компонента зарегистрирована через regasm и инициализирована в 1С без ошибок. Платформа 1с 8.2.14.533 Куда копать? Заранее спасибо! |
|||
1
alexkozin
19.10.15
✎
08:49
|
Уп))
|
|||
2
Кирпич
19.10.15
✎
08:53
|
(0) смотреть на свой код пока не вскочишь и воскликнешь: "о боже! неужели это я мог допустить такую глупую ошибку!"
|
|||
3
alexkozin
19.10.15
✎
08:55
|
(2) Дык вроде как всё просмотрел таки..... Всё прям по фен шую
|
|||
4
Кирпич
19.10.15
✎
09:00
|
(3) ну тогда выкладывай код. добрый дядя тебе найдет твой косяк.
|
|||
5
alexkozin
19.10.15
✎
19:17
|
Imports System.Runtime.InteropServices
Imports System.Windows.Forms 'Сгенерируйте уникальный идентификатор компоненты (меню Tools - Create GUID) 'Укажите ProgID компоненты (по этому имени ее будет находить 1С). 'Пример регистрации компоненты в системном реестре, чтобы ее смогла найти 1С: 'regasm.exe vk_XmlTextReaderWriter.dll /codebase <ComVisible(True), Guid("ACA5E6E0-DA61-4a05-8024-F0002D0E9616"), ProgId("AddIn.vk_OLE")> _ Public Class vk_OLE Implements IInitDone Implements ILanguageExtender Const c_AddinName As String = "vk_OLE" #Region "IInitDone implementation" '///////////////////////////////////////////////////////////////////////////////// Public Sub New() ' Обязательно для COM инициализации 'Вызывается при начале работы внешней компоненты (2 раза) End Sub '///////////////////////////////////////////////////////////////////////////////// Private Sub Init(<MarshalAs(UnmanagedType.IDispatch)> ByVal pConnection As Object) Implements IInitDone.Init 'Вызывается при начале работы внешней компоненты (2 раза) V7Data.V7Object = pConnection End Sub '///////////////////////////////////////////////////////////////////////////////// Private Sub Done() Implements IInitDone.Done 'Вызывается при завершении работы внешней компоненты (2 раза) MessageBox.Show("Завершение работы ВК") obj1C = Nothing V7Data.V7Object = Nothing GC.Collect() GC.WaitForPendingFinalizers() End Sub '///////////////////////////////////////////////////////////////////////////////// Private Sub GetInfo(ByRef pInfo() As Object) Implements IInitDone.GetInfo pInfo.SetValue("2000", 0) End Sub '///////////////////////////////////////////////////////////////////////////////// Sub RegisterExtensionAs(ByRef bstrExtensionName As String) Implements ILanguageExtender.RegisterExtensionAs bstrExtensionName = c_AddinName End Sub #End Region #Region "Переменные" Dim obj1C As Object 'Объект 1С Dim g_flagInit As Boolean 'Признак, что инициализация obj1C уже прошла '<MarshalAs(UnmanagedType.IDispatch)> Dim g_var As Object Dim g_var As Object #End Region #Region "Свойства" '///////////////////////////////////////////////////////////////////////////////// Enum Props 'Числовые идентификаторы свойств внешней компоненты LastProp = 0 End Enum '///////////////////////////////////////////////////////////////////////////////// Sub GetNProps(ByRef plProps As Integer) Implements ILanguageExtender.GetNProps 'Здесь 1С получает количество доступных из ВК свойств plProps = Props.LastProp End Sub '///////////////////////////////////////////////////////////////////////////////// Sub FindProp(ByVal bstrPropName As String, ByRef plPropNum As Integer) Implements ILanguageExtender.FindProp 'Здесь 1С ищет числовой идентификатор свойства по его текстовому имени Select Case bstrPropName End Select End Sub '///////////////////////////////////////////////////////////////////////////////// Sub GetPropName(ByVal lPropNum As Integer, ByVal lPropAlias As Integer, ByRef pbstrPropName As String) Implements ILanguageExtender.GetPropName 'Здесь 1С (теоретически) узнает имя свойства по его идентификатору. lPropAlias - номер псевдонима pbstrPropName = "" End Sub '///////////////////////////////////////////////////////////////////////////////// 'Функция генерирует исключение в 1С Sub Raise1CException(ByVal s As String) Dim ei As ExcepInfo ei.wCode = 1004 'Вид пиктограммы '1000 - нет значка '1001 - обычный значок '1002 - красный значок ! '1003 - красный значок !! '1004 - красный значок !!! '1005 - зеленый значок i '1006 - красный значок err '1007 - Окно предупреждения "Внимание" '1008 - Окно предупреждения "Информация" '1009 - Окно предупреждения "Ошибка" ei.scode = 1 'Генерируем ошибку времени исполнения ei.bstrDescription = s 'Сообщение ei.bstrSource = c_AddinName V7Data.ErrorLog.AddError(c_AddinName, ei) End Sub '///////////////////////////////////////////////////////////////////////////////// Sub GetPropVal(ByVal lPropNum As Integer, ByRef pvarPropVal As Object) Implements ILanguageExtender.GetPropVal 'Здесь 1С узнает значения свойств Try pvarPropVal = Nothing Select Case lPropNum End Select Catch ex As Exception 'Обработчик исключительных ситуаций (ошибок) Raise1CException(ex.Message) End Try End Sub '///////////////////////////////////////////////////////////////////////////////// Sub SetPropVal(ByVal lPropNum As Integer, ByRef varPropVal As Object) Implements ILanguageExtender.SetPropVal 'Здесь 1С изменяет значения свойств Select Case lPropNum '///////////////////////////////////////////////////////// 'Реализуем изменение свойства "Отступ" End Select End Sub '///////////////////////////////////////////////////////////////////////////////// Sub IsPropReadable(ByVal lPropNum As Integer, ByRef pboolPropRead As Boolean) Implements ILanguageExtender.IsPropReadable 'Здесь 1С узнает, какие свойства доступны для чтения pboolPropRead = True ' Все свойства доступны для чтения End Sub '///////////////////////////////////////////////////////////////////////////////// Sub IsPropWritable(ByVal lPropNum As Integer, ByRef pboolPropWrite As Boolean) Implements ILanguageExtender.IsPropWritable 'Здесь 1С узнает, какие свойства доступны для записи pboolPropWrite = True ' Все свойства доступны для записи End Sub #End Region #Region "Методы" '///////////////////////////////////////////////////////////////////////////////// Enum Methods 'Числовые идентификаторы методов (процедур или функций) внешней компоненты methTest = 0 methGetValue = 1 methSetValue = 2 methClose = 3 LastMethod = 4 End Enum '///////////////////////////////////////////////////////////////////////////////// Sub GetNMethods(ByRef plMethods As Integer) Implements ILanguageExtender.GetNMethods plMethods = Methods.LastMethod End Sub '///////////////////////////////////////////////////////////////////////////////// Sub FindMethod(ByVal bstrMethodName As String, ByRef plMethodNum As Integer) Implements ILanguageExtender.FindMethod 'Здесь 1С получает числовой идентификатор метода (процедуры или функции) по имени (названию) процедуры или функции plMethodNum = -1 Select Case bstrMethodName Case "Test", "Тест" plMethodNum = Methods.methTest Case "GetValue", "ПолучитьЗначение" plMethodNum = Methods.methGetValue Case "SetValue", "УстановитьЗначение" plMethodNum = Methods.methSetValue Case "Close", "Закрыть" plMethodNum = Methods.methClose End Select End Sub '///////////////////////////////////////////////////////////////////////////////// Sub GetMethodName(ByVal lMethodNum As Integer, ByVal lMethodAlias As Integer, ByRef pbstrMethodName As String) Implements ILanguageExtender.GetMethodName 'Здесь 1С (теоретически) получает имя метода по его идентификатору. lMethodAlias - номер синонима. pbstrMethodName = "" End Sub '///////////////////////////////////////////////////////////////////////////////// Sub GetNParams(ByVal lMethodNum As Integer, ByRef plParams As Integer) Implements ILanguageExtender.GetNParams 'Здесь 1С получает количество параметров у метода (процедуры или функции) Select Case lMethodNum Case Methods.methTest plParams = 0 Case Methods.methGetValue plParams = 0 Case Methods.methSetValue plParams = 1 Case Methods.methClose plParams = 0 End Select End Sub '///////////////////////////////////////////////////////////////////////////////// Sub GetParamDefValue(ByVal lMethodNum As Integer, ByVal lParamNum As Integer, ByRef pvarParamDefValue As Object) Implements ILanguageExtender.GetParamDefValue 'Здесь 1С получает значения параметров процедуры или функции по умолчанию pvarParamDefValue = Nothing 'Нет значений по умолчанию End Sub '///////////////////////////////////////////////////////////////////////////////// Sub HasRetVal(ByVal lMethodNum As Integer, ByRef pboolRetValue As Boolean) Implements ILanguageExtender.HasRetVal 'Здесь 1С узнает, возвращает ли метод значение (т.е. является процедурой или функцией) pboolRetValue = True 'Все методы у нас будут функциями (т.е. будут возвращать значение). End Sub '///////////////////////////////////////////////////////////////////////////////// Sub CallAsProc(ByVal lMethodNum As Integer, ByRef paParams As System.Array) Implements ILanguageExtender.CallAsProc 'Здесь внешняя компонента выполняет код процедур. А процедур у нас нет. End Sub '///////////////////////////////////////////////////////////////////////////////// Sub CallAsFunc(ByVal lMethodNum As Integer, _ ByRef pvarRetValue As Object, _ <MarshalAs(UnmanagedType.IDispatch)> ByRef paParams As System.Array) _ Implements ILanguageExtender.CallAsFunc 'Здесь внешняя компонента выполняет код функций. Try pvarRetValue = 0 'Возвращаемое значение метода для 1С Select Case lMethodNum 'Порядковый номер метода '////////////////////////////////////////////////////////// Case Methods.methTest 'Реализуем метод для тестирования доступа к 1С If g_flagInit = False Then obj1C = V7Data.V7Object.AppDispatch Marshal.Release(Marshal.GetIDispatchForObject(obj1C)) g_flagInit = True End If Dim obj0 As Object obj0 = obj1C.CreateObject("Справочник.Товары") obj0.ВыбратьЭлементы() obj0.ПолучитьЭлемент() System.Windows.Forms.MessageBox.Show("Товар: " + obj0.Наименование) obj0 = Nothing GC.Collect() GC.WaitForPendingFinalizers() Case Methods.methSetValue 'Реализуем метод для установки значения из 1С в внешнюю компоненту g_var = paParams.GetValue(0) Case Methods.methGetValue 'Реализуем метод для чтения значения в 1С из внешней компоненты pvarRetValue = g_var Case Methods.methClose 'Реализуем метод для очистки переменной (иначе 1С зависает в памяти) 'Marshal.Release(Marshal.GetIDispatchForObject(g_var)) g_var = Nothing GC.Collect() GC.WaitForPendingFinalizers() End Select Catch ex As Exception 'Обрабатываем исключение (ошибку) Raise1CException(ex.Message) End Try End Sub #End Region End Class |
|||
6
alexkozin
19.10.15
✎
19:19
|
Собсно вот класс.... Абсолютно как в книжке))
Вот форма: Процедура ПриОткрытии() ИмяВК="AddIn.vk_OLE"; ок=ПодключитьВнешнююКомпоненту(ИмяВК); Если ок=0 Тогда Сообщить("Не удалось подключить компоненту "+ИмяВК); КонецЕсли; ВК = Новый COMОбъект(ИмяВК); КонецПроцедуры Процедура КнопкаВыполнитьНажатие(Кнопка) Сообщить(ВК.methTest()); КонецПроцедуры |
|||
7
alexkozin
19.10.15
✎
19:20
|
А вот ошибка:
{Форма.Форма.Форма(8)}: Метод объекта не обнаружен (methTest) Сообщить(ВК.methTest()); |
|||
8
Serginio1
19.10.15
✎
20:36
|
А зачем тебе ВК?
посмотри http://catalog.mista.ru/public/238584/ Там кстати реализована ВК для получения глобального контекста и интерфейсов |
|||
9
hhhh
19.10.15
✎
21:59
|
(7) в процедуду ПриОткрытии() попадает вообще? В отладчике смотрел?
|
|||
10
alexkozin
20.10.15
✎
06:59
|
(9) Здарова!
Да, попадает и загрузка и выгрузка компоненты робит отлично. IInitDone отрабатывает без проблем. |
|||
11
alexkozin
20.10.15
✎
07:00
|
(8) дык научиться хочу)) Кстати, спс за ссылку, обязательно ознакомлюсь, но для начала хотелось бы разобраться с ВК.
|
|||
12
Serginio1
20.10.15
✎
08:21
|
Так для того, что бы научиться, нужно посмотреть на уже существующие решения. Там есть и реализация ВК
|
|||
13
Кирпич
20.10.15
✎
08:25
|
Sub GetMethodName(ByVal lMethodNum As Integer, ByVal lMethodAlias As Integer, ByRef pbstrMethodName As String) Implements ILanguageExtender.GetMethodName
pbstrMethodName = "" End Sub это что за фигня? здесь ты должен возвращать имя метода по его номеру |
|||
14
Маратыч
20.10.15
✎
08:27
|
Погодь, у тебя FindMethod что искать пытается, посмотри. Ты ей пихаешь methTest, а у нее в Case такого нет, есть только Test. Плюс (13) еще.
|
|||
15
Serginio1
20.10.15
✎
08:32
|
Посмотри http://rsdn.ru/forum/src/1303039.1
|
|||
16
Serginio1
20.10.15
✎
11:08
|
14 Ну и в отладчике посмотри
FindMethod CallAsFunc |
|||
17
alexkozin
20.10.15
✎
21:17
|
(16) приколюха в том что в отладчике да данных функций почему-то не доходит. Последний отрабатываемый метод это ILanguageExtender-овский RegisterExtensionAs
Sub RegisterExtensionAs(ByRef bstrExtensionName As String) Implements ILanguageExtender.RegisterExtensionAs bstrExtensionName = c_AddinName End Sub и усё.... даьше как будто выходит из отладчика |
|||
18
alexkozin
20.10.15
✎
21:20
|
(14) вписал таки
'///////////////////////////////////////////////////////////////////////////////// Sub FindMethod(ByVal bstrMethodName As String, ByRef plMethodNum As Integer) Implements ILanguageExtender.FindMethod 'Здесь 1С получает числовой идентификатор метода (процедуры или функции) по имени (названию) процедуры или функции plMethodNum = -1 Select Case bstrMethodName Case "methTest", "Тест" plMethodNum = Methods.methTest Case "methGetValue", "ПолучитьЗначение" plMethodNum = Methods.methGetValue Case "methSetValue", "УстановитьЗначение" plMethodNum = Methods.methSetValue Case "methClose", "Закрыть" plMethodNum = Methods.methClose End Select End Sub (13) доделал, но один фиг толку 0 '///////////////////////////////////////////////////////////////////////////////// Sub GetMethodName(ByVal lMethodNum As Integer, ByVal lMethodAlias As Integer, ByRef pbstrMethodName As String) Implements ILanguageExtender.GetMethodName 'Здесь 1С (теоретически) получает имя метода по его идентификатору. lMethodAlias - номер синонима. pbstrMethodName = "" Select Case lMethodNum Case Methods.methTest pbstrMethodName = "methTest" End Select End Sub |
|||
19
alexkozin
20.10.15
✎
21:21
|
Хожу отладчиком. Короче почему-то не заходит в методы FindMethod и т.д. В общем ооладчик не хотит ходить по методом интерфейса ILanguageExtender :(
|
|||
20
ProgAL
20.10.15
✎
21:28
|
У тебя ГУИД ком объекта ILanguageExtender должен быть точно таким как в шаблоек внешних компонент в примерах на диске ИТС. И у интерфейса IInitDone, IAsyncEvent, IStatusLine тоже.
|
|||
21
ProgAL
20.10.15
✎
21:29
|
Вероятно, причина именно в этом. 1с просто не видит твои интерфейсы, т к тыкается через кваериинтерфейс в предопределенные значения ГУИДов, а твои ГУИДы другие.
|
|||
22
alexkozin
20.10.15
✎
21:40
|
(21) Клянуся ГУИД как надо именно такой, с другим даже компонента не регится AB634003-F13D-11d0-A459-004095E1DAEA
:( |
|||
23
alexkozin
20.10.15
✎
21:47
|
(21) + в метод RegisterExtensionAs-то нормально заходит.
|
|||
24
alexkozin
20.10.15
✎
21:49
|
Чудеса, ребята :(
|
|||
25
Serginio1
20.10.15
✎
21:55
|
А c_AddinName="vk_OLE"
|
|||
26
Serginio1
20.10.15
✎
21:56
|
ВК = Новый(ИмяВК);
|
|||
27
Serginio1
20.10.15
✎
21:58
|
Бери примеры и не мучайся.
|
|||
28
alexkozin
20.10.15
✎
21:59
|
(26) Ага, так и делаю. Создается нормально, отладчиком нормально ходит по интерфейсу IInitDone и по первому методу интерфейса ILanguageExtender "RegisterExtensionAs", но вот в остальные методы отладчик не идет почему-то. Осталось с помощью коллег выяснить почему)
(27) Будешь смеяться, но это пример)) |
|||
29
alexkozin
20.10.15
✎
22:00
|
(27) мне критично именно на VB.NET, а это как раз пример VB.NET
|
|||
30
Serginio1
20.10.15
✎
22:04
|
(29) А в чем разница? Можешь код сконвертировать.
|
|||
31
Кирпич
20.10.15
✎
22:15
|
(24) какие нафиг чудеса?! Просто понятия нет никпкого. Когда будет понятие, сам свои ошибки видеть будешь, а не искать их через мисту методом тыка.
|
|||
32
Serginio1
20.10.15
✎
22:16
|
30+ Берешь ILSpy выбираешь свой любимый VB и декомпилируешь.
|
|||
33
Serginio1
20.10.15
✎
22:18
|
28 Разницу видишь
ВК = Новый COMОбъект(ИмяВК); и ВК = Новый(ИмяВК); |
|||
34
Serginio1
20.10.15
✎
22:20
|
(28) Не работающий вариант. А на будущее проще использовать 15. В ближайшем будущем прикручу автоматическую компиляцию врапера для обертки нетовских событий в комовские.
|
|||
35
Кирпич
20.10.15
✎
22:27
|
(33)не видит он.
|
|||
36
Serginio1
20.10.15
✎
22:49
|
(35) Да уж 5 дней уже страдает.
|
|||
37
Сияющий в темноте
20.10.15
✎
23:41
|
да
птсатель прозаек сскачал шаблон а заполнить не смог |
|||
38
Сияющий в темноте
20.10.15
✎
23:47
|
он там ещё и встр неправильно формирует
его нужно создавать а не копировпть |
|||
39
alexkozin
21.10.15
✎
07:12
|
(31) у меня сейчас единственный вопрос остался, суть которого в следующем "почему отладчик не видит методов интерфейса ILanguageExtender кроме единственного 'RegisterExtensionAs'"
(37) По делу что-то будет сказано или забить уже мне? (33) В примере от 1С был верхний вариант. В чем разница кроме того что написано по-разному? |
|||
40
Serginio1
21.10.15
✎
08:13
|
(39) Потому, что 33. Разница большая
При ВК = Новый COMОбъект(ИмяВК) создается COMОбъект А при ВК = Новый(ИмяВК) Ищется ВК с зарегистрированным RegisterExtensionAs Один вызов твоей ВК делается при ПодключитьВнешнююКомпоненту(ИмяВК); |
|||
41
alexkozin
21.10.15
✎
08:27
|
(40) При ВК = Новый(ИмяВК) 1С вот такое говорит:
vk_OLE : Общий член "CreateObject" для типа "_ComObject" не найден.. При чем говорит при вызове метода. Инициализируется без ошибок. |
|||
42
Serginio1
21.10.15
✎
08:46
|
Имя Вк должно быть
AddIn.vk_OLE |
|||
43
Serginio1
21.10.15
✎
08:56
|
Чему у тебя равен c_AddinName
|
|||
44
alexkozin
21.10.15
✎
08:59
|
(43) Const c_AddinName As String = "vk_OLE"
|
|||
45
Serginio1
21.10.15
✎
09:00
|
А ИмяВК?
Вообще возьми любой рабочий пример и потихоньку его изменяй |
|||
46
alexkozin
21.10.15
✎
09:03
|
(45) Имя ВК тоже такое же vk_OLE.
Фигня в том что на VB.NET нигде не могу найти нормального рабочего примера. Изначально именно так и хотел поступить, но куда ни ткнусь - везде облом. |
|||
47
MM
21.10.15
✎
09:18
|
(34) А можно будет выкладывать проект на какой-нибудь бесплатный ресурс? А то, стармани не безграничные (
|
|||
48
Serginio1
21.10.15
✎
10:57
|
Да мне не жалко. Просто никому это не нужно. Я всегда кто попросит отправляю на поччту
|
|||
49
Serginio1
21.10.15
✎
10:59
|
(45) Берешь в руки ILSpy и декомпилируешь сборку в VB.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |