如何在UFT中为Windows UI的MonthCalendar控件设置日期?
我之前处理过不少WinForms控件的UFT自动化需求,针对你提到的这个WindowsForms10.SysMonthCal32.app.0.13965fa_r30_ad1类型的MonthCalendar控件——没法直接输入日期、单个日期单元格也识别不了的情况,有两种靠谱的实现思路,分享给你:
方案1:通过键盘模拟快速实现随机日期选择
这个方案不需要复杂的API调用,依赖控件本身支持的键盘输入逻辑,适合大多数场景:
- 先确保日历控件获得焦点,这样键盘输入能被正确接收
- 生成符合规则的随机日期(要处理不同月份的天数差异,比如闰年2月)
- 按控件支持的格式输入日期字符串,再按回车确认
UFT代码示例(VBScript)
' 定位到目标日历控件(请替换Window的识别属性为你的应用实际属性) Set objCalendar = Window("YourAppWindow").WinObject("nativeclass:=WindowsForms10.SysMonthCal32.app.0.13965fa_r30_ad1") ' 激活控件并设置焦点,确保键盘输入有效 objCalendar.Activate objCalendar.SetFocus ' 生成2020-2025年之间的随机日期 Randomize intTargetYear = Int((2025 - 2020 + 1) * Rnd + 2020) intTargetMonth = Int((12 - 1 + 1) * Rnd + 1) ' 根据月份计算当月最大天数,处理闰年2月的情况 Select Case intTargetMonth Case 2 If (intTargetYear Mod 4 = 0 And intTargetYear Mod 100 <> 0) Or (intTargetYear Mod 400 = 0) Then intMaxDay = 29 Else intMaxDay = 28 End If Case 4,6,9,11 intMaxDay = 30 Case Else intMaxDay = 31 End Select intTargetDay = Int((intMaxDay - 1 + 1) * Rnd + 1) ' 格式化为控件支持的输入格式(这里用MM/DD/YYYY,需根据你的控件实际接受格式调整) strRandomDate = Right("0" & intTargetMonth, 2) & "/" & Right("0" & intTargetDay, 2) & "/" & intTargetYear ' 发送日期字符串并确认选择 objCalendar.SendKeys strRandomDate objCalendar.SendKeys "{ENTER}"
方案2:通过Windows API精准设置日期
如果键盘模拟不生效(比如控件禁用了键盘输入),可以直接调用Windows API给日历控件发送设置日期的消息,这种方式更稳定精准:
UFT代码示例(VBScript)
' 声明所需的Windows API函数 Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" _ (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" _ (Destination As Any, Source As Any, ByVal Length As Long) ' 日历控件的消息常量 Const MCM_SETCURSEL = &H1008 ' SYSTEMTIME结构体,用于传递日期信息到API Private Type SYSTEMTIME wYear As Integer wMonth As Integer wDayOfWeek As Integer wDay As Integer wHour As Integer wMinute As Integer wSecond As Integer wMilliseconds As Integer End Type ' 辅助函数:将VBScript日期转换为SYSTEMTIME对应的内存指针值 Private Function DateToSystemTimePtr(dtDate As Date) As Long Dim st As SYSTEMTIME st.wYear = Year(dtDate) st.wMonth = Month(dtDate) st.wDayOfWeek = Weekday(dtDate, vbSunday) - 1 ' 0代表周日,对应SYSTEMTIME的规则 st.wDay = Day(dtDate) st.wHour = 0 st.wMinute = 0 st.wSecond = 0 st.wMilliseconds = 0 Dim lngPtr As Long CopyMemory lngPtr, st, Len(st) DateToSystemTimePtr = lngPtr End Function ' 主逻辑:设置随机日期到日历控件 Sub SetRandomCalendarDate() ' 定位日历控件 Set objCalendar = Window("YourAppWindow").WinObject("nativeclass:=WindowsForms10.SysMonthCal32.app.0.13965fa_r30_ad1") lngCalendarHwnd = objCalendar.GetROProperty("hwnd") ' 生成随机日期(同方案1的逻辑) Randomize intTargetYear = Int((2025 - 2020 + 1) * Rnd + 2020) intTargetMonth = Int((12 - 1 + 1) * Rnd + 1) Select Case intTargetMonth Case 2 If (intTargetYear Mod 4 = 0 And intTargetYear Mod 100 <> 0) Or (intTargetYear Mod 400 = 0) Then intMaxDay = 29 Else intMaxDay = 28 End If Case 4,6,9,11 intMaxDay = 30 Case Else intMaxDay = 31 End Select intTargetDay = Int((intMaxDay - 1 + 1) * Rnd + 1) dtRandomDate = DateSerial(intTargetYear, intTargetMonth, intTargetDay) ' 发送API消息设置日期 Dim lngResult As Long lngResult = SendMessage(lngCalendarHwnd, MCM_SETCURSEL, 0, ByVal DateToSystemTimePtr(dtRandomDate)) ' 可选:添加结果验证 If lngResult <> 0 Then Reporter.ReportEvent micPass, "随机日期设置", "成功设置日期为:" & dtRandomDate Else Reporter.ReportEvent micFail, "随机日期设置", "日期设置失败,请检查控件句柄或API参数" End If End Sub
关键注意事项
- 日期格式适配:方案1中要先手动测试控件接受的输入格式(比如
DD/MM/YYYY或YYYY-MM-DD),再调整代码中的格式化逻辑 - 控件属性匹配:确保
nativeclass属性完全匹配你的控件,后缀r30_ad1可能因应用的.NET版本不同而变化 - API权限:方案2需要UFT运行时有足够的权限访问Windows API,部分受保护的应用可能需要以管理员身份运行UFT
内容的提问来源于stack exchange,提问作者koder
相关产品推荐
相关产品推荐

