vb.net - read - workbook vb net
Pasarle valor a excel inputbox from VB.NET (2)
Estoy tratando de automatizar la población de datos en algunas hojas de Excel que tienen algunas macros. Ahora el Excel está protegido y no puedo obtener la clave secreta. Ahora puedo ejecutar las macros, pero cuando intento pasar los argumentos obtengo una discrepancia de argumentos.
Si solo ejecuto la macro con el nombre, obtengo una inputbox
que toma un argumento extra como entrada y auto genera algunos de los valores para las columnas. Debo ingresar este valor manualmente en la inputbox
partir de ahora. ¿Hay alguna forma de que pueda automatizar ese proceso, es decir, capturar la casilla de entrada lanzada por la macro en el script vb.net e ingresar los valores desde allí? es decir, me gustaría ejecutar la macro y luego de obtener la ventana emergente que me pide que ingrese algún valor, use el código de vb.net para ingresar el valor a esa ventana emergente.
Esto es lo que tengo hasta ahora
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
Definición de macro
createNetworks()
//does so basic comparisons on existing populated fields
//if true prompts an inputbox and waits for user input.
Esto también detiene mi script vb.net al pasar a la siguiente línea.
Actualmente, utilizo un método donde ejecuto un hilo antes de que el script invoque la macro. El hilo verifica si se ha llamado a la casilla de entrada. Si es así, recoge el valor de la ubicación y, usando sendkeys, envía el cuadro.
Esta es una solución rudimentaria, pero esperaba una solución más elegante para este problema.
Mi solución Código:
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
Al igual que tú y yo, ambos tenemos nombres, de manera similar, las ventanas tienen handles(hWnd)
, Class
, etc. Una vez que sabes qué es ese hWnd
, es más fácil interactuar con esa ventana.
Esta es la captura de pantalla de InputBox
Lógica :
Encuentre el Handle del InputBox usando
FindWindow
y el título del cuadro de entrada que esCreate Network IDs
Una vez que se encuentre, busque el control del cuadro de edición en esa ventana usando
FindWindowEx
Una vez que se encuentra el controlador del cuadro de edición, simplemente use
SendMessage
para escribir en él.
En el siguiente ejemplo, estaríamos escribiendo. It is possible to Interact with InputBox from VB.Net
a la caja de entrada de Excel.
Código :
Crea un formulario y agregale un botón.
Pega este código
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
Captura de pantalla
Cuando ejecutas el código esto es lo que obtienes
EDIT (Basado en otra solicitud de automatización de OK / Cancel en el chat)
AUTOMATIZACIÓN DE LOS BOTONES OK / CANCELAR DE INPUTBOX
Ok aquí hay un hecho interesante.
Puede llamar a la función InputBox
dos maneras en Excel
Sub Sample1()
Dim Ret
Ret = Application.InputBox("Called Via Application.InputBox", "Sample Title")
End Sub
y
Sub Sample2()
Dim Ret
Ret = InputBox("Called Via InputBox", "Sample Title")
End Sub
En su caso, se utiliza la primera manera y, desafortunadamente, los botones OK
y CANCEL
no tienen un controlador, por lo que desafortunadamente tendrá que usar SendKeys (Ouch!!!)
Para interactuar con él. Si Inbutbox se hubiera generado a través del segundo método, podríamos automatizar los botones OK
y CANCEL
fácilmente :)
Información adicional :
Probado en Visual Studio 2010 Ultimate (64 bit) / Excel 2010 (32 bit)
Inspirado por su pregunta, en realidad escribí un artículo de blog sobre cómo interactuar con el botón OK
en InputBox.