为什么我的 VBA 函数返回 0?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7475360/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 14:03:48  来源:igfitidea点击:

Why is my VBA function returning 0?

functionvbarecursion

提问by Jason Strimpel

Consider the following function in VBA (note that it's been edited based on the answers given so now it's working - see the edit history for the original version):

考虑 VBA 中的以下函数(请注意,它已根据给出的答案进行了编辑,因此现在可以正常工作了 - 请参阅原始版本的编辑历史记录):

Function DisplayNode(ByRef Nodes)

    Dim xNode As Object
    For Each xNode In Nodes

        If xNode.nodeName = "LastTradePriceOnly" Then
            DisplayNode = xNode.Text
            Exit Function
        End If
        If xNode.HasChildNodes Then
            DisplayNode = DisplayNode (xNode.ChildNodes)
        End If

   Next xNode

End Function

This function parses an XML response and returns the value of one of the nodes, LastTradePriceOnly.

此函数解析 XML 响应并返回节点之一的值,LastTradePriceOnly

The Nodes argument is a MSXML.DOMDocumentobject. When I use msgBoxto print the value of xNode.textthe value I am expecting is output. However, when I call this function from another function, 0 is returned.

Nodes 参数是一个MSXML.DOMDocument对象。当我msgBox用来打印xNode.text我期望输出的值时。但是,当我从另一个函数调用此函数时,返回 0。

Any thoughts on why I might be returning 0?

关于为什么我可能会返回 0 的任何想法?

采纳答案by jtolle

Alains's answer gets at the root of your problem but doesn't go all the way.

Alains 的回答是您问题的根源,但并没有完全解决。

Perhaps you need to recall that a line like DisplayNode = xNode.Textjust tells VBA what to return upon function exit, but doesn't actually exit the function. VBA will happily let you assign and reassign the return value, and will just return whatever you told it to last.

也许您需要回忆一下,像这样的行DisplayNode = xNode.Text只是告诉 VBA 在函数退出时返回什么,但实际上并没有退出函数。VBA 会很乐意让您分配和重新分配返回值,并且只会返回您告诉它最后的任何内容。

Also, if you never assign a value to the function, VBA will assume you wanted to return the default value of whatever the type of the function is. In your case, your function is of type Variant, and the default value of Variantis Empty. You might be seeing this as zero, because VBA implicitly converts Emptyto zero in all kinds of situations

此外,如果您从不为该函数赋值,VBA 将假定您希望返回任何函数类型的默认值。在你的情况,你的功能型Variant,和默认值Variant就是Empty。您可能将其视为零,因为 VBAEmpty在各种情况下都会隐式转换为零

With that in mind, consider what happens in your example if any of these are true:

考虑到这一点,如果其中任何一个为真,请考虑在您的示例中会发生什么:

1) your Nodesparameter doesn't have anything in it (i.e. it's an empty array or Collection or whatever it is in MSXML)

1)您的Nodes参数中没有任何内容(即它是一个空数组或集合或它在 MSXML 中的任何内容)

2) there are some nodes, but none of them meet either of the tests in your loop

2)有一些节点,但没有一个满足循环中的任何一个测试

3) there are some nodes, and the last node satisfies (1) or (2) above

3)有一些节点,最后一个节点满足上面的(1)或(2)

You should be able to see that your function will return Empty, even if it found one or more "LastTradePriceOnly" nodes on it's way through your tree of nodes. And then you would see that as zero when you display it in a message box.

您应该能够看到您的函数将返回Empty,即使它在您的节点树中找到一个或多个“LastTradePriceOnly”节点。然后当你在消息框中显示它时,你会看到它为零。

It sounds like you really want a more specific routine - maybe something that finds a specific node in a tree and raises an error if it can't do so. I guess it depends on your data, but this explanation should address your immediate question about why you could be seeing zero in your message box.

听起来你真的想要一个更具体的例程 - 也许是在树中找到特定节点并在它不能这样做时引发错误的东西。我想这取决于您的数据,但是这个解释应该可以解决您的直接问题,即为什么您会在消息框中看到零。

回答by Alain

You forgot to actually return the value from your recursive call:

您忘记了从递归调用中实际返回值:

DisplayNode =DisplayNode (xNode.ChildNodes)

DisplayNode =DisplayNode (xNode.ChildNodes)

Been there :)

到过那里 :)

回答by ray

Based on your code, you should change this:

根据您的代码,您应该更改此内容:

Function DisplayNode(ByRef Nodes)

to this:

对此:

Function DisplayNode(Nodes as MSXML2.DOMDocument) as String 

ByRef happens by default in VBA so you don't have to include it unless you want to. Also, not declaring variables or functions defaults them to Variants. Doing this is generally considered a bad coding practice plus you don't get the advantage of IntelliSense.

ByRef 默认情况下发生在 VBA 中,因此除非您愿意,否则不必包含它。此外,不声明变量或函数会将它们默认为 Variants。这样做通常被认为是一种糟糕的编码习惯,而且您无法获得 IntelliSense 的优势。

You might also want to change your declaration of xNode. I haven't worked with DOMDocument before, but if there's more than one different type of object, then the FOR EACH statement will loop through them all; looks like you may only want to loop through one kind of object.

您可能还想更改 xNode 的声明。我以前没有使用过 DOMDocument,但是如果有不止一种不同类型的对象,那么 FOR EACH 语句将遍历它们;看起来您可能只想遍历一种对象。

Finally, could the property you want to use be nodeValueand not Text?

最后,您要使用的属性可以是nodeValue而不是Text吗?

When I look in the object browser, the definition for nodeValue is value stored in the node.

当我查看对象浏览器时, nodeValue 的定义是存储在 node 中的值

However, text is text content of the node and subtree.

但是,文本是节点和子树的文本内容