13

Q. Excel keeps throwing the following error, whenever my addin is loaded (Runtime Error 49, Bad DLL calling convention)

Error

The dialog starts to pop up everytime with no indication of where the error is, despite having absolutely no external DLL references.

OR

Q. Excel crashes every time I save a particular line of code.

How can this be fixed?

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191

9 Answers9

20

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.

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
9
  1. 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:

    • Carefully check all parameter-argument and return value types and assignment statements, especially for routines that you have been recently working on. If any are Variant-valued functions, explicitly type-cast to the correct type for the assignment.
    • If the above situation is unavoidable due to using the Application.Run method to call a routine in a different workbook (for which you have no control over the parameter definitions), as a result of the Application.Run method passing all arguments ByVal, then, if the containing routine is a Sub, try converting it to a Function with no specified return type. This seems to force a clean-up of the stack and suppresses the error condition being thrown at a higher level in the call-stack.
  2. 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:

    • Explicit recompile the project.
    • Save the file and close it.
    • Re-open the file and re-run the code.
  3. 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.*

  4. 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.

pstraton
  • 1,080
  • 14
  • 9
8

Or, the best option ever:

- Rewrite the name of the routine.

- Then recompile !

You're good to go now!

SecretAgentMan
  • 2,856
  • 7
  • 21
  • 41
  • This answer is lacking in detail and specifics. While some might disagree with the 'tone' - I am fine with that, actually, I like it, but the answer itself is wanting... – JoeG Apr 19 '16 at 14:10
  • JoeG, I respect your opinion. Hope you understand that if I could offer more details, I would. BUT, please, come back here when you have the issue, and try everything you can, before the solution I suggested. Then try this solution. It will work like a charm. That's a promise. About the tone, thanks for being fine with that. – Fernando Fernandes Apr 22 '16 at 16:58
  • 2
    Giving -1 to the answer before testing it is actually something I strongly disagree. – Fernando Fernandes Apr 22 '16 at 17:03
  • Worked for me. I was at a loss - nothing logical was working. @FernandoFernandes has my vote! Thanks mate! – joehanna Nov 04 '18 at 04:31
3

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.

sandbrain
  • 31
  • 1
  • Thanks for posting this comment. I was passing a String argument ByRef instead of ByVal, and that was enough to trigger this warning. Based on your comment, I changed the function signature to "ByVal", and the error message was gone. – Pflugs Oct 13 '22 at 05:09
1

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.

Stejin
  • 64
  • 4
0

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"
0

I had a similar issue, on my development PC it was working just fine. Funny thing was I had two separate calls to the same routine, one worked and the other didn't. On a production PC, kept getting the error. Tried renaming the routine, changing the parameters, parameter types to no avail.

What worked for me was to move the failing calling routine into the same module as the called subroutine.

The routine that was working previously was already in the same module.

wallyeye
  • 116
  • 5
0

In my case this was "caused" by an excessive use of the continue character _ in a single if conditional

I had already recompiled, checked all return codes, moved modules around ,restarted excel , restarted my computer, copied the code to a brand new Excel spread-sheet, I read this article and the bit about return codes made me think about how many returns can be in an if statement

I had this

    If CompressIntoOneLineON(rg1, rgstart, rgend) or _
       CompressIntoOneLineOS(rg1, rgstart, rgend) or _
       CompressIntoOneLineOGN(rg1, rgstart, rgend) or _
       CompressIntoOneLineOGS(rg1, rgstart, rgend) or _
       CompressIntoOneLineGO(rg1, rgstart, rgend) Then
       <code>
    End If

I was getting the error when the subroutine containing this code exited So I changed to this

matched = True
If CompressIntoOneLineON(rg1, rgstart, rgend) Then
ElseIf CompressIntoOneLineOS(rg1, rgstart, rgend) Then
ElseIf CompressIntoOneLineOGN(rg1, rgstart, rgend) Then
ElseIf CompressIntoOneLineOGS(rg1, rgstart, rgend) Then
ElseIf CompressIntoOneLineGO(rg1, rgstart, rgend) Then
Else
  matched = False
End If
if matched then
  <code>

and the error went away

Ross
  • 186
  • 1
  • 8
0

My experiments have shown: The error: 'Runtime Error 49, Bad DLL calling convention' disappeared when I replaced the declarations:

Dim coll as new Collection

on

Dim coll as Collection
Set coll = New Collection

The object must explicitly become Nothing on failure of creation (if it does not itself) so that its existence can be traced.

Thanks, RubberDuck VBA