Excel VBA编译错误求助:参数数量错误或属性赋值无效
VBA编译错误:Wrong Number of arguments or invalid property assignment 解决方法
问题根源分析
编译错误的核心原因是API函数声明的参数类型不匹配,以及常量类型不一致:
SetCursorPos和mouse_event的PtrSafe声明参数类型错误,导致VBA无法正确解析函数调用的参数数量和类型- 部分鼠标事件常量被错误声明为
LongPtr类型,与其他常量类型不统一
修复步骤
1. 修正API函数声明
替换原有的两行API声明为以下正确版本:
' 64位Office兼容的SetCursorPos声明 Public Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long ' 64位Office兼容的mouse_event声明 Public Declare PtrSafe Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As LongPtr)
SetCursorPos的参数x/y是32位整数,对应VBA的Long类型,返回值也是32位布尔值,用Longmouse_event中dwFlags/dx/dy/cButtons为32位DWORD类型,用Long;dwExtraInfo是64位指针类型,用LongPtr
2. 统一常量类型
将所有鼠标事件常量改为Long类型(原代码中部分常量错误使用LongPtr):
Public Const MOUSEEVENTF_LEFTDOWN = &H2 Public Const MOUSEEVENTF_LEFTUP = &H4 Public Const MOUSEEVENTF_RIGHTDOWN = &H8 Public Const MOUSEEVENTF_RIGHTUP = &H10
3. 可选优化:直接操作单元格替代模拟鼠标
你的目标是点击Excel单元格,模拟鼠标操作依赖屏幕坐标,容易受窗口位置、缩放比例影响,更可靠的方式是直接操作单元格:
比如把模拟点击的代码替换为:
' 替代SetCursorPos+mouse_event的直接操作 Cells(行号, 列号).Activate ' 或 .Select
修复后的完整代码
Public Declare PtrSafe Function SetCursorPos Lib "user32" (ByVal x As Long, ByVal y As Long) As Long Public Declare PtrSafe Sub mouse_event Lib "user32" (ByVal dwFlags As Long, ByVal dx As Long, ByVal dy As Long, ByVal cButtons As Long, ByVal dwExtraInfo As LongPtr) Public Const MOUSEEVENTF_LEFTDOWN = &H2 Public Const MOUSEEVENTF_LEFTUP = &H4 Public Const MOUSEEVENTF_RIGHTDOWN = &H8 Public Const MOUSEEVENTF_RIGHTUP = &H10 Sub MoveMousePlease() Dim i As Integer For i = 1 To 9999 If Cells(3, 5) = "" Then SetCursorPos 350, 300 mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 WaitPlease SetCursorPos 350, 360 mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 WaitPlease SetCursorPos 350, 420 mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 WaitPlease SetCursorPos 350, 480 mouse_event MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0 mouse_event MOUSEEVENTF_LEFTUP, 0, 0, 0, 0 WaitPlease Else Exit For End If Next i End Sub Sub WaitPlease() Dim sngWaitEnd As Single sngWaitEnd = Timer + 5 Do DoEvents Cells(3, 3).Value = Timer Loop Until Timer >= sngWaitEnd End Sub
内容的提问来源于stack exchange,提问作者Crick
相关产品推荐
相关产品推荐

