Почему моя функция VBA возвращает 0? - PullRequest
4 голосов
/ 19 сентября 2011

Рассмотрим следующую функцию в 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

Эта функция анализирует ответ XMLи возвращает значение одного из узлов, LastTradePriceOnly.

Аргумент Nodes - это объект MSXML.DOMDocument.Когда я использую msgBox, чтобы напечатать значение xNode.text, ожидаемое значение выводится.Однако, когда я вызываю эту функцию из другой функции, возвращается 0.

Любые мысли о том, почему я мог бы возвратить 0?

Ответы [ 3 ]

4 голосов
/ 19 сентября 2011

Вы забыли фактически вернуть значение из вашего рекурсивного вызова:

DisplayNode = DisplayNode (xNode.ChildNodes)

Был там:)

3 голосов
/ 20 сентября 2011

Ответ Алейнса лежит в основе вашей проблемы, но не доходит до конца.

Возможно, вам нужно вспомнить, что строка типа DisplayNode = xNode.Text просто говорит VBA, что возвращать при выходе из функции, но на самом деле не выходит из функции. VBA с радостью позволит вам назначить и переназначить возвращаемое значение и просто вернет все, что вы сказали, до последнего.

Кроме того, если вы никогда не назначите значение функции, VBA будет предполагать, что вы хотите вернуть значение по умолчанию независимо от типа функции. В вашем случае ваша функция имеет тип Variant, а значение по умолчанию Variant равно Empty. Вы можете видеть это как ноль, потому что VBA неявно преобразует Empty в ноль во всех ситуациях

Имея это в виду, подумайте, что происходит в вашем примере, если какое-либо из них верно:

1) в вашем параметре Nodes ничего нет (т. Е. Это пустой массив или коллекция или что-то еще в MSXML)

2) есть некоторые узлы, но ни один из них не соответствует ни одному из тестов в вашем цикле

3) есть несколько узлов, и последний узел удовлетворяет (1) или (2) выше

Вы должны увидеть, что ваша функция вернет Empty, даже если она обнаружит один или несколько узлов "LastTradePriceOnly" на своем пути через ваше дерево узлов. И тогда вы увидите это как ноль, когда отобразите его в окне сообщения.

Звучит так, будто вы действительно хотите более конкретную подпрограмму - может быть, что-то, что находит определенный узел в дереве и выдает ошибку, если не может этого сделать. Я полагаю, это зависит от ваших данных, но это объяснение должно ответить на ваш непосредственный вопрос о том, почему вы могли видеть ноль в окне сообщения.

2 голосов
/ 20 сентября 2011

Исходя из вашего кода, вы должны изменить это:

Function DisplayNode(ByRef Nodes)

к этому:

Function DisplayNode(Nodes as MSXML2.DOMDocument) as String 

ByRef по умолчанию происходит в VBA, поэтому вам не нужно включать его, если вы этого не хотите. Кроме того, не объявляя переменные или функции по умолчанию их Варианты. Это обычно считается плохой практикой кодирования, плюс вы не получаете преимущества IntelliSense.

Возможно, вы также захотите изменить объявление xNode. До этого я не работал с DOMDocument, но если существует более одного объекта другого типа, оператор FOR EACH будет проходить через них все; Похоже, вы можете захотеть перебрать только один тип объекта.

Наконец, может ли свойство, которое вы хотите использовать, быть nodeValue , а не Text ?

Когда я смотрю в браузере объектов, определение для nodeValue равно значению, хранящемуся в узле .

Однако текст представляет собой текстовое содержимое узла и поддерева .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...