将值传递给VB.NET中的input框
我试图自动化一些有一些macros的Excel表上的数据人口。 现在excel被保护,我不能得到密钥。 现在我能够运行macros,但是当我尝试传递参数时,我得到的参数不匹配。
如果我只是用这个名字运行macros,我会得到一个inputinputbox
,它将一个额外的参数作为input,并自动生成一些列的值。 截至目前,我必须手动input这个值到input框中。 有没有什么办法可以使这个过程自动化,也就是捕获vb.net脚本中的macros引发的input框,并从那里input值? 即我想要运行macros,当我得到popup要求我input一些值,使用vb.net代码input该popup的值。
这是我到现在为止
Public Class Form1 Dim excelApp As New Excel.Application Dim excelWorkbook As Excel.Workbook Dim excelWorkSheet As Excel.Worksheet Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click excelWorkbook = excelApp.Workbooks.Open("D:/excelSheets/plan_management_data_templates_network.xls") excelApp.Visible = True excelWorkSheet = excelWorkbook.Sheets("Networks") With excelWorkSheet .Range("B7").Value = "AR" End With excelApp.Run("createNetworks") // now here I would like to enter the value into the createNetworks Popup box excelApp.Quit() releaseObject(excelApp) releaseObject(excelWorkbook) End Sub
macros定义
createNetworks() //does so basic comparisons on existing populated fields //if true prompts an inputbox and waits for user input.
这也阻止我的vb.net脚本移动到下一行。
就像你我一样,我们都有名字,同样的,窗口也有handles(hWnd)
, Class
等等。一旦你知道了hWnd
是什么,就更容易和窗口交互了。
这是InputBox的截图
逻辑 :
-
使用
FindWindow
findinput框的句柄,并inputCreate Network IDs
的input框的标题 -
一旦find,使用
FindWindowEx
find该窗口中编辑框的句柄 -
一旦find编辑框的句柄,只需使用
SendMessage
写入即可。
在下面的例子中,我们将写入It is possible to Interact with InputBox from VB.Net
到Excelinput框It is possible to Interact with InputBox from VB.Net
。
代码 :
创build一个窗体并添加一个button。
粘贴这个代码
Imports System.Runtime.InteropServices Imports System.Text Public Class Form1 Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _ (ByVal lpClassName As String, ByVal lpWindowName As String) As Integer Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _ (ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, _ ByVal lpsz2 As String) As Integer Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, _ ByVal lParam As String) As Integer Const WM_SETTEXT = &HC Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Ret As Integer, ChildRet As Integer '~~> String we want to write to Input Box Dim sMsg As String = "It is possible to Interact with InputBox from VB.Net" '~~> Get the handle of the "Input Box" Window Ret = FindWindow(vbNullString, "Create Network IDs") If Ret <> 0 Then 'MessageBox.Show("Input Box Window Found") '~~> Get the handle of the Text Area "Window" ChildRet = FindWindowEx(Ret, 0, "EDTBX", vbNullString) '~~> Check if we found it or not If ChildRet <> 0 Then 'MessageBox.Show("Text Area Window Found") SendMess(sMsg, ChildRet) End If End If End Sub Sub SendMess(ByVal Message As String, ByVal hwnd As Long) Call SendMessage(hwnd, WM_SETTEXT, False, Message) End Sub End Class
截图
当你运行代码时,这就是你得到的
编辑(根据进一步的请求自动化确定/取消在聊天)
自动确定/取消input框的button
好的,这是一个有趣的事实。
您可以在Excel中以两种方式调用InputBox
函数
Sub Sample1() Dim Ret Ret = Application.InputBox("Called Via Application.InputBox", "Sample Title") End Sub
和
Sub Sample2() Dim Ret Ret = InputBox("Called Via InputBox", "Sample Title") End Sub
在你的情况下,第一种方式是使用,不幸的是, OK
和CANCEL
button没有一个句柄,所以不幸的是,你将不得不使用SendKeys (Ouch!!!)
进行交互。 如果您通过第二种方法生成了Inbutbox,那么我们可以轻松地自动执行OK
和CANCEL
button:)
附加信息 :
在Visual Studio 2010 Ultimate(64位)/ Excel 2010(32位)上进行testing
受到您的问题的启发,我实际上写了一篇关于如何与InputBox上的OK
button进行交互的博客文章 。
目前,我使用了一个方法,在脚本调用macros之前运行一个线程。 线程检查input框是否被调用。 如果是,则从该位置获取值并使用sendkeys,提交该框。
这是一个基本的解决scheme,但我希望有一个更优雅的解决scheme来解决这个问题。
我的解决schemeCode:
Public Class Form1 Dim excelApp As New Excel.Application Dim excelWorkbook As Excel.Workbook Dim excelWorkSheet As Excel.Worksheet Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click excelWorkbook = excelApp.Workbooks.Open("D:/excelSheets/some_excel.xls") excelApp.Visible = True excelWorkSheet = excelWorkbook.Sheets("SheetName") With excelWorkSheet .Range("B7").Value = "Value" End With Dim trd = New Thread(Sub() Me.SendInputs("ValueForInputBox")) trd.IsBackground = True trd.Start() excelApp.Run("macroName") trd.Join() releaseObject(trd) excelApp.Quit() releaseObject(excelApp) releaseObject(excelWorkbook) End Sub Private Sub releaseObject(ByVal obj As Object) Try System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) obj = Nothing Catch ex As Exception obj = Nothing Finally GC.Collect() End Try End Sub Private Sub SendInputs(ByVal noOfIds As String) Thread.Sleep(100) SendKeys.SendWait(noOfIds) SendKeys.SendWait("{ENTER}") SendKeys.SendWait("{ENTER}") End Sub