You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用VBA自动选择C#应用程序表单中的指定值实现流程自动化?

实现VBA自动操作C# WinForm控件的方案

前置准备

先安装窗口检测工具(比如系统自带的Spy++),提前获取以下信息:

  • C#应用主窗口的标题文本
  • Institution Name 对应控件(大概率是下拉框ComboBox/列表框ListBox)的类名
  • Put Files、Get Files按钮的控件类名或按钮文本

第一步:声明所需Windows API

注意根据你的Office版本选择对应声明,64位Office需要加PtrSafe关键字:

' 32位Office用以下声明
Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As Long, ByVal hWndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long
Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

' 64位Office用以下声明
'Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
'Declare PtrSafe Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWndParent As LongPtr, ByVal hWndChildAfter As LongPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As LongPtr
'Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
'Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

' 常量定义(下拉框场景用)
Const CB_FINDSTRINGEXACT = &H158
Const CB_SETCURSEL = &H14E
Const BM_CLICK = &HF5
' 如果是列表框控件,就用下面两个常量替换上面CB开头的两个
' Const LB_FINDSTRINGEXACT = &H1A2
' Const LB_SETCURSEL = &H186

第二步:完整操作代码

在你原有启动应用的代码基础上新增操作逻辑:

Sub 自动操作WinForm()
    Dim fileName As Variant
    Dim filePath As String
    Dim fso As Object
    Dim appHwnd As LongPtr ' 32位Office请改为Long类型
    Dim comboHwnd As LongPtr ' 32位Office请改为Long类型
    Dim btnPutHwnd As LongPtr ' 32位Office请改为Long类型
    Dim btnGetHwnd As LongPtr ' 32位Office请改为Long类型
    Dim targetInstitution As String
    Dim itemIndex As Long
    
    ' 填入你要固定选中的机构名
    targetInstitution = "你要固定选中的Institution Name值"
    ' 填入你C#应用主窗口的标题,通过Spy++抓取
    Const APP_WINDOW_TITLE = "你的C#应用窗口标题"
    ' 填入你抓取到的下拉框类名
    Const COMBO_CLASS_NAME = "WindowsForms10.COMBOBOX.app.0.xxxxxxx" ' 替换为实际抓取到的类名
    
    ' 原有启动应用逻辑
    Set fso = CreateObject("shell.application")
    filePath = "C:\Dropbox (###)\###\###\###\"
    fileName = Dir(filePath & "### UI*") ' 原代码的MyPath为笔误,已修正为filePath
    If fileName <> "" Then
        fso.Open (filePath & fileName)
    End If
    
    ' 等待3秒确保窗口完全加载,可根据实际运行情况调整时长
    Sleep 3000
    
    ' 获取主窗口句柄
    appHwnd = FindWindow(vbNullString, APP_WINDOW_TITLE)
    If appHwnd = 0 Then
        MsgBox "未找到应用窗口"
        Exit Sub
    End If
    
    ' 获取下拉框控件句柄
    comboHwnd = FindWindowEx(appHwnd, 0, COMBO_CLASS_NAME, vbNullString)
    ' 如果界面有多个同类型控件,可多次调用FindWindowEx,第二个参数传入上一个找到的句柄遍历定位
    If comboHwnd = 0 Then
        MsgBox "未找到Institution Name下拉框"
        Exit Sub
    End If
    
    ' 查找目标项的索引
    itemIndex = SendMessage(comboHwnd, CB_FINDSTRINGEXACT, -1, ByVal targetInstitution)
    If itemIndex = -1 Then
        MsgBox "未找到指定机构名"
        Exit Sub
    End If
    
    ' 选中目标项
    Call SendMessage(comboHwnd, CB_SETCURSEL, itemIndex, 0)
    
    ' 点击Put Files按钮,按钮文本和你界面显示一致即可
    btnPutHwnd = FindWindowEx(appHwnd, 0, vbNullString, "Put Files")
    If btnPutHwnd <> 0 Then
        Call SendMessage(btnPutHwnd, BM_CLICK, 0, 0)
    End If
    
    ' 等待Put操作完成,可根据实际运行情况调整时长
    Sleep 5000
    
    ' 点击Get Files按钮
    btnGetHwnd = FindWindowEx(appHwnd, 0, vbNullString, "Get Files")
    If btnGetHwnd <> 0 Then
        Call SendMessage(btnGetHwnd, BM_CLICK, 0, 0)
    End If
End Sub

注意事项

  • 如果你的C#应用是用WPF开发的,上述基于Win32 API的方案不适用,需要换用UI Automation类库实现
  • 若应用更新后控件类名发生变化,需要重新抓取类名更新代码
  • 操作前确保没有其他同标题的窗口打开,避免FindWindow匹配到错误窗口

内容的提问来源于stack exchange,提问作者bgado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 10:54:02