Q. Excel keeps throwing the following error, whenever my addin is loaded (Runtime Error 49, Bad DLL calling convention)
Another way instead of "change/add something and recompile" would be to /decompile your project. Esp. in large access/excel projects that can get ride of a lot of problems.
Just to add another possible cause, I was using the Application.OnTime method to call a public sub with a parameter. The parameter is meant to be a long (the current row), but I'm guessing it's actually passed as a string value.
Here is an example of the OnTime call:
Application.OnTime Now + TimeValue("00:00:01"), "'UpdateEditedPref " & curRow & "'"
I tried performing an arbitrary update to the code and recompiling, but this didn't fix the issue. What fixed it was changing the parameter type from long to string in the called sub:
Public Sub UpdateEditedPref(ByVal inRowStr As String)
Then you just need to convert the string to a value within the sub. Thankfully, no more error.
Update: Passing a parameter using Application.OnTime seems to have caused another error, "Cannot run the macro". I was getting this error when the worksheet was locked. I'm still using Application.OnTime, but instead of passing a parameter, I'm saving the value in a global variable and using that value in the called sub. This now appears to be working correctly.
The OnTime call now looks like this:
' Set global variable
gCurRow = curRow
Application.OnTime Now + TimeValue("00:00:01"), "UpdateEditedPref"
For info, I also experienced "Runtime Error 49, Bad DLL calling convention" in Excel VBA code that had been running fine.
The error was pointing to an internal function call and the fix for me was to change an argument from ByVal to ByRef. There existed a call to another function where that value was already passed ByRef, so this may have been a factor.
This error is probably occurring because of a compiler-bug. The easiest solution to this, would be to make a small code-change and recompile. What I usually do is,
1 -> Add a Private Enum
type to the top of any module in the addin
Private Enum Something
member = 1
End Enum
2 -> Compile the addin
3 -> Restart excel
4 -> Remove the code change made. It is no longer necessary.
Even though this error refers to an external (DLL) function call, it can be triggered by a parameter or return-value type mismatch for a VBA-defined function or subroutine. Furthermore, when it is triggered by these causes, the debugger sometimes displays the error point to be a different function call, often higher in the call-stack, including calls that have been working and stable until the problem-situation was created. Often, the problem is triggered by a miss-match between a fixed-type parameter-argument or return value and a Variant or vice versa.
Example: A Variant-valued function returns a Long value at run time that is assigned to an Integer variable.
Resolution:
An object method (such as AutoFit) applied to an erroneous object variation for which that method isn’t available (such as AutoFit being applied to a range that is neither an entire row or entire column range). Similarly to the above scenario, the error may be thrown at the return point of the routine in which the problem statement exists, not at the statement itself.
Resolution: Start with fixing the syntax problem. Unfortunately fixes that should work sometimes continue to throw the error until the VBE editor is reset. I haven’t deduced the minimal set of steps that resolve that issue but something like this often works:
If a call to an external library function is identified as the culprit, refer to Microsoft’s documentation on the error:
Bad DLL calling convention
*Arguments passed to a dynamic-link library (DLL) must exactly match those expected by the routine. Calling conventions deal with number, type, and order of arguments. Your program may be calling a routine in a DLL that is being passed the wrong type or number of arguments.
To correct this error make sure all argument types agree with those specified in the declaration of the routine that you are calling.
Make sure you are passing the same number of arguments indicated in the declaration of the routine that you are calling.
If the DLL routine expects arguments by value, make sure ByVal is specified for those arguments in the declaration for the routine.
Return argument: One thing that can be easily overlooked when talking about procedure arguments is the return argument. Make sure its of the correct type, or that its not missing. Excel/VBA users are used to the fact that if you leave out a return type for a function, the system implicitly sets the return type to Variant, and it works with any returned data. Not so with externally declared functions!! The return type has to be declared in the DECLARE statement.*
Broken library references: check whether the library references for your module code are valid. In the VBA IDE, select Tools=>References to see the list of referenced libraries and make sure none of the checked items are marked "Missing". If so, fix those.
Or, the best option ever:
- Rewrite the name of the routine.
- Then recompile !
You're good to go now!