Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 从函数返回的VBA对象不可用_Excel_Vba - Fatal编程技术网

Excel 从函数返回的VBA对象不可用

Excel 从函数返回的VBA对象不可用,excel,vba,Excel,Vba,在函数中创建的自动化对象可以在该函数中使用。 但是当我试图从这个函数返回它,然后在另一个函数中使用它时,它就不可用了 我知道传递对象的技巧,ByRef buy应该将返回值分配给哪个函数。我想知道在我的例子中,VBA不允许直接从函数返回对象 谢谢 UPD。querySelectorAll()也存在同样的问题,尽管它是“静态”列表 我认为这是因为WebPage是GetElementByClass的一个局部变量,它在End函数中被销毁。因为您返回的Set GetElementByClass=WebPa

在函数中创建的自动化对象可以在该函数中使用。 但是当我试图从这个函数返回它,然后在另一个函数中使用它时,它就不可用了

我知道传递对象的技巧,ByRef buy应该将返回值分配给哪个函数。我想知道在我的例子中,VBA不允许直接从函数返回对象

谢谢

UPD。
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