excel Compile error: Can't assign to array - vba

I am working on an Excel macro that uses several external references. Once in a while I get the error:
excel Compile error:
Can't assign to array
The highlighted line is an array assignments, not always the same. Something like:
Dim MyArray() As MyClass
MyArray = MyApplication.GetArrayOfElements
I get this error while the file is open on my computer once or twice per hour, after editing the VBA macro, especially (but not only) if I edit it while in break mode.
I usually compile before saving to make sure this problem is not there, but some users call me reporting this problem on their computer. So it looks like it breaks somewhere between my compilation and the next execution on another computer.
In order to get rid of the error all I need to do is to select all, cut, paste and compile (Ctrl+A, Ctrl+X, Ctrl+V, Alt+D, L.)
My wild guess is that it has to do with the VBA incremental compilation.
Anybody out there can help me get rid of this problem?

Related

Finding a syntax error in a large VBA/MS Access project

I have a MS Access database that displays an error message about a SQL syntax error on launch. "Syntax Error in query. Incomplete query clause." It also shows another error a few seconds after I hit "OK" on the first one.
Here's the two errors: https://imgur.com/a/PesjIFk
But it doesn't tell me where the syntax error is. There are SQL statements in a bunch of different places all over this project. This is a really large project and it wouldn't be practical to just look through all the code hoping that I notice an error someplace. How can I find out where this error is?
EDIT: Ok, so apparently you have to have a keyboard that has a "Break" key on it in order to even find where the error is. Wow. Fortunately I happen to have one. Here's the code that Access takes me to if I press break when I see the error message. This code is for a subform of another form. It highlights the first line (Private Sub Form_Current()).
Private Sub Form_Current()
If NumEnums > 0 Then
CurrentEnum = val(Nz(bit_value_edit.value)) 'Update CurrentEnum to the currently selected enum
Call UpdateEnumsLabel(Me.Parent![enums label]) 'Update label
End If
End Sub
...and here's UpdateEnumsLabel():
Public Sub UpdateEnumsLabel(ByRef label As Control)
If NumEnums > 0 Then
label.Caption = "Enums: " & CurrentEnum & "/" & NumEnums
Else
label.Caption = "Enums: 0"
End If
End Sub
The definition for CurrentEnum:
Public CurrentEnum, CurrentPort, CurrentFile, CurrentGroup As Long
I'm thinking that this error is unrelated to the code in Form_Current(), but Access is highlighting that line because the error happens when the form is opened. But the form doesn't contain anything that uses a query, so I'm confused as to what query Access has a problem with.
When the error Message pops up, Use Control+Break. It will take you to the line causes the issue.
You should also open a module and form the debug option in the VBA editor select "Compile All Modules"
And since it appears to happening on open/load, you can check both the macros and the main modules to find anything that triggers on AutoExec.
Often ctrl-break will hit the line where you errored out. However, in the case of multiple “events”, and code without error handling, then often the error occurs in the routine that called the code, not the actual code that caused the error.
What I would do launch the application (hold down the shift key to prevent any start up code, or forms running).
Now that you launched the application, but without forms or code running, then check for an autoexecc macro (if there is one, check what code it attempts to run).
If there not an autoexec macro in use, then check under file->options->current database. In this view, you can look/see/determine what the name of the start-up form is.
Once you determined the start-up form (or start up module/code) called from autoexec macro, then you can simply add a blank code module, and place in your code the SAME command that is used to start your application.
So let’s assume no autoexec macro, and you determine that the start-up form is frmMain.
So now, we can launch the application (hold down shift key to prevent any start up code from running). Now, type into a new “test” standard code module the following code:
Sub MyGo
Stop
Docmd.OpenForm "frmMain"
End sub
So you type in above code, hit ctrl-s to save the above code. Now with your cursor anyplace inside of the above code, you simply hit F5 to run.
At this point you hit/stop on the “stop” command in the debugger. At this point, you then can hit f8 to step to the next line of code. If the form in question calls other code etc., you still be able to single step, and “eventually” you hit the line which causes the error.
While the application may be large, a simple look at the start up forms (and huts then the start-up code) means that you ONLY really need to trace and look at the start up code – not the whole application.

Colleagues get error 5 in Excel-file with VBA, but same file works fine on my computer?

We have an Excel-file with a large amount of VBA behind it. The Excel-file works just fine on my computer, but so far 3 of my colleagues (non-IT'ers) have gotten this error:
Runtime error 5:
Invalid procedure call or argument
The error is located on this line, and I don't see why it is throwing an error there because it's just a simple Set (and it works perfectly fine on my computer):
Set MyButton = Application.CommandBars("Attributions").Controls.Add(Type:=msoControlButton, Before:=10)
We all have the exact same Excel-file. I even sent them my version of the file, in which everything is running fine and no errors happen, but even when they open my version of the file they still get the above error on the above line!
What exactly could cause this? We all have Office 2013 and updates are installed automatically. The problem started about 2 weeks ago with one colleague and since this week I heard from two other colleagues that they have the same problem. One even said it suddenly worked again after he moved to a different desk (which I doubt would have an influence) but shortly after, it started getting the error again.
I have absolutely no idea why they get the error, or what might cause it. Seeing as we now all have the same version and they still get the error, I am thinking it might have something to do with Excel itself but that's just my idea.
Does this sound familiar to anyone here? Or does anyone know what might cause this, and how it can be fixed?
Edit: a while ago I checked on my colleagues their computers to see if the CommandBar was present, and it was. Even then the error still happened.
I suggest you to use a function that checks if there is a CommandBar in your Application like this:
Function IsCommandBarValid(cbName As String) As Boolean
Dim i As Long
IsCommandBarValid = True
For i = 1 To Application.CommandBars.Count
If (Application.CommandBars(i).Name = cbName) Then
Exit Function
End If
Next i
IsCommandBarValid = False
End Function
Now, You can use it to see that your user have that CommandBar in his or her Application, then make it like this:
If (Not IsCommandBarValid("Attributions")) Then
Call Application.CommandBars.Add(Name:="Attributions")
End If
' And after this add your code
Set MyButton = Application.CommandBars("Attributions").Controls.Add(Type:=msoControlButton, Before:=10)
Invalid procedure call or argument (Error 5)
Some part of the call can't be completed. This error has the following causes and solutions:
An argument probably exceeds the range of permitted values. For example, the Sin function can only accept values within a certain range. Positive arguments less than 2,147,483,648 are accepted, while 2,147,483,648 generates this error.
Check the ranges permitted for arguments.
This error can also occur if an attempt is made to call a procedure that isn't valid on the current platform. For example, some procedures may only be valid for Microsoft Windows, or for the Macintosh, and so on.
Check platform-specific information about the procedure.
For additional information, select the item in question and press F1 (in Windows) or HELP (on the Macintosh).
MSDN Source Article

Capture Variable/Object Name causing the error

How can I capture the variable name or object name causing an error in VBA?
Ex
Sub test()
On Error GoTo Handler
i = 0
n = 1/i
Handler:
Select Case variablename
Case "n"
'do something................
The error is not being caused by a variable. The error is caused by the line of code that attempts to divide 1 by 0. The assignment doesn't actually happen.
The best way I've found to diagnose issues when I'm actively developing is to have Stop and then Resume in the error handler.
Public Sub func()
On Error GoTo ErrHandler
'... some code here ...
Exit Sub
ErrHandler:
Stop
Resume
End Sub
The way this works is, when there is an error VBA will break (pause the execution, show the instruction pointer arrow and yellow highlighting) on the Stop. You can step to the Resume and then once more to find out which specific line of code is causing the error.
Once you start to understand what errors you are encountering you can build individual If ... Then cases for them to handle each appropriately. When you are ready to release your code into a production environment (i.e., for other users), you would need to replace the Stop/Resume with an unexpected error handler that either logs it or displays it to the user.
While Blackhawk's answer works fine for a small example, I personally prefer to avoid modifying code to track down errors like that. If I'm working on a lot of files trying to track down a nasty bug, it's entirely possible that I might forget to remove any "special code" like Stop statements, etc. after I've finished debugging. If any such code makes it to production, that can be quite embarrassing for me. In addition, it can be annoying having to add this code to many different places in order to figure out where the error is happening in the first place (it's not always as obvious as in your example!).
For these reasons, I prefer to use the facilities provided by the VBA Editor. So:
Open the VBA Editor.
Go to Tools > Options.
Select the General tab and click the Break on All Errors radio button.
Click OK.
Now run your code and you'll notice that when it reaches this line:
n = 1/i
you'll get an error dialog saying what the problem is ("Run-time error '11': Division by zero") and you'll get the option to click the "Debug" button on the dialog, which will break execution at the above line and will highlight it in yellow.
Once you're done with your debugging and find the error that had been troubling you, you can go back to the VBA Editor options and revert the "Error Trapping" setting back to the default option ("Break on Unhandled Errors").
This way, you've done no changes to the code that you need to remember to revert before releasing the code and the actual operation to set/unset this behaviour only takes a few clicks.

Excel VBA: A much needed alternative for GOTO statement

I was creating an excel vba that has about say 20 modules(about 6 created and remaining under development).The code runs for a long time sometimes as it updates a minimum of 6 files to a maximum of upto 1200 files. The modules need to be updated in future so I have created a master module that goes through each of my modules and looks something like this :
Option Explicit
Sub CodeRunner()
Go_NoGo
'Module That decides when to run the Code and Sets the CDate.
CheckLastRunDate
'Module that checks when the code was last successfully Run.
DownloadListFile
'Downloads an updated list.csv file and makes some changes in it daily
DownloadBRVFile
'Downloads an updated BRV.csv file and makes some changes in it daily
FileUpdater
'Updates multiple files based on Updated BRV.csv and list.csv
'========================================
'And So on many more modules
'========================================
LogWriterModule:
EndofCode
End Sub
What i wanted to do was that whenever a module is called it should perform its function and if it finds something extra ordinary
IT SHOULD SKIP THE REMAINING CODE within the current module
and goto the LogWriterModule label in the master module
I Totally understand jumping over modules is not a good programmng habbit but here This helps me avoid contamination of huge data after which someone can intervene manually what went wrong with the help of logs..
I have an average knowledge of programming, but this is my somewhat 1st mega excel vba project
What I initially tried was I had used a GOTO statement to call the LogWriterModule in these separate modules but later came to know that the label must exist in the same module...
Has anyone any idea how can i achieve this without the use goto statements without the use of repetitive code that i may need to introduce as a last resort in my Master module ?
(i have a idea but its not a good solution to my problem. something like introducing a flag and checking it every time before the next module is called... )

Run Time Error 1004 When Inserting Rows/Columns

So I'm running into the lovely run time error 1004: Application defined or object defined error.
The bear of it is, half the time the code in VBA runs correctly with no problems, and the other half it falls on its face. The third line ("Mgmt.List.....") is run in a loop normally, but it has no problems messing up on me in this simple macro.
Sub whyyyy()
Dim Mgmt As Worksheet
Set Mgmt = Sheets("Mgmt MarginAnalysis")
Mgmt.ListObjects("Table4").ListRows.Add (3)
End Sub
The line
Mgmt.ListObjects("Table4").ListRows.Add (3)
is extra special, as when it's run in the loop, it will sometimes work the first time, but fail the second time. Or it will just fail outright.
Don't really know what makes it work and what doesn't. This just started happening, and the worksheet/table combination seems to only happen to tables I've just inserted recently (not by using VBA).
Are you sure, the Sheets("Mgmt Margin Analysis") has table named "Table4". If you are creating the table on runtime, chances are that, it will not be assigned the same name ("Table4") everytime it is created.
Please ensure you assign this name in your code, and do not let Excel to choose the name for you.