VBS: переменной не присваивается значение через рекурсивное выражение

У меня проблема с присвоением значения переменной VBS:

Dim varName  
varName = function(x, y)
varName = function(x, y)

функция — это рекурсивная функция, которая вызывает сама себя:

Function function(x, y)
    If IsObject(dicColumnIndices) Then
        function = CInt(dicColumnIndices.Item(y))
    Else
        Set oCDSGrid = %MyAppObject%
        Set dicColumnIndices = CreateObject("Scripting.Dictionary")
        intColumnCount = oCDSGrid.ActiveSheet.Columns.Count
        For i = 0 To intColumnCount - 1
            dicColumnIndices.Add oCDSGrid.ActiveSheet.Columns.Item(i).Label, i
        Next

        function x, y
    End If
End Function

Насколько я вижу, присвоение значения переменной происходит только со второй попытки. Я подумал, что это как-то связано с рекурсивным вызовом моей функции (проблема исчезнет, ​​если я уберу рекурсивный вызов), но мне очень хотелось бы узнать, каковы корни такого поведения.

Я безуспешно искал как StackOverflow, так и Интернет.

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

Function function(x, y)
If IsObject(dicColumnIndices) Then
    function = CInt(dicColumnIndices.Item(y))
Else
    Set oCDSGrid = %MyAppObject%
    Set dicColumnIndices = CreateObject("Scripting.Dictionary")
    intColumnCount = oCDSGrid.ActiveSheet.Columns.Count
    For i = 0 To intColumnCount - 1
        dicColumnIndices.Add oCDSGrid.ActiveSheet.Columns.Item(i).Label, i
    Next

    function = CInt(dicColumnIndices.Item(y))
End If
End Function

Редактировать 2: Наконец, с помощью MSDN я получил неправильную часть - это второй вызов

function x, y

который возвращает значение в ничто, должен быть изменен на:

function = function x, y

Спасибо всем!


person Eugene A    schedule 08.08.2012    source источник
comment
Однако вам не следует использовать ключевые слова VBScript в качестве примера именования переменных или функций. Это чертовски сбивает с толку людей, пытающихся найти ответ. И почему вы хотите использовать рекурсию, для меня загадка. Почему бы не использовать: If not IsObject(someVar) then Set someVar = CreateObject("Scripting.Dictionary") '... etc и после End If вы помещаете код, который обрабатывает someVar как только что инициализированный объект, в вашем случае: YourFunction = CInt(dicColumnIndices.Item(y))   -  person AutomatedChaos    schedule 09.08.2012
comment
Согласен, буду иметь в виду для своих будущих постов. Также спасибо за совет по упрощению!   -  person Eugene A    schedule 09.08.2012


Ответы (1)


Функция не должна называться функцией, а varname — паршивое имя для переменной. Более того: в VBScript функция не является функцией (не возвращает что-либо), если вы не «назначаете имя функции»:

  Dim s : s = "abcdefg"
  Dim l : l = recLen(s)
  WScript.Echo "recursive length of", qq(s), "=>", l, CStr(l = Len(s))

  Function recLen(s)
    If "" = s Then
       recLen = 0
    Else
       recLen = 1 + recLen(Mid(s, 2))
    End If
  End Function

(Длина пустой строки равна 0; для более длинных строк это 1 + длина «хвоста» строки)

Обновление (благодаря AutomatedChaos):

Function qq( vStringable )
  qq = """" & vStringable & """"
End Function

Обновление II (чтобы ответить на вопрос Юджина в комментарии):

Чтобы заставить функцию что-то возвращать, вам нужно присвоить возвращаемое значение переменной с тем же именем, что и у функции. В вашем исходном коде этого не было (даже если имя «функция» было заменено «настоящим» именем).

person Ekkehard.Horner    schedule 08.08.2012
comment
Спасибо, Эккехард, конечно, мои функции и переменные так не называются. В итоге я заменил рекурсивный вызов блоком обработки: s/function x, y/GetColumnIndex = CInt(dicColumnIndices.Item(y))/, и на этот раз это сработало. Однако я до сих пор не понимаю, почему функции не было присвоено значение при втором (рекурсивном) вызове. - person Eugene A; 08.08.2012
comment
Хорошее объяснение, но ваш код не работает! Сначала я был взволнован введением функции VBScript, о которой я не знал: qq но, к сожалению, это было не так. Чего я не знал, так это использования Wscript.Echo с несколькими параметрами. - person AutomatedChaos; 08.08.2012