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.
You issue is incompatable types between
Try declaring all thses
() As Double
Dim ABP() As Double
Dim ABP() As Double
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
You need to specify each variables type explicitly.
Also, don’t use
Integer unless you have a specific reason. Use
Thanks Chris! You definitely led me in the right direction. I also used these two websites:
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