Home » excel » excel – Function calls another function but gets "stuck"

excel – Function calls another function but gets "stuck"

Posted by: admin April 23, 2020 Leave a comment

Questions:

I’m an occasional VBA programmer, for fun (not my job).

I have a series of VBA modules in MS Excel 2010. Can’t figure out what I did wrong. This routine worked, then I changed some things and it stopped working. One of the things I did was split the code from a single function to two functions in two modules. I think it worked for a while after I split it into two, but now I can’t remember if that is true since I’ve tried so many things to make it work again. Luckily, I saved the older version with all of the code in a single function, and it still works. It returns a large array to the spreadsheet.

Fundamentally, I have a worksheet that calls a function. That function calls another function. Using the Debug – Toggle Breakpoints in combination with some MsgBox calls, I have figured out that the first function runs down to the point that it calls the second function. Then the second function runs down to the “End Function” command. At that point, the name at the top of the worksheet flickers a few times…and nothing. While debugging, the program does not seem to return to the first function. The array that is supposed to be populated in the first function is filled with #Value.

I read several places where VBA can be corrupted, so shutting everything down and rebooting can fix it. It didn’t. Then I read that if you copy/paste everything into a new worksheet, with new modules (yes, a LOT of copy/pasting), that can clean it up. It didn’t.

I also read of an issue where dimensioning arrays had problems when the dimensions were input variables to the function. So I initialized the variables used to set the array dimensions, even though they were input variables to the function. Maybe that’s a problem?

The code is really long, so I’ve only included the call to the second function, the declarations of variables in the second function, and a few other things. Maybe I screwed up some syntax when I passed variables?

The first 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

The second 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

Thanks in advance. I’ve blown two long evenings and can’t figure it out.

How to&Answers:

You issue is incompatable types between InputOutputDVL.ABP, Section2VL.ABP and Section2VL itself

Try declaring all thses () As Double

ie.

In InputOutputDVL

Dim ABP() As Double

In Section2VL

Dim ABP() As Double

And

Function Section2VL(...) As Double()

Note on Type declarations

When you declare variables like this

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

all except the last one are infact declared as Variant‘s

You need to specify each variables type explicitly.

Also, don’t use Integer unless you have a specific reason. Use Long instead.

Answer:

Thanks Chris! You definitely led me in the right direction. I also used these two websites:

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

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

Incomplete/incompatible variable declarations were the source of my problem.

First, I had forgotten that VBA requires “as Integer” or “as Double” after EACH variable, not just at the end of the line. So many of variables were VARIANTS instead of integers, doubles, etc. Thanks again Chris!

Second, and more specific, I only had to make one of Chris’ changes noted above, and that was to properly declare ABP() as Double in the first calling function. ABP() was already properly called Double in the second function, and I did NOT declare the Function Section2VL as Double(). With the original code:

Dim ABP(), TV() as Double

This indicated that ABP was a VARIANT ARRAY. The later call to ABP = Section2VL() was then trying to stuff a VARIANT into a VARIANT ARRAY, and THAT was the problem. I’m still disappointed that the compiler didn’t somehow say it had incompatible data types or some other error. This also explains where the problem came from. The code was previously working as two functions in two modules. As I was making some other changes, I noticed that I hadn’t declared ABP as an Array, so I added the “()”. I made other changes, and it stopped working. I focused on the other changes, not the seemingly minor “correction” of adding the () marks. What was really happening was that in the original code a combination of mistakes had resulted in a correctly working code! Imagine that!

So the code worked with ABP as a variant, or ABP() as a double array, but NOT with ABP() as a variant array.

Of course, the correct answer here is what Chris suggested, and that is correctly and explicitly declaring all of the variables. An interesting note is that a VARIANT (not VARIANT ARRAY) can essentially “accept” being assigned any incoming value, including a DOUBLE ARRAY.

So in my final code, I’ve left both Functions as VARIANTs, but I’ve now specifically declared them as VARIANT to make it clear. In the second function, ABP is properly declared as a dynamic DOUBLE ARRAY, and later given the proper dimensions to allocate memory space. In the first function, ABP could either be a VARIANT or a DOUBLE ARRAY, and either would work, but since I always want it to be a DOUBLE ARRAY, I’ve specified it as such.

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

And the second, called 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