该模块由 EE 的 dlmille 创建于 2011 年 3 月 20 日
这是一个练习,在工作簿中存储 active-x 控件设置,在工作表的基础上,如果/当 Excel 变得“古怪”并且形状大小歪斜时保留它们的设置而 ListBox 有一个 IntegralHeight 属性,其副作用是 FALSE设置将防止该控件歪斜,虽然命令按钮具有诸如移动/调整单元格等属性,但其他控件并不那么优雅。
例程 setControlsOnSheet():1) 为活动工作表上的每个 OLEObject (active-x) 控件获取 6 个常用控件设置,2) 将这些设置存储到字符串数组 sControlSettings() 中,以及 3) 添加/更新具有这些设置的已定义名称(隐藏)。
工作表上每个控件的定义名称是根据活动工作表名称和控件名称建立的(应该创建一个唯一的实例)
过程:用户创建将在工作表上的任何控件,并且在任何时候,都可以运行 setControlsOnSheet() 例程,以最初存储所有控件的设置、刷新这些设置或添加新设置(因为它对工作表上的每个控件执行此操作)。
应注意确保所有设置“看起来正确”(例如,Excel 尚未变得“古怪”,或者用户刚刚调整了他的多个控件并准备“保存”他们的设置。否则,任何尺寸不正确的控件的设置将被存储。
工作表激活的 ThisWorkbook 事件不会使这个例程过程变得密集,而是会“重新初始化”刚刚选择的工作表上存在的所有控件的所有设置。这样,工作表上的控制设置“恢复”到它们最近保存的设置,因此“永远?” 避免 Excel“古怪”调整大小的后果。
作为一个潜在的增强功能,这个应用程序可以作为插件的一部分嵌入到类模块中,从而将任何相关代码排除在用户“正常”编程环境之外。例如,工作表激活事件捕获将在类模块中捕获,而不是用户必须将其添加到他/她的 ThisWorkbook 模块中。
Const CONTROL_OPTIONS = "Height;Left;Locked;Placement;Top;Width" 'some potentially useful settings to store and sustain
Function refreshControlsOnSheet(sh As Object)'routine enumerates all objects on the worksheet (sh), determines which have stored settings, then refreshes those settings from storage (in the defined names arena)
Dim myControl As OLEObject
Dim sBuildControlName As String
Dim sControlSettings As Variant
For Each myControl In ActiveSheet.OLEObjects
sBuildControlName = "_" & myControl.Name & "_Range" 'builds a range name based on the control name
'test for existance of previously-saved settings
On Error Resume Next
sControlSettings = Evaluate(sBuildControlName) 'ActiveWorkbook.Names(sBuildControlName).RefersTo 'load the array of settings
If Err.Number = 0 Then ' the settings for this control are in storage, so refresh settings for the control
myControl.Height = sControlSettings(1)
myControl.Left = sControlSettings(2)
myControl.Locked = sControlSettings(3)
myControl.Placement = sControlSettings(4)
myControl.Top = sControlSettings(5)
myControl.Width = sControlSettings(6)
End If
Err.Clear
On Error GoTo 0
Next myControl
End Function
Private Sub storeControlSettings(sControl As String)
Dim sBuildControlName As String
Dim sControlSettings(1 To 6) As Variant ' set to the number of control settings to be stored
Dim oControl As Variant
Set oControl = ActiveSheet.OLEObjects(sControl)
'store the settings to retain, so they can be reset on demand, thus avoiding Excel's resizing "problem"
'create array of settings to be stored, with order dictated by CONTROL_OPTIONS for consistency/documentation
sControlSettings(1) = oControl.Height
sControlSettings(2) = oControl.Left
sControlSettings(3) = oControl.Locked
sControlSettings(4) = oControl.Placement
sControlSettings(5) = oControl.Top
sControlSettings(6) = oControl.Width
sBuildControlName = "_" & sControl & "_Range" 'builds a range name based on the control name
Application.Names.Add Name:="'" & ActiveSheet.Name & "'!" & sBuildControlName, RefersTo:=sControlSettings, Visible:=False 'Adds the control's settings to the defined names area and hides the range name
End Sub
Public Sub setControlsOnSheet()
Dim myControl As OLEObject
If vbYes = MsgBox("If you click 'Yes' the settings for all controls on your active worksheet will be stored as they CURRENTLY exist. " & vbCrLf & vbCrLf _
& "Are you sure you want to continue (any previous settings will be overwritten)?", vbYesNo, "Store Control Settings") Then
For Each myControl In ActiveSheet.OLEObjects 'theoretically, one could manage settings for all controls of this type...
storeControlSettings (myControl.Name)
Next myControl
MsgBox "Settings have have been stored", vbOKOnly
End If
Application.EnableEvents = True 'to ensure we're set to "fire" on worksheet changes
End Sub