Excel 从函数返回的VBA对象不可用
在函数中创建的自动化对象可以在该函数中使用。 但是当我试图从这个函数返回它,然后在另一个函数中使用它时,它就不可用了 我知道传递对象的技巧,ByRef buy应该将返回值分配给哪个函数。我想知道在我的例子中,VBA不允许直接从函数返回对象 谢谢 UPD。Excel 从函数返回的VBA对象不可用,excel,vba,Excel,Vba,在函数中创建的自动化对象可以在该函数中使用。 但是当我试图从这个函数返回它,然后在另一个函数中使用它时,它就不可用了 我知道传递对象的技巧,ByRef buy应该将返回值分配给哪个函数。我想知道在我的例子中,VBA不允许直接从函数返回对象 谢谢 UPD。querySelectorAll()也存在同样的问题,尽管它是“静态”列表 我认为这是因为WebPage是GetElementByClass的一个局部变量,它在End函数中被销毁。因为您返回的Set GetElementByClass=WebPa
querySelectorAll()
也存在同样的问题,尽管它是“静态”列表
我认为这是因为
WebPage
是GetElementByClass
的一个局部变量,它在End函数中被销毁。因为您返回的Set GetElementByClass=WebPage.getElementsByClassName(ClassName)
是WebPage
对象的成员,所以函数结束时它也会消失
1.变通办法
将变量声明为public,这样它就不会被销毁
Option Explicit
Global WebPage As MSHTML.HTMLDocument
Function GetElementByClass(Html As String, ClassName As String) _
As IHTMLElementCollection
Set WebPage = New MSHTML.HTMLDocument
WebPage.body.innerHTML = Html
'GetElementByClass is valid object
Set GetElementByClass = WebPage.getElementsByClassName(ClassName)
End Function
2.变通办法
或者在GetDataFromPage
中创建变量WebPage
,并将其作为参数传递:
Option Explicit
Function GetElementByClass(WebPage MSHTML.HTMLDocument, ClassName As String) _
As IHTMLElementCollection
'GetElementByClass is valid object
Set GetElementByClass = WebPage.getElementsByClassName(ClassName)
End Function
Sub GetDataFromPage()
Dim WebPage As MSHTML.HTMLDocument
Set WebPage = New MSHTML.HTMLDocument
WebPage.body.innerHTML = Html
Dim Element As IHTMLElementCollection
'Element is Nothing here. Why?
Set Element = GetElementByClass(WebPage, "relative")
End Sub
检查是否有效。我认为这是因为WebPage
是GetElementByClass
的局部变量,它在结束函数
处被销毁。因为您返回的Set GetElementByClass=WebPage.getElementsByClassName(ClassName)
是WebPage
对象的成员,所以函数结束时它也会消失
1.变通办法
将变量声明为public,这样它就不会被销毁
Option Explicit
Global WebPage As MSHTML.HTMLDocument
Function GetElementByClass(Html As String, ClassName As String) _
As IHTMLElementCollection
Set WebPage = New MSHTML.HTMLDocument
WebPage.body.innerHTML = Html
'GetElementByClass is valid object
Set GetElementByClass = WebPage.getElementsByClassName(ClassName)
End Function
2.变通办法
或者在GetDataFromPage
中创建变量WebPage
,并将其作为参数传递:
Option Explicit
Function GetElementByClass(WebPage MSHTML.HTMLDocument, ClassName As String) _
As IHTMLElementCollection
'GetElementByClass is valid object
Set GetElementByClass = WebPage.getElementsByClassName(ClassName)
End Function
Sub GetDataFromPage()
Dim WebPage As MSHTML.HTMLDocument
Set WebPage = New MSHTML.HTMLDocument
WebPage.body.innerHTML = Html
Dim Element As IHTMLElementCollection
'Element is Nothing here. Why?
Set Element = GetElementByClass(WebPage, "relative")
End Sub
检查是否有效。使用getElementsByClassName()
创建节点列表是行不通的,因为这样会创建一个活动的节点列表。这些只适用于整个文档。但是当你离开办公室时,文件会丢失。没有文档,没有活动节点列表
我认为您可以通过使用statik节点列表来解决这个问题,您可以使用它来创建
ByRef的“把戏”不是把戏。这是处理函数间对象的唯一方法。无法按值处理对象。使用getElementsByClassName()
创建节点列表无法工作,因为这样会创建一个活动的节点列表。这些只适用于整个文档。但是当你离开办公室时,文件会丢失。没有文档,没有活动节点列表
我认为您可以通过使用statik节点列表来解决这个问题,您可以使用它来创建
ByRef的“把戏”不是把戏。这是处理函数间对象的唯一方法。不可能按值处理对象。Html在GetDataFromPage()
Sub
中的外观如何?@FaneDru只是一个字符串。Html
在GetDataFromPage()
中的外观如何?@FaneDru只是一个字符串。谢谢!我知道这种方法。我不赞成全局变量,但若所描述的问题是VBA的局限性,那个么第二点是可以的。我只是认为对象是通过引用返回的,因此当我返回网页时。GetElementsByCassName(ClassName)(此行返回不同的对象,所以网页现在已经可以设置为Nothing)对象函数返回对它的引用。最终我切换到第二种方法。。。在COM自动化的情况下,VBA似乎只保留对主对象的引用。谢谢!我知道这种方法。我不赞成全局变量,但若所描述的问题是VBA的局限性,那个么第二点是可以的。我只是认为对象是通过引用返回的,因此当我返回网页时。GetElementsByCassName(ClassName)(此行返回不同的对象,所以网页现在已经可以设置为Nothing)对象函数返回对它的引用。最终我切换到第二种方法。。。在COM自动化的情况下,VBA似乎只保留对主对象的引用。谢谢!你所说的“因为它创建了一个活动节点列表”是什么意思?GetElementsByCassName()返回不同的对象,该对象不应再依赖于网页。是的,它依赖于网页。您可以很容易地对此进行测试,因为可以从这样的列表中寻址(例如父节点)。这只可能是因为列表与文档一起工作。查看我链接中的第一句话文档方法querySelectorAll()返回一个静态(非活动)节点列表…@user2702866使用getElementsByClassName()
创建的元素节点列表只在文档网页
存在时才存在。如果您在结束函数
处销毁变量网页
,元素列表也会被销毁。@Zwenn哦,我明白了。通常,您可以很容易地从函数返回对象,因为它们被引用使用,但在这种特殊情况下,由于GetElementByClass依赖于网页,并且在函数执行后,没有对网页的引用(已扫描)。我明白了这个问题。谢谢Zwenn,PeH@user2702866但使用自定义函数的结束函数
,网页
对象将被销毁。由于WebPage
in在该函数中本地声明,因此仅存在于该函数中。如果结束,它将立即销毁对象网页
。因此,引用指向一个已销毁的对象,该对象无法再提供任何活动列表。这就是它不起作用的原因。谢谢!你所说的“因为它创建了一个活动节点列表”是什么意思?GetElementsByCassName()返回不同的对象,该对象不应再依赖于网页。是的,它依赖于网页。您可以很容易地对此进行测试,因为可以从这样的列表中寻址(例如父节点)。这只可能是因为列表与文档一起工作。看看我链接中的第一句话,文档方法querySelectorAll()返回一个静态(非活动)节点列表…@user27