函数调用另一个函数但被“卡住”

Posted

技术标签:

【中文标题】函数调用另一个函数但被“卡住”【英文标题】:Function calls another function but gets "stuck" 【发布时间】:2014-01-04 05:38:46 【问题描述】:

我是一个偶尔的 VBA 程序员,为了好玩(不是我的工作)。

我在 MS Excel 2010 中有一系列 VBA 模块。无法弄清楚我做错了什么。这个例程奏效了,然后我改变了一些东西,它停止了工作。我做的一件事是将代码从一个函数拆分为两个模块中的两个函数。我认为在我将它分成两部分后它工作了一段时间,但现在我不记得这是不是真的,因为我已经尝试了很多东西让它再次工作。幸运的是,我将旧版本的所有代码保存在一个函数中,它仍然有效。它将一个大数组返回到电子表格。

基本上,我有一个调用函数的工作表。该函数调用另一个函数。结合使用 Debug - Toggle Breakpoints 和一些 MsgBox 调用,我发现第一个函数运行到它调用第二个函数的地步。然后第二个函数运行到“结束函数”命令。那时,工作表顶部的名称会闪烁几次……但什么也没有。调试时,程序似乎没有返回到第一个函数。应该在第一个函数中填充的数组用#Value 填充。

我阅读了几个可能损坏 VBA 的地方,因此关闭所有内容并重新启动可以修复它。它没有。然后我读到,如果您将所有内容复制/粘贴到新工作表中,并带有新模块(是的,大量复制/粘贴),则可以清理它。没有。

我还读到了一个问题,即当维度是函数的输入变量时,维度数组会出现问题。所以我初始化了用于设置数组维度的变量,即使它们是函数的输入变量。也许这是个问题?

代码真的很长,所以我只包含了对第二个函数的调用、第二个函数中的变量声明以及其他一些内容。也许我在传递变量时搞砸了一些语法?

第一个函数:

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

第二个功能:

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

提前致谢。我已经度过了两个漫长的夜晚,无法弄清楚。

【问题讨论】:

【参考方案1】:

您的问题是 InputOutputDVL.ABPSection2VL.ABPSection2VL 本身之间的类型不兼容

尝试声明所有这些() As Double

即。

InputOutputDVL

Dim ABP() As Double

Section2VL

Dim ABP() As Double

Function Section2VL(...) As Double()

关于类型声明的注意事项

当你像这样声明变量时

Dim i, j, k, l, c1, c2 As Integer

除最后一个之外的所有内容都被声明为Variant's

您需要明确指定每个变量类型。

此外,除非您有特定原因,否则请勿使用Integer。请改用Long

【讨论】:

【参考方案2】:

谢谢克里斯!你肯定把我引向了正确的方向。我也用过这两个网站:

http://www.cpearson.com/excel/passingandreturningarrays.htm

http://www.cpearson.com/excel/vbaarrays.htm

不完整/不兼容的变量声明是我问题的根源。

首先,我忘记了 VBA 需要在每个变量之后“作为整数”或“作为双精度”,而不仅仅是在行尾。如此多的变量是 VARIANTS 而不是整数、双精度数等。再次感谢 Chris!

其次,更具体地说,我只需要在上面提到的 Chris 中进行一项更改,那就是在第一个调用函数中正确地将 ABP() 声明为 Double。 ABP() 已经在第二个函数中正确调用了 Double,并且我没有将 Function Section2VL 声明为 Double()。附上原代码:

Dim ABP(), TV() as Double

这表明 ABP 是一个变体数组。后来对 ABP = Section2VL() 的调用试图将 VARIANT 填充到 VARIANT ARRAY 中,这就是问题所在。我仍然对编译器没有以某种方式说它具有不兼容的数据类型或其他一些错误感到失望。这也解释了问题出在哪里。该代码以前在两个模块中作为两个函数工作。当我进行其他一些更改时,我注意到我没有将 ABP 声明为数组,所以我添加了“()”。我进行了其他更改,但它停止了工作。我专注于其他更改,而不是添加 () 标记的看似微小的“更正”。真正发生的是,在原始代码中,错误的组合导致了正确工作的代码!想象一下!

所以代码使用 ABP 作为变体,或 ABP() 作为双精度数组,但不使用 ABP() 作为变量数组。

当然,这里的正确答案是 Chris 建议的,即正确且明确地声明所有变量。有趣的一点是,VARIANT(不是 VARIANT ARRAY)基本上可以“接受”分配任何传入值,包括 DOUBLE ARRAY。

所以在我的最终代码中,我将这两个函数都保留为 VARIANT,但我现在专门将它们声明为 VARIANT 以使其清楚。在第二个函数中,ABP 被正确地声明为一个动态 DOUBLE ARRAY,然后给定了适当的维度来分配内存空间。在第一个函数中,ABP 可以是 VARIANT 或 DOUBLE ARRAY,两者都可以,但由于我一直希望它是 DOUBLE ARRAY,所以我将其指定为这样。

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

【讨论】:

以上是关于函数调用另一个函数但被“卡住”的主要内容,如果未能解决你的问题,请参考以下文章

远程函数调用

js 函数如何去调用另一个函数中的函数?

python调用另一个目录,另一个文件 中的函数报错,怎么解决

如何期望一个函数调用另一个函数?

函数调用另一个函数设置自身属性 JS

this 指向