运行时错误49,错误的DLL调用约定

时间:2013-04-02 07:49:55

标签: excel vba

Q值。每当加载我的插件时,Excel都会抛出以下错误(运行时错误49,错误的DLL调用约定)

Error

尽管绝对没有外部DLL引用,但每次都会弹出对话框,但没有指出错误的位置。

Q值。每次保存特定代​​码行时Excel都会崩溃。

如何解决这个问题?

9 个答案:

答案 0 :(得分:13)

由于编译器错误,可能会发生此错误。 对此最简单的解决方案是进行小的代码更改并重新编译。 我通常做的是,

1 - >将Private Enum类型添加到插件

中任何模块的顶部
Private Enum Something
    member = 1
End Enum

2 - > 编译插件

3 - >重启excel

4 - >删除所做的代码更改。它不再是必要的。

答案 1 :(得分:7)

  1. 即使此错误引用外部(DLL)函数调用,它也是如此 可以由a的参数或返回值类型不匹配触发 VBA定义的函数或子例程。而且,当它是 由这些原因触发,调试器有时会显示错误 指向一个不同的函数调用,通常更高 call-stack,包括一直工作且稳定的调用 问题情况已经形成。通常,问题会被触发 通过固定类型参数 - 参数或返回值与a之间的未匹配 变体,反之亦然。

    示例:变量值函数返回a 分配给Integer变量的运行时的长值。

    解决

    • 仔细检查所有参数参数并返回 值类型和赋值语句,尤其是对于例程 你最近一直在努力。如果有任何变量值函数,则显式地为类型转换为正确的类型 分配
    • 如果由于使用Application.Run方法调用不同工作簿中的例程(您无法控制参数定义)而导致上述情况不可避免,则Application.Run方法会传递所有参数然后,如果包含例程是Sub,则尝试将其转换为没有指定返回类型的Function。这似乎强制清理堆栈并抑制在调用堆栈中抛出更高级别的错误情况。
  2. 应用于该方法不可用的错误对象变体的对象方法(如AutoFit)(如AutoFit) 被应用于既不是整行也不是整个行的范围 列范围)。与上述场景类似,错误可能是 抛出问题的例行程序的返回点 声明存在,而不是声明本身。

    解决方案:首先修复 语法问题。不幸的是,修复程序有时会起作用 继续抛出错误,直到重置VBE编辑器。一世 没有推断出解决该问题的最小步骤但是 像这样的东西经常有效:

    • 显式重新编译项目。
    • 保存文件并关闭它。
    • 重新打开文件并重新运行代码。
  3. 如果对外部库函数的调用被识别为罪魁祸首,请参阅Microsoft关于错误的文档:

    错误的DLL调用约定

    *传递给动态链接库(DLL)的参数必须完全匹配 常规所期望的那些。调用约定涉及数字, 类型和参数的顺序。你的程序可能正在调用例程 在传递错误类型或数量的参数的DLL中。

    要纠正此错误,请确保所有参数类型都符合这些 在您正在调用的例程的声明中指定。

    确保传递的是相同数量的参数 你要求的例行程序的声明。

    如果DLL例程需要按值进行参数,请确保ByVal为 为例程声明中的那些参数指定。

    返回参数: 有一点可以轻易忽略 谈论过程参数是返回参数。确保 它的类型正确,或者它没有丢失。 Excel / VBA用户 如果你遗漏了一个返回类型的事实已经习惯了 函数,系统隐式将返回类型设置为Variant,和 它适用于任何返回的数据。外部声明不是这样 功能!!返回类型必须在DECLARE中声明 语句。*

  4. 损坏的库引用:检查模块代码的库引用是否有效。在VBA IDE中,选择 工具=>引用以查看引用的库列表和make 确保没有选中的项目标记为“缺少”。如果是这样,请修复 那些。

答案 2 :(得分:2)

有关信息,我还在运行正常的Excel VBA代码中遇到了“运行时错误49,错误的DLL调用约定”

错误指向内部函数调用,我的修复是将参数从ByVal更改为ByRef。存在对另一个函数的调用,其中该值已经通过了ByRef,所以这可能是一个因素。

答案 3 :(得分:2)

OOOOOOOR ,有史以来最好的选择:

- 重写例程的名称。

- 然后重新编译!

你现在好了!

答案 4 :(得分:0)

为了添加另一个可能的原因,我使用 Application.OnTime 方法使用参数调用public sub。该参数意味着很长(当前行),但我猜测它实际上是作为字符串值传递的。

以下是OnTime调用的示例:

Application.OnTime Now + TimeValue("00:00:01"), "'UpdateEditedPref " & curRow & "'"

我尝试对代码执行任意更新并重新编译,但这并没有解决问题。修复它的方法是在被调用的子中将参数类型从long更改为string:

Public Sub UpdateEditedPref(ByVal inRowStr As String)

然后你只需要将字符串转换为sub中的值。谢天谢地,没有更多的错误。

更新: 使用 Application.OnTime 传递参数似乎导致了其他错误,"无法运行宏&#34 ;。当工作表被锁定时,我收到此错误。我仍在使用 Application.OnTime ,但是我没有传递参数,而是将值保存在全局变量中并在被调用的子中使用该值。现在这似乎工作正常。

OnTime调用现在看起来像这样:

' Set global variable
gCurRow = curRow

Application.OnTime Now + TimeValue("00:00:01"), "UpdateEditedPref"

答案 5 :(得分:0)

我有一个类似的问题,在我的开发PC上工作得很好。有趣的是,我有两个单独的调用相同的例程,一个工作,另一个没有。在生产PC上,不断收到错误。尝试重命名例程,更改参数,参数类型无济于事。

对我来说有用的是将失败的调用例程移动到与被调用子例程相同的模块中。

以前工作的例程已经在同一个模块中。

答案 6 :(得分:0)

另一种替代方法是“ /反编译”项目,而不是“更改/添加某些内容并重新编译”。 Esp。在可能会遇到很多问题的大型访问/ excel项目中。

答案 7 :(得分:0)

在我的情况下,这是由于在单个(如果有条件的情况下)过度使用继续字符_造成的

我已经重新编译,检查了所有返回代码,移动了模块,重新启动excel,重新启动计算机,将代码复制到全新的Excel电子表格中,我读了这篇文章,有关返回代码的一些内容让我开始思考if语句中有多少个返回值

我有这个

    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

退出包含此代码的子例程时出现错误 所以我改成了这个

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>

错误消失

答案 8 :(得分:-1)

费尔南多的解决方案运作良好......

在我的场景中,我有一个Main Sub调用Another Sub,当流返回到Main Sub时代码失败。 我刚刚重命名了Another Sub,重新编译了项目并找到了原始子名称时出错。然后我将其命名为原始版本并重新编译,没有问题。

之后该宏没有抛出运行时错误49 ...

由于

Sysss