#vba #com #visual-foxpro
#vba #com #visual-foxpro
Вопрос:
Я получаю следующее сообщение при попытке вернуть новый объект в VBA с моего сервера Visual Foxpro COM. «Ошибка времени выполнения ‘ -2147417851 (80010105)’:
Ошибка метода ‘returnObject’ объекта ‘Itestclass'»
Если я удалю «Dim… В строке » ошибка исчезает, но затем я теряю intellisense для COM-объекта.
Это код VBA:
Sub Test()
'' Removing the following line gets rid of the error but loses intellisense for the COM object
Dim objTest As testcom.TestClass
Set objTest = CreateObject("TestCOM.TestClass")
Set objNew = objTest.ReturnObject '' This is the line that causes the error
End Sub
Я создал ссылку на библиотеку типов TestCOM в Сервисах > Ссылки
Вот код Visual Foxpro (VFP): COM-сервер создается как незавершенный исполняемый файл. Если я создаю его как inprocess .DLL, то код VBA приводит к сбою Excel.
DEFINE CLASS ObjectToReturn AS SESSION OLEPUBLIC
ENDDEFINE
DEFINE CLASS TestClass AS SESSION OLEPUBLIC
FUNCTION ReturnObject
RETURN CREATEOBJECT("ObjectToReturn")
ENDFUNC
ENDDEFINE
Я попытался изменить ВОЗВРАЩАЕМЫЙ CREATEOBJECT(«ObjectToReturn») на ВОЗВРАЩАЕМЫЙ CREATEOBJECT («ПОЛЬЗОВАТЕЛЬСКИЙ»), но проблема сохраняется.
Пожалуйста, посоветуйте, как я могу избавиться от этой ошибки без потери intellisense для COM-объекта в VBA. Спасибо
Комментарии:
1. Это ошибка RPC_E_SERVER, ваш COM-сервер выдал исключение. Почему не угадывается.
2. @hans-passant спасибо за дополнительную информацию. Основываясь на симптомах, я «предполагаю», что это как-то связано с ранней и поздней привязкой и библиотекой типов, но помимо этого я заблудился.
3. Я не могу представить, что я единственный человек, который когда-либо хотел вернуть объект в VBA из VFP без потери intellisense, т.Е. ранней привязки
4. Вы только что задали вопрос с опозданием на 10 лет.
5. ха-ха, я думаю, все эти знания исчезли в порыве .net
Ответ №1:
Я не знаю, почему вы сталкиваетесь с такими трудностями… Это должно быть в состоянии вам помочь… Вы можете определить свой класс как OlePublic и задать для него некоторые свойства, подобные примерам вверху. Вы можете установить эти свойства в любом месте с помощью других функций, которые не скрыты.
Если вам нужно получить доступ к определенным элементам какого-либо другого «объекта», попробуйте создать экземпляр объекта и вставить его в свойство класса OlePublic… смотрите мой метод
doSomethingElse
который выполняет простой вызов scatter NAME для свойства «SomeObject» класса. Даже если вы явно не возвращаете его, он должен быть виден изнутри вашего создания из VB…
DEFINE CLASS VFPClassForVB as Session OLEPublic
cTmpFiles = ""
cCOMUser = ""
SomeObject = ""
FUNCTION Init()
*/ Who is user... always ignore the machine....
This.cCOMUser = SUBSTR( SYS(0), AT( "#", SYS(0)) 1 )
This.cTmpFiles = "somepath"
*/ Unattended mode... any "MODAL" type dialog will throw error / exception
SYS(2335, 0 )
*/ ALWAYS HAVE EXCLUSIVE OFF FOR COM!!!
SET EXCLUSIVE OFF
*/ ALWAYS HIDE DELETED RECORDS!!!
SET DELETED ON
ENDFUNC
*/ Error handler at the CLASS level will always be invoked
*/ instead of explicit ON ERROR or TRY/CATCH handlers...
FUNCTION xError(nError, cMethod, nLine)
lcMsg = "User: " SYS(0) " Tmp:" SYS(2023);
" Method: " cMethod " Error: " STR( nError,5);
" Line: " STR( nLine, 6 )
STRTOFILE( lcMsg, This.cTmpFiles "COMLog.txt" )
*/ NOW, throw the COM Error...
COMReturnError( cMethod ' Error:' str(nError,5);
' Line:' str(nline,6);
' Msg:' message(), _VFP.ServerName )
RETURN
HIDDEN FUNCTION SomeOtherFunction( lcWhat String,;
lnThing as Integer ) as String
*/ Do something
RETURN 1
ENDFUNC
*/ Another completely visible function direct form VB
FUNCTION DoSomethingElse( SomeParameter as String ) as String
USE SomeTable
*/ Now, this object should be visible as a direct property in VB
SCATTER MEMO NAME This.SomeObject
ENDFUNC
ENDDEFINE
Ваша сторона VB, даже из вашего образца…
Sub Test()
Set objTest = CreateObject("MySampleProject.VFPClassForVB")
objTest.DoSomethingElse( "I dont care" )
dim Something as objTest.SomeObject.ColumnFromTable
End Sub
Вы можете создать столько OlePublic классов в своих библиотеках классов в коде, которые вы хотите предоставить, и просто создавать эти экземпляры по мере необходимости. Дайте мне знать, если это поможет вам приблизиться, и мы постараемся продолжить работу над этим.
Я пробовал всевозможные образцы, но, глядя на то, что у вас есть для объекта, где оба являются записями OLEObject VFP, каждая из них доступна и может быть создана по отдельности. Вам не нужно создавать один, чтобы создать другой.
Есть ли какая-то конкретная причина, по которой вы пытаетесь создать один объект из другого? У вас может быть один объект, предоставляющий множество методов и свойств для выполнения всего, что вам нужно из VFP.
Если вы хотите, чтобы было открыто несколько классов объектов и под централизованным управлением, вы всегда можете создать свой основной объект для обмена данными и заставить его создавать экземпляры каждого «другого» класса на нем. Затем предоставьте методы в вашем основном классе для обработки сообщений между ними, чтобы выполнить все, что вам нужно.
Комментарии:
1. спасибо за совет, но я думаю, что вы можете немного неправильно понять проблему. Я не могу передать какие-либо объекты между сервером VFP COM и программой VBA (MS Excel 2007). Теперь я попытался создать объект в VFP или VBA, но я не могу передать его ни в том, ни в другом направлении:(
2. Я расширил ответ и добавил вопросы о ваших потребностях.
3. Я пишу сервер VFP COM, но сторонний клиент будет писать код VBA. Поэтому я пытаюсь максимально упростить для него создание «дочерних» объектов, что является конкретной причиной, по которой я пытаюсь создать один объект из другого. Из вашего кода я вижу, что вы можете создать общедоступное свойство для хранения нового объекта, который будет доступен с клиента VBA; но как насчет нескольких объектов? Поскольку основной класс ‘TestClass’ будет иметь несколько дочерних элементов, мне действительно нужно, чтобы общедоступное свойство было коллекцией, но в этом случае клиент VBA не может передать объект.
4. Вы не можете явно вернуть объект этого типа. Я бы просто создал один главный объект, который открыт, а затем, исходя из этого, все ваши функции в нем БУДУТ ДЕЙСТВОВАТЬ на дочерний объект, который он создает, или ПРОТИВ НЕГО. Таким образом, вы все еще можете предлагать любую функциональность дочернего объекта, но вызываемого из созданного основного OlePublic.
5. Вы могли бы создать коллекцию в коде VFP для хранения набора создаваемых вами объектов. Доступ к этой коллекции можно получить через свойство объекта VFP, который вы фактически создаете в коде VBA.