2017-01-18 13 views
3

Введение.: В моей компании у нас есть надстройка безопасности, установленная в Excel, не позволяющая нам сохранять новую книгу Excel без ввода необходимых параметров.Excel VBA SendKeys не работает при попытке отправить в Excel надстройку

Задача: использовать SendKeys для отправки ключей, необходимых для этой надстройки Excel.

Проблема: когда Add-In экране всплывает (как можно видеть на скриншоте ниже) код, кажется, не продолжать эту линию: SendKeys " ", True.

Classification Add-In

Мой код (соответствующая часть)

Edit 1: Приведенный ниже код находится внутри For цикла, я экспортирования filterred БД для каждого пользователя к пользователю. Поэтому каждый раз, когда я пытаюсь сохранить файл для одного из пользователей, я буду сталкиваться с надстройкой (мне нужно, чтобы «обход» внутри цикла 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 
+0

У вас есть доступ к коду AddIn? Можете ли вы изменить код, показывая форму 'UserForm1.Show vbModeless'? – Vityata

+0

@Vityata Нет, я хочу :) –

+1

Имеет ли админ какой-либо общедоступный доступ, поэтому «MyAddIn.» после точки, что говорит intellisense, может быть установлен как «MyAddin.Value = ValueToSet» –

ответ

2
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 - ваша идея написать что-то вроде этого ^^?

Затем позвонить, прежде чем вызывать форму, а затем удалить ее где-нибудь позже? Сначала я думал, что вы нигде не создаете файл, но теперь я попробовал его, и я заметил. Он должен работать.

+0

Спасибо , принял ваше представление о фактической настройке содержимого VBS внутри VBA, и большинство importatn, чтобы сохранить 'vbNormalFocus' –

+0

Спасибо, я также узнал из ответа @Pierre. – Vityata

2

Тот факт, что вы запустили всплывающее окно «заморозило» код. Я не знаю, как это сделать асинхронно в VBA (теперь я начал использовать VB.NET, я чувствую себя намного лучше об этом!). Лучший я могу придумать это: - сохранить в файле temparary (temp.vbs для экс) код и запустить его перед запуском формы:

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) 
+0

Я думал о том же (но моя идея была немного ламером, чтобы сделать скрипт в отдельном файле и называть его из VBA)! – Vityata

+0

@Pierre не уверен, что я полностью понимаю, где положить его в код, этот раздел выше находится внутри цикла 'For', я сохраняю несколько файлов для каждого менеджера проектов. –

+0

@Vityata: хорошо моя тоже хромая, просто «чистая», потому что вы можете удалить VBS после использования – Pierre

2

Это выглядит так, как будто ваша надстройка будет погружая приложение учебное пособие, прежде чем сохранить событие, так быстро исправить, чтобы сэкономить, будет тонуть его снова, так что в вашем коде, имеет следующую

в нормальном модуле имеет следующее

Public cResink As clsResinkApplication 

есть класс называется clsResinkApplication и Код для этого класса будет выглядеть следующим образом

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 

Это должно отвлечь на вашу сохранить мойку перед раскладом надстройки в.

+0

спасибо за вашу помощь, я закончил с помощью VBScript, но мне нравится знать, что я могу зациклиться на 'AddIns' :) –

1

Я хотел бы поблагодарить @Vityata, @Pierre за идею сделать это с помощью VBScript, а также написать содержимое VBScipt внутри кода VBA.

То, что я в конечном итоге делает это:

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. Проверить, если VBSciprt уже существует, если не создать.

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. Другой Sub, который создает VBScript с 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