函数调用另一个函数,但得到“卡住”
我是偶尔的VBA程序员,为了好玩(不是我的工作)。
我在MS Excel 2010中有一系列的VBA模块。不知道我做错了什么。 这个例程工作,然后我改变了一些东西,它停止工作。 我做的一件事就是将代码从单个函数分成两个模块。 我认为在我把它分成两部分之后,它工作了一段时间,但是现在我不记得这是否是真的,因为我已经尝试了很多东西来使它重新工作。 幸运的是,我将所有代码的旧版本保存在一个函数中,并且仍然有效。 它将大数组返回到电子表格。
基本上,我有一个工作表,调用一个函数。 该函数调用另一个函数。 使用debugging – 切换断点结合一些MsgBox调用,我发现第一个函数运行到它调用第二个函数的点。 然后第二个函数运行到“End Function”命令。 在那个时候,工作表顶部的名字闪烁了几次……而什么也没有。 在debugging时,程序似乎没有返回到第一个函数。 应该在第一个函数中填充的数组用#Value填充。
我读了几个VBA可能被破坏的地方,closures所有东西并重新启动可以修复它。 它没有。 然后我读到,如果您将所有内容复制/粘贴到一个新的工作表,新的模块(是的,很多的复制/粘贴),可以清理它。 它没有。
我还读到了一个问题,即当维度是函数的inputvariables时,维度数组有问题。 所以我初始化了用于设置数组维度的variables,即使它们是函数的inputvariables。 也许这是一个问题?
代码很长,所以我只包含了对第二个函数的调用,第二个函数中的variables声明以及其他一些事情。 当我传递variables的时候,可能我搞砸了一些语法?
第一个function:
Option Explicit 'forces all variables to be explicitly declared Function InputOutputDVL(InData As Variant) '--------------------------------------------------------------------------------------------- Dim g, p, ng, np, ns, ID, count As Integer Dim ngmax, npmax, nsmax, namax, nxmax, nymax As Integer Dim row As Integer Dim panelmax As Integer Dim TLstyle As Integer Dim Group(), Part(), Section(), Airfoil() As Variant Dim ABP(), TV() As Double ngmax = 20 npmax = 100 nsmax = 1000 namax = 10 ReDim Group(1 To ngmax, 1 To 4) ReDim Part(1 To npmax, 1 To 6) ReDim Section(1 To nsmax, 1 To 17) ReDim Airfoil(0 To 100, 0 To 2 * namax + 1) 'missing code here MsgBox ng & " " & np 'This msgbox works correctly and give the right value for np ABP = Section2VL(nxmax, nymax, ns, panelmax, Group, Part, Section, Airfoil) MsgBox "Completed Section2VL" 'The code never gets to this msgbox InputOutputDVL = ABP 'I've tried setting this to = 1234 assuming there was a problem with 'ABP, but the cells on the spreadsheet are still #Value End Function
第二个function:
Option Explicit 'forces all variables to be explicitly declared Function Section2VL(nxmax, nymax, ns, panelmax, Group, Part, Section, Airfoil) Dim i, j, k, l, c1, c2 As Integer Dim g, p, s, ng, np, chord, span, panel, ID, count As Integer Dim NX, NY As Integer Dim station, panelID, panelIDref As Integer Dim pi, Xstyle, Ystyle As Double Dim angle, dist As Double Dim sx(), sy() As Double Dim Scoord(), ABP() As Double ns = 6 nxmax = 12 nymax = 12 panelmax = 300 ReDim sx(0 To nxmax), sy(0 To nymax) ReDim Scoord(1 To ns, 0 To nxmax, 1 To 3), ABP(1 To panelmax, 1 To 32) MsgBox ABP(panelmax, 5) 'This call works, and provides the proper value in the msgbox 'return ABP vector Section2VL = ABP 'I've also tried just returning an integer thinking there was something wrong with the 'ABP array, like 987, but that doesn't work either End Function 'This is where it stops when debugging. Doesn't return to first function
提前致谢。 我吹了两个漫长的夜晚,无法弄清楚。
您问题是InputOutputDVL.ABP
, Section2VL.ABP
和Section2VL
本身之间的不兼容types
尝试声明所有的() As Double
即。
在InputOutputDVL
Dim ABP() As Double
在Section2VL
Dim ABP() As Double
和
Function Section2VL(...) As Double()
关于types声明的注意事项
当你声明像这样的variables
Dim i, j, k, l, c1, c2 As Integer
除了最后一个以外,所有的事实都被宣布为Variant
的
您需要明确指定每个variablestypes。
另外,除非你有特定的原因,否则不要使用Integer
。 使用Long
而不是。
谢谢Chris! 你一定会把我带到正确的方向。 我也使用了这两个网站:
http://www.cpearson.com/excel/passingandreturningarrays.htm http://www.cpearson.com/excel/vbaarrays.htm
不完整/不兼容的variables声明是我的问题的来源。
首先,我忘记了VBA在每个variables之后都要求“整数”或“双倍”,而不仅仅是行尾。 所以很多变数是VARIANTS而不是整数,双打等。再次感谢Chris!
其次,更具体地说,我只需要做一个上面提到的Chris的变化,那就是在第一个调用函数中正确地声明ABP()为Double。 在第二个函数中,ABP()已经被正确地调用了Double,而且我没有将Function Section2VL声明为Double()。 用原来的代码:
Dim ABP(), TV() as Double
这表明ABP是一种变种arrays。 之后调用ABP = Section2VL()然后试图将VARIANT填充到VARIANT ARRAY中,那就是问题所在。 我仍然感到失望的是编译器不知道它有不兼容的数据types或其他错误。 这也解释了问题的来源。 该代码以前在两个模块中作为两个函数工作。 当我做了一些其他的改变,我注意到我没有宣布ABP作为一个数组,所以我加了“()”。 我做了其他更改,并停止工作。 我专注于其他变化,而不是join()标记的看似微小的“修正”。 真正发生的是在原始代码中,错误的组合导致了正确的工作代码! 想象一下!
所以代码与ABP一起作为变体,或者ABP()作为双数组,而不作为变体数组使用ABP()。
当然,这里的正确答案是Chris所build议的,那就是正确而明确地声明了所有的variables。 有趣的是,一个VARIANT(不是VARIANT ARRAY)本质上可以“接受”被赋值的任何传入值,包括一个DOUBLE ARRAY。
所以在我的最终代码中,我已经把两个函数都作为VARIANT来使用了,但是现在我已经明确地声明了它们是VARIANT。 在第二个函数中,ABP被正确地声明为一个dynamic的DOUBLE ARRAY,然后给出适当的尺寸来分配内存空间。 在第一个函数中,ABP既可以是VARIANT也可以是DOUBLE ARRAY,也可以工作,但是因为我总是希望它是双重arrays,所以我已经指定了它。
Option Explicit 'forces all variables to be explicitly declared Function InputOutputDVL(InData As Variant) as Variant '--------------------------------------------------------------------------------------------- Dim ABP() as Double, TV() As Double 'This ABP was a variant array - which was incompatible 'code removed here ABP = Section2VL(nxmax, nymax, ns, panelmax, Group, Part, Section, Airfoil) InputOutputDVL = ABP End Function
第二个叫做函数:
Option Explicit 'forces all variables to be explicitly declared Function Section2VL(nxmax as integer, nymax as integer... ) as Variant Dim Scoord(), ABP() As Double 'This was already correctly declaring ABP as Double Array, but 'now I realize Scoord was incorrectly a Variant Array, but it 'wasn't actually causing a problem with my code. 'I fixed this in my own code, but left here as example of what 'not to do! ReDim ABP(1 To panelmax, 1 To 32) 'Code removed here 'return ABP vector Section2VL = ABP End Function