Excel VBA SendKeys 在尝试发送到 Excel 加载项时不起作用
Excel VBA SendKeys not working when trying to Send to Excel Add-In
简介。:在我公司,我们在 Excel 中安装了一个安全插件,阻止我们在不输入的情况下保存新的 Excel 工作簿需要的参数。
挑战:使用 SendKeys
发送此 Excel 加载项所需的密钥。
问题:当加载项屏幕弹出时(如下面的屏幕截图所示),代码似乎没有继续到这一行: SendKeys " ", True
.
我的代码(相关部分)
编辑 1:下面的代码在 For
循环内,我正在为每个用户向该用户导出一个 filterred 数据库。因此,每次我尝试为其中一个用户保存文件时,我都会遇到加载项(我需要 "by-pass" 它在 For
循环中)。
' sort the PM's workbook , hide source data
Application.DisplayAlerts = False
NewWB.Sheets("Combined").Visible = False
NewWB.Sheets("Sheet3").Delete
NewWB.SaveAs "Budget usage - " & Year(Date) & "-" & Month(Date - 30) & " " & PMList(r)
Dim i As Long
SendKeys " ", True ' <-- it doesn't get to this line when the Excel Add-In pops up
For i = 1 To 3
SendKeys "+{DOWN}", True
Next i
SendKeys "{ENTER}", True
For i = 1 To 4
SendKeys "+", True
Next i
SendKeys "{ENTER}", True
您启动插件弹出窗口的事实 "froze" 代码。
我不知道如何在 VBA 中异步执行此操作(现在我开始使用 VB.NET 我对这些事情感觉好多了!)。
我能想到的最好的是:
- 保存在一个临时文件(temp.vbs for ex)一些代码和 运行 它在启动表单之前:
Dim s$
s = "Set WshShell = WScript.CreateObject(""WScript.Shell"")" & vbNewLine & _
"WScript.Sleep 6000" & vbNewLine & _
"WshShell.SendKeys ""+{TAB}""" & vbNewLine & _
"WshShell.SendKeys ""~"""
CreateObject("Scripting.FileSystemObject").createtextfile(FileName).write s
shell(filename)
看起来您的插件在保存事件之前正在下沉应用程序工作簿,因此允许保存的快速修复是再次下沉它,因此在您的代码中,具有以下内容
在普通模块中有以下
Public cResink As clsResinkApplication
有一个名为 clsResinkApplication 的 class,class 的代码如下
Private WithEvents resinkApp As Excel.Application
Public Sub init2(appToResink As Excel.Application)
Set resinkApp = appToResink
End Sub
Private Sub resinkApp_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
ActiveWorkbook.SaveAs "test.xlsx"
End Sub
然后在打开的工作簿中可以有如下内容
Private Sub Workbook_Open()
Set cResink = New clsResinkApplication
cResink.init2 Application
End Sub
这应该在插件的之前转移到您的保存槽。
Public Sub TryMe()
Dim s As String
Dim sPath As String
Dim sTitle As String: sTitle = "runme.vbs"
s = "Set WshShell = WScript.CreateObject(""WScript.Shell"")" & vbNewLine & _
"WScript.Sleep 6000" & vbNewLine & _
"WshShell.SendKeys ""+{TAB}""" & vbNewLine & _
"WshShell.SendKeys ""~"""
CreateObject("Scripting.FileSystemObject").createtextfile(sTitle).write s
sPath = "wscript " & ThisWorkbook.Path & "\runme.vbs"
Shell sPath, vbNormalFocus
End Sub
@Pierre - 你的想法是写这样的东西^^ ?
然后在调用表单之前调用它,然后在某个地方删除它?最初我认为你不会在任何地方创建文件,但现在我已经尝试过并且我注意到了。应该可以。
感谢@Vityata 和@Pierre 提出了使用 VBScript 的想法,并在 VBA 代码中编写了 VBScipt 的内容。
我最后做的是:
1. 在调用我的保存之前添加了 Call WShellSendKeys
。
'========== Call the VBScript to run a Shell to send to Keys in the background ======
Call WShellSendKeys
NewWB.SaveAs "Budget usage - " & Year(Date) & "-" & Month(Date - 30) & " " & PMList(r)
2.
检查VBScirt是否已经存在,如果不存在则创建它。
Public Sub WShellSendKeys()
Dim wsh As Object
Dim objFile As Object
Dim objFSO As Object
Set wsh = VBA.CreateObject("WScript.Shell")
If Dir(VBScrPath) <> "" Then ' <-- VBS file name already exits in folder >> there's no need to re-create it, just run it
' Run Shell
wsh.Run "wscript " & Chr(34) & VBScrPath & Chr(34), vbNormalFocus
Else ' VBS file name doesn't exits in folder >> create it
Call WriteToVBS
wsh.Run "wscript " & Chr(34) & VBScrPath & Chr(34), vbNormalFocus
End If
End Sub
3。
另一个使用 SendKeys
.
创建 VBScript 的 Sub
Sub WriteToVBS()
Dim objFile As Object
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(VBScrPath, 8, True)
' --- Text to write into the VBScript file ---
objFile.WriteLine ("Option Explicit")
objFile.WriteLine ("")
objFile.WriteLine ("Dim WshShell")
objFile.WriteLine ("Dim i")
objFile.WriteLine ("")
objFile.WriteLine ("Set WshShell = CreateObject(""WScript.Shell"")")
objFile.WriteLine ("WScript.Sleep(4000)")
objFile.WriteLine ("")
objFile.WriteLine ("WshShell.SendKeys ""{R}"",True")
objFile.WriteLine ("WScript.Sleep(1000)")
objFile.WriteLine ("For i = 1 To 2")
objFile.WriteLine ("WshShell.SendKeys ""{ENTER}"",True")
objFile.WriteLine ("WScript.Sleep(1000)")
objFile.WriteLine ("Next")
objFile.Close
Set objFile = Nothing
Set objFSO = Nothing
End Sub
简介。:在我公司,我们在 Excel 中安装了一个安全插件,阻止我们在不输入的情况下保存新的 Excel 工作簿需要的参数。
挑战:使用 SendKeys
发送此 Excel 加载项所需的密钥。
问题:当加载项屏幕弹出时(如下面的屏幕截图所示),代码似乎没有继续到这一行: SendKeys " ", True
.
我的代码(相关部分)
编辑 1:下面的代码在 For
循环内,我正在为每个用户向该用户导出一个 filterred 数据库。因此,每次我尝试为其中一个用户保存文件时,我都会遇到加载项(我需要 "by-pass" 它在 For
循环中)。
' sort the PM's workbook , hide source data
Application.DisplayAlerts = False
NewWB.Sheets("Combined").Visible = False
NewWB.Sheets("Sheet3").Delete
NewWB.SaveAs "Budget usage - " & Year(Date) & "-" & Month(Date - 30) & " " & PMList(r)
Dim i As Long
SendKeys " ", True ' <-- it doesn't get to this line when the Excel Add-In pops up
For i = 1 To 3
SendKeys "+{DOWN}", True
Next i
SendKeys "{ENTER}", True
For i = 1 To 4
SendKeys "+", True
Next i
SendKeys "{ENTER}", True
您启动插件弹出窗口的事实 "froze" 代码。 我不知道如何在 VBA 中异步执行此操作(现在我开始使用 VB.NET 我对这些事情感觉好多了!)。 我能想到的最好的是: - 保存在一个临时文件(temp.vbs for ex)一些代码和 运行 它在启动表单之前:
Dim s$
s = "Set WshShell = WScript.CreateObject(""WScript.Shell"")" & vbNewLine & _
"WScript.Sleep 6000" & vbNewLine & _
"WshShell.SendKeys ""+{TAB}""" & vbNewLine & _
"WshShell.SendKeys ""~"""
CreateObject("Scripting.FileSystemObject").createtextfile(FileName).write s
shell(filename)
看起来您的插件在保存事件之前正在下沉应用程序工作簿,因此允许保存的快速修复是再次下沉它,因此在您的代码中,具有以下内容
在普通模块中有以下
Public cResink As clsResinkApplication
有一个名为 clsResinkApplication 的 class,class 的代码如下
Private WithEvents resinkApp As Excel.Application
Public Sub init2(appToResink As Excel.Application)
Set resinkApp = appToResink
End Sub
Private Sub resinkApp_WorkbookBeforeSave(ByVal Wb As Workbook, ByVal SaveAsUI As Boolean, Cancel As Boolean)
ActiveWorkbook.SaveAs "test.xlsx"
End Sub
然后在打开的工作簿中可以有如下内容
Private Sub Workbook_Open()
Set cResink = New clsResinkApplication
cResink.init2 Application
End Sub
这应该在插件的之前转移到您的保存槽。
Public Sub TryMe()
Dim s As String
Dim sPath As String
Dim sTitle As String: sTitle = "runme.vbs"
s = "Set WshShell = WScript.CreateObject(""WScript.Shell"")" & vbNewLine & _
"WScript.Sleep 6000" & vbNewLine & _
"WshShell.SendKeys ""+{TAB}""" & vbNewLine & _
"WshShell.SendKeys ""~"""
CreateObject("Scripting.FileSystemObject").createtextfile(sTitle).write s
sPath = "wscript " & ThisWorkbook.Path & "\runme.vbs"
Shell sPath, vbNormalFocus
End Sub
@Pierre - 你的想法是写这样的东西^^ ?
然后在调用表单之前调用它,然后在某个地方删除它?最初我认为你不会在任何地方创建文件,但现在我已经尝试过并且我注意到了。应该可以。
感谢@Vityata 和@Pierre 提出了使用 VBScript 的想法,并在 VBA 代码中编写了 VBScipt 的内容。
我最后做的是:
1. 在调用我的保存之前添加了 Call WShellSendKeys
。
'========== Call the VBScript to run a Shell to send to Keys in the background ======
Call WShellSendKeys
NewWB.SaveAs "Budget usage - " & Year(Date) & "-" & Month(Date - 30) & " " & PMList(r)
2. 检查VBScirt是否已经存在,如果不存在则创建它。
Public Sub WShellSendKeys()
Dim wsh As Object
Dim objFile As Object
Dim objFSO As Object
Set wsh = VBA.CreateObject("WScript.Shell")
If Dir(VBScrPath) <> "" Then ' <-- VBS file name already exits in folder >> there's no need to re-create it, just run it
' Run Shell
wsh.Run "wscript " & Chr(34) & VBScrPath & Chr(34), vbNormalFocus
Else ' VBS file name doesn't exits in folder >> create it
Call WriteToVBS
wsh.Run "wscript " & Chr(34) & VBScrPath & Chr(34), vbNormalFocus
End If
End Sub
3。
另一个使用 SendKeys
.
Sub WriteToVBS()
Dim objFile As Object
Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(VBScrPath, 8, True)
' --- Text to write into the VBScript file ---
objFile.WriteLine ("Option Explicit")
objFile.WriteLine ("")
objFile.WriteLine ("Dim WshShell")
objFile.WriteLine ("Dim i")
objFile.WriteLine ("")
objFile.WriteLine ("Set WshShell = CreateObject(""WScript.Shell"")")
objFile.WriteLine ("WScript.Sleep(4000)")
objFile.WriteLine ("")
objFile.WriteLine ("WshShell.SendKeys ""{R}"",True")
objFile.WriteLine ("WScript.Sleep(1000)")
objFile.WriteLine ("For i = 1 To 2")
objFile.WriteLine ("WshShell.SendKeys ""{ENTER}"",True")
objFile.WriteLine ("WScript.Sleep(1000)")
objFile.WriteLine ("Next")
objFile.Close
Set objFile = Nothing
Set objFSO = Nothing
End Sub