VBA如何不关闭重开窗体即可重置控件属性至初始状态
编辑补充:
@Kostas K. 准确指出我此前将问题考虑得过于复杂,本可使用条件格式实现颜色的修改与重置,但我提出的第二个通用性问题依然成立:为便于讨论,此处假设条件格式不可作为可选方案。
假设你创建了一个会在特定条件下更改颜色的文本框,示例代码如下:
If Me.txtTextbox.Value > [somevalue] Then Me.txtTextbox.BackColor = vbYellow End If
若要将文本框重置为初始颜色,常规实现方式非常简单:
If Me.txtTextbox.Value <= [somevalue] Then Me.txtTextbox.BackColor = vbWhite End If
但如果重新设计窗体时将该文本框的底色设置为蓝色,就必须同步修改对应的VBA代码,否则重置时文本框会恢复为错误的颜色。需要注意的是,通过VBA修改.BackColor属性的效果并非永久:关闭并重新打开窗体后,文本框就会恢复为设计时的初始状态。是否存在可通过VBA直接将控件背景色重置为初始状态的方法?
~~我曾考虑过一种实现方案:将控件的初始背景色存入公共变量,或是存储在窗体页眉的控件中,重置时调用该存储值即可,示例代码如下:
If Me.txtTextbox.Value > [somevalue] Then publicvarTextboxCol = Me.txtTextbox.BackColor Me.txtTextbox.BackColor = vbYellow End If If Me.txtTextbox.Value <= [somevalue] Then Me.txtTextbox.BackColor = publicvarTextboxCol End If
但我认为应当存在更简便的实现方式。~~
核心问询:如何通过VBA在不关闭、重新打开窗体的前提下,将控件的各类属性(例如尺寸大小)重置为初始值?
不需要依赖公共变量,也不需要申请窗体设计权限,在窗体内用字典在加载阶段一次性缓存所有控件的初始属性,是兼容性最好、后续维护成本最低的方案,完全能避免改了设计视图控件样式忘记同步VBA代码的问题。
- 先在窗体代码最顶部声明一个窗体级字典对象,作用域仅限当前窗体,不会被其他过程误改:
Private dicInitProps As Object
- 在窗体的
Load事件里完成字典初始化和初始属性缓存。这个事件触发时所有控件还没被任何运行时代码修改过,完全是设计视图设置的初始状态,存下来的值不会有偏差:
Private Sub Form_Load() Dim ctl As Control Set dicInitProps = CreateObject("Scripting.Dictionary") ' 批量遍历控件自动缓存需要的属性,不用手动给每个控件写代码 For Each ctl In Me.Controls Select Case ctl.ControlType Case acTextBox, acComboBox, acCommandButton ' 下面的属性列表可以按需增删 dicInitProps.Add ctl.Name & "_BackColor", ctl.BackColor dicInitProps.Add ctl.Name & "_ForeColor", ctl.ForeColor dicInitProps.Add ctl.Name & "_Width", ctl.Width dicInitProps.Add ctl.Name & "_Height", ctl.Height dicInitProps.Add ctl.Name & "_Top", ctl.Top dicInitProps.Add ctl.Name & "_Left", ctl.Left End Select Next Set ctl = Nothing End Sub
- 需要重置属性的时候,直接从字典里读之前缓存的初始值赋值就行,比如重置示例里的文本框背景色:
If Me.txtTextbox.Value <= [somevalue] Then Me.txtTextbox.BackColor = dicInitProps("txtTextbox_BackColor") End If
如果要一次性重置整个窗体所有控件的属性,写个简单的循环遍历字典批量赋值即可,不用逐控件写重置逻辑。
注意事项
- 不要等第一次要修改属性的时候才缓存初始值。如果窗体打开后第一次触发逻辑就满足属性修改条件,或者有其他事件提前改了控件属性,这时候存下来的值就不是真正的设计时初始值了,
Load事件是唯一可靠的缓存时机。 - 别尝试通过VBA读取窗体设计模板的属性来获取初始值,这个方法需要开放数据库的设计权限,会触发安全警告,在Access运行时环境下直接失效,没有实用价值。
- 不要用公共变量存属性,窗体级变量随窗体加载创建、窗体关闭自动释放,不会有冗余内存占用,也不会出现多窗体同时打开时变量值串扰的问题。
内容的提问来源于stack exchange,提问作者Notiophilus
相关产品推荐
相关产品推荐

