2013-04-02 46 views
7

问:Excel中不断抛出下面的错误,每当我的插件加载(运行时错误49,错误的DLL调用约定)运行时错误49,错误的DLL调用约定

Error

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

OR

问:Excel中崩溃每次我救一个特定的代码行时间。

这怎么解决?

回答

12

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

1 - >添加Private Enum类型的任何模块的顶部的插件

Private Enum Something 
    member = 1 
End Enum 

2 - >编译的插件

3 - >重新启动excel

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

+0

有趣!出于好奇:您如何设法在同一时间发布问题和答案?你是否“预先写好”答案? –

+1

@PeterAlbert发布​​问题时有一个复选框,[自己回答](http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-自身的问题/)。 –

+4

我使用以下快捷键:'Ctrl + A' - 'Ctrl + X' - 'Ctrl + V' - 'Ald + D' - 'L' – stenci

6
  1. 即使这种错误是指外部(DLL)函数调用,它 可以通过参数或者触发返回值用于 VBA定义的函数或子程序类型不匹配。此外,当由这些原因触发的 时,调试器有时会显示错误 指向一个不同的函数调用,通常在 调用堆栈中更高,包括一直工作并且稳定的调用,直到 问题状况为止创建。通常,通过固定类型参数参数或返回值与 变体之间的错误匹配触发 ,反之亦然。

    示例:变量值函数返回一个 运行时分配给Integer变量的Long值。

    分辨率

    • 仔细检查所有参数,参数和返回值 类型和赋值语句,尤其是对于那些 你最近已经工作程序。如果有变量值函数,则明确地将其类型转换为 赋值的正确类型。
    • 如果由于使用Application.Run方法调用其他工作簿中的例程(因为您无法控制参数定义),上述情况不可避免,因为Application.Run方法会传递所有参数然后,如果包含例程是一个Sub,请尝试将其转换为一个没有指定返回类型的函数。这似乎强制清除堆栈并抑制在调用堆栈中更高级别抛出的错误条件。
  2. (如自动调整)施加到一个错误的对象的变化能够识别此方法不可用的对象方法(如自动调整 施加到既不是一整行或整列 范围的范围)。类似于上面的情况,错误可能是 抛出在存在问题 声明的例程的返回点,而不是语句本身。

    分辨率:从修复 语法问题开始。不幸的修复程序应该有效地工作,直到VBE编辑器被重置,有时 继续抛出错误。我 没有推导出的最小的一套解决这一问题,但 这样的事情经常工作步骤:

    • 明确重新编译该项目。
    • 保存该文件并关闭它。
    • 重新打开文件并重新运行代码。
  3. 如果外部库函数被确定为罪魁祸首,是指微软的错误文档:

    错误的DLL调用约定

    *参数传递给一个动态链接库(DLL)必须与例程中预期的那些完全匹配。调用约定涉及编号, 类型和参数的顺序。您的程序可能会调用正在传递错误类型或数量的参数的DLL中的例程 。

    纠正此错误确保所有参数类型与您正在调用的例程声明中指定的那些 一致。

    确保您传递的参数数量与 中指示的参数数量相同,即您正在调用的例程的声明。

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

    返回参数 有关 谈论过程参数时容易被忽略的一点是返回参数。确保 其正确的类型,或者说它不会丢失。 Excel/VBA用户 用于这样一个事实,即如果省略 函数的返回类型,则系统会隐式地将返回类型设置为Variant,并且 可与任何返回的数据一起使用。与外部宣称的 功能不一样!返回类型必须在DECLARE 声明中声明。*

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

2

有关的信息,我也经历“运行时错误49,错误的DLL调用约定”在已经运行良好的Excel VBA代码。

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

0

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

这里是准时调用的例子:

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

我试图执行的代码并重新编译任意更新,但这并没有解决问题。什么固定它是从长期改变参数类型为字符串中的称为子:

Public Sub UpdateEditedPref(ByVal inRowStr As String) 

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

更新:传递使用Application.OnTime参数似乎造成了另一个错误,“无法运行宏”。当工作表被锁定时,我收到了这个错误。我仍然使用Application.OnTime,但不是传递参数,而是将值保存在全局变量中,并在被调用的子项中使用该值。这现在似乎工作正常。

接通时间的呼叫现在看起来是这样的:

' Set global variable 
gCurRow = curRow 

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

OOOOOOOR,永远是最好的选择:

- 改写程序的名称。

- 然后重新编译!

你现在很好走!

+0

这个答案在细节和细节方面都欠缺。虽然有些人可能不同意这种'口气' - 我对此很好,实际上,我喜欢它,但答案本身就是想... – JoeG

+0

JoeG,我尊重你的意见。希望你明白,如果我能提供更多的细节,我会的。但是,请在出现问题时回到这里,在我提出的解决方案之前尝试尽一切可能。然后尝试此解决方案。它会像魅力一样工作。这是一个承诺。 关于基调,感谢您对此感到满意。 –

+0

在测试之前给答案-1实际上是我强烈反对的。 –

-1

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

在我的情况我有一个主要的子调用另一个Sub和当流量返回到主要的子代码只是失败。 我刚更名为Another Sub,重新编译的项目,并且发现原始子名称时出错。然后我将它命名为原始文件,然后重新编译而没有问题。

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

感谢

Sysss

+0

你应该评论费尔南多的答案...而不是张贴这个评论作为答案。它没有提供新的东西。 – Rdster

+0

是的,这是事实。 – sysss