将值传递给来自VB.NET的excel输入框

时间:2013-04-10 09:42:12

标签: excel vb.net vba excel-vba excel-automation

我正在尝试在一些具有一些宏的Excel工作表上自动化数据填充。现在excel受到保护,我无法获得密钥。现在我能够运行宏,但是当我尝试传递参数时,我得到的参数不匹配。

如果我只是运行带有名称的宏,我会得到一个inputbox,它需要一个额外的参数作为输入,并自动为列生成一些值。到目前为止,我必须手动将此值输入inputbox。有什么方法可以自动化该过程,即捕获vb.net脚本中的宏抛出的输入框并从那里输入值?即,我想运行宏,并在弹出窗口要求我输入一些值后,使用vb.net代码输入该弹出窗口的值。

这是我现在所拥有的

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

宏定义

createNetworks()
//does so basic comparisons on existing populated fields
//if true prompts an inputbox and waits for user input.

这使我的vb.net脚本停止移动到下一行。

2 个答案:

答案 0 :(得分:12)

和你我一样,我们都有名字,类似的窗口有handles(hWnd)Class等等。一旦你知道hWnd是什么,就更容易与那个窗口进行交互。

这是InputBox的截图

enter image description here

<强>逻辑

  1. 使用FindWindow找到InputBox的句柄,输入框的标题为Create Network IDs

  2. 找到后,使用FindWindowEx

  3. 在该窗口中找到编辑框的句柄
  4. 找到编辑框的句柄后,只需使用SendMessage即可写入。

  5. 在下面的示例中,我们将It is possible to Interact with InputBox from VB.Net写入Excel输入框。

    <强>代码

    创建表单并向其添加按钮。

    enter image description here

    粘贴此代码

    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
    

    <强>截图

    当你运行代码时,这就是你得到的

    enter image description here


    编辑(基于进一步请求自动化聊天中的确定/取消)

    自动输入输入框的正常/取消按钮

    好的,这是一个有趣的事实。

    您可以在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
    

    enter image description here

    在您的情况下,第一种方式被使用,不幸的是,OKCANCEL按钮没有句柄,所以不幸的是,您必须使用SendKeys (Ouch!!!)与之交互。如果您通过第二种方法生成Inbutbox,那么我们可以轻松自动化OKCANCEL按钮:)

    enter image description here

    其他信息

    在Visual Studio 2010 Ultimate(64位)/ Excel 2010(32位)

    上测试

    受您的问题的启发,我实际上写了一篇关于如何与InputBox上的OK按钮互动的博客Article

答案 1 :(得分:4)

目前,我使用的方法是在脚本调用宏之前运行一个线程。线程检查是否已调用输入框。如果是,它从该位置获取值并使用sendkeys,提交该框。

这是一个基本的解决方案,但我希望能更优雅地解决这个问题。

我的解决方案代码:

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