我试图让VBA解雇命令
sImportFilePath = Application.GetOpenFilename(FileFilter:= _
"Excel Files (*.xls), *.xls", Title:="Choose The Source File")
Application.Workbooks.Open (sImportFilePath)
sImportFileName = FunctionGetFileName(sImportFilePath)
当我单步执行该功能时它们会起作用,但当我使用热键 Ctrl + Shift + F 或任何其他热键时,Application.Workbooks.Open
命令可以正常工作,但它会导航新的Excel文档,然后什么都不做。但是,当我打开" Macros"在开发人员选项卡中,选择我的宏,然后单击"运行"一切都运行良好。
答案 0 :(得分:21)
我实际上遇到了这个问题,最终找到了解决问题的方法。
您用来调用代码的键盘快捷键中的 Shift 按钮。
显然,Excel中的一项功能专门用于防止在打开工作簿并按下 Shift 键时运行代码,但不幸的是,这也会影响使用Workbook.Open
方法打开工作簿通过VBA。这在KB Article 555263中提到,适用于Excel 2000& 2003年,但我在Excel 2010中遇到了同样的问题,所以我想它也会对2007年产生影响。
当您尝试在程序的早期通过代码打开工作簿时,会发生这种情况。如果在您有足够的时间实际放开 Shift 按钮之前已在代码中达到Workbook.Open
调用,则Excel会将其解释为阻止代码运行并中止该过程。并且没有错误消息或我找到的任何内容。它突然停止了。
解决方法/修复方法是强制代码在发出Workbook.Open
命令之前等待释放Shift键。
根据这篇文章,只需将此代码添加到您的宏中即可:
'Declare API
Declare Function GetKeyState Lib "User32" (ByVal vKey As Integer) As Integer
Const SHIFT_KEY = 16
Function ShiftPressed() As Boolean
'Returns True if shift key is pressed
ShiftPressed = GetKeyState(SHIFT_KEY) < 0
End Function
Sub Demo()
Do While ShiftPressed()
DoEvents
Loop
Workbooks.Open Filename:="C:\MyPath\MyFile.xlsx"
End Sub
(注意:此代码适用于32位版本的Excel.64位版本需要使用PtrSafe
语句中的Declare
属性。
如果您不想添加额外的代码,那么您唯一的其他选择是不使用 Ctrl + Shift + Some Letter 启动宏,或稍后将Workbook.Open
命令放在宏中(不在开头),以便在启动后释放Shift按钮。
答案 1 :(得分:3)
只需向&#34; DoEvents&#34;添加一个电话在调用Workbooks.Open之前就已经开始了。 所以下面的代码片段将起作用:
DoEvents
Workbooks.Open Filename:="C:\MyPath\MyFile.xlsx"
答案 2 :(得分:1)
问题在这行代码之前的任何时候你都有一行代码选择多个标签?我发现这有点像在移动键中选择它们的整个时间。为了解决这个问题,我有一个宏取消组合(单选)一个选项卡,然后宏开始工作。
答案 3 :(得分:0)
为我做的一个简单的解决方法是将VBA分配给没有移位的快捷键。我并不是这样做的忠实粉丝,因为与dafault Excel快捷方式存在更多冲突。但是基于this article的Excel 2010中有一些可用:Ctrl + e,Ctrl + j,Ctrl + m,Ctrl + q。
答案 4 :(得分:0)
法国论坛上的临时解决方案:使用以下 ForEachWinDoEvents 在激活您选择的工作簿之前。
Sub Test()
Application.ScreenUpdating = False
Set w1 = Workbooks.Add(xlWBATWorksheet)
Set w2 = Workbooks.Add(xlWBATWorksheet)
Set w3 = Workbooks.Add(xlWBATWorksheet)
Application.ScreenUpdating = True
ForEachWinDoEvents
w2.Activate
End Sub
Sub ForEachWinDoEvents()
Dim win As Window
For Each win In Application.Windows
DoEvents
Next win
End Sub