如何在VBA不同模块中获取UserForm ListBox的用户输入值
问题分析与修正方案
核心问题
你的代码存在三个关键错误:
- 变量覆盖:UserForm中
Cmd_OK_Click里声明了局部Lead_time,覆盖了顶部的Public全局变量,导致赋值仅作用于局部变量,外部模块无法获取。 - 循环范围错误:ListBox索引从0开始,
ListCount是总项数,循环上限应为ListCount-1,否则会超出索引范围;未选中项的判断逻辑也有误。 - 控件访问时机错误:Unload窗体后再访问
ListBox1.Value会触发错误,需先赋值再卸载。
修正后的UserForm代码
Public Lead_time As Double Private Sub UserForm_Initialize() ' 简化添加选项的代码,无需逐个AddItem Dim num As Integer For num = 1 To 10 ListBox1.AddItem CStr(num) Next num ' 默认选中4,符合需求 ListBox1.Value = "4" End Sub Private Sub Cmd_OK_Click() Dim i As Integer ' 循环查找选中项,索引范围0到ListCount-1 For i = 0 To Me.ListBox1.ListCount - 1 If Me.ListBox1.Selected(i) = True Then Exit For End If Next i ' 未选中任何项时提示并终止流程 If i = Me.ListBox1.ListCount Then MsgBox "请选择提前期天数" Exit Sub End If ' 给全局变量赋值,再卸载窗体 Me.Lead_time = CDbl(Me.ListBox1.Value) Unload Me End Sub
修正后的模块代码
Sub GetLeadTime() Dim selectedLeadTime As Double ' 设置默认值4 selectedLeadTime = 4 Load Days_lead_time ' 模态显示窗体,确保关闭后再执行后续代码 Days_lead_time.Show vbModal ' 获取UserForm的全局变量值 If Not Days_lead_time Is Nothing Then selectedLeadTime = Days_lead_time.Lead_time Unload Days_lead_time End If MsgBox "选中的提前期:" & CStr(selectedLeadTime) End Sub
关键优化点
- 移除局部变量声明,确保赋值作用于Public全局变量。
- 修正循环索引范围和未选中判断逻辑,避免报错。
- 提前给全局变量赋值再卸载窗体,防止控件访问错误。
- 初始化时默认选中4,用户无需手动选择即可使用默认值。
- 使用
vbModal模态显示窗体,保证代码执行顺序正确。
内容的提问来源于stack exchange,提问作者Doublus
相关产品推荐
相关产品推荐

