从Visual Foxpro COM服务器返回对象到VBA时出现错误

3
当我尝试从我的Visual Foxpro COM服务器返回一个新对象到VBA时,出现以下消息: “运行时错误'-2147417851(80010105)': 对象'Itestclass'的方法'ReturnObject'失败”
如果我删除“Dim ... As”行,则错误消失,但我会失去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服务器正在作为独立进程EXE构建。如果将其构建为内部进程.DLL,则VBA代码会导致Excel崩溃。

DEFINE CLASS ObjectToReturn AS SESSION OLEPUBLIC

ENDDEFINE

DEFINE CLASS TestClass AS SESSION OLEPUBLIC

FUNCTION ReturnObject

    RETURN CREATEOBJECT("ObjectToReturn")

ENDFUNC

ENDDEFINE

我尝试将RETURN CREATEOBJECT("ObjectToReturn")更改为RETURN CREATEOBJECT("CUSTOM"),但问题仍然存在。

请指导我如何在不失去VBA中COM对象的智能感知的情况下解决此错误。谢谢。


那是RPC_E_SERVERFAULT,你的COM服务器抛出了一个异常。为什么是无法猜测的。 - Hans Passant
@hans-passant感谢您提供的额外信息。根据症状,我“猜测”这与早期绑定和晚期绑定以及类型库有关,但除此之外我一无所知。 - Caltor
我不敢想象只有我一个人曾经想过在不失去智能感知(即早期绑定)的情况下,将一个对象从VFP返回到VBA。 - Caltor
哈哈,我猜所有那些知识都在 .net 的一阵风中消失了。 - Caltor
你能否给我更多关于 "ObjectToReturn" 是什么的澄清?它是另一个具有公开属性、方法等的 VFP 类吗? - DRapp
显示剩余2条评论
1个回答

0

我不知道为什么你会遇到这样的困难...这应该能帮助到你...你可以将你的类定义为OlePublic,并像顶部的示例一样设置一些属性。你可以在其他非隐藏函数中的任何地方设置这些属性。

如果你需要访问其他“对象”的某些元素,请创建该对象的实例并将其插入到OlePublic类的属性中...看看我的方法

DoSomethingElse

它对类的“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类,以便公开并根据需要创建这些实例。如果这有助于您更接近目标,请告诉我,我们将继续努力。

我已经尝试了各种示例,但是看到您拥有的对象,两个都是VFP OleObject条目,每个都是公开的,并且可以单独创建。您不需要创建一个对象来创建另一个对象。

您是否有特定的原因要从另一个对象创建一个对象?您可以让一个对象公开一堆方法和属性,以执行您需要的任何操作。

如果您想公开多个对象类,并在中央控制下进行管理,您始终可以创建用于通信的主要对象,并由其创建每个“其他”类的实例。然后,在您的主类上公开方法以处理它们之间的通信,以执行您需要的任何操作。


谢谢你的建议,但我认为你可能稍微误解了问题。我无法让任何对象在VFP COM服务器和VBA(MS Excel 2007)程序之间传递。我现在已经尝试在VFP或VBA中创建对象,但我也无法将其传递到任何方向 :( - Caltor
我已经扩展了答案,并根据您的需求添加了问题。 - DRapp
我正在编写VFP COM服务器,但第三方客户端将编写VBA代码。因此,我正在尝试尽可能简化他创建“子”对象的过程,这也是我试图从另一个对象中创建一个对象的特定原因。从您的代码中,我发现您可以创建一个公共属性来保存新对象,并且可以从VBA客户端访问该属性;但是多个对象怎么办?由于主类“TestClass”将具有多个子项,因此我实际上需要公共属性为集合,但在这种情况下,VBA客户端无法传递该对象。 - Caltor
你不能显式地返回那种类型的对象。我会创建一个主对象,然后从这个对象中,让所有的函数在它所创建的子对象上执行/对抗。这样,你仍然可以提供子对象的任何功能,但是从创建的主OlePublic调用。 - DRapp
你可以在 VFP 代码中创建一个集合来保存你正在创建的一组对象。该集合可以通过 VBA 代码中实际创建的 VFP 对象的属性进行访问。 - Tamar E. Granor
我发现使用早期绑定返回COM对象时,这绝对是一个通用问题。我已经使用早期绑定重写了客户端代码,并且我得到了相同的错误。我目前正在进行的解决方法是基于在客户端代码中创建和填充COM对象,然后将其传递给COM服务器,或者在COM服务器中创建COM对象,然后通过数组或集合访问它们,就像Tamar建议的那样。 - Caltor

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接