如何在办公室自动更改大小的ActiveX对象?

此线程讨论了我在Excel电子表格中使用ActiveX对象所遇到的问题。 这是一个混乱的阅读,最终没有一个有凝聚力的答案。

问题是100%可重现的:

  1. 使用扩展坞时,在电子表格中打开带有ActiveX对象的工作簿
  2. 从坞站断开机器,触发解决scheme更改(还有其他原因,我的是一个扩展坞,似乎改变决议导致这一点)
  3. 单击一个ActiveX控件 – 他们立即resize和字体更改大小。 字体大小的变化不是.Font.Size参数的函数,而是在问题发生后无法更改的东西,除了不断增加字体大小

唯一看似权威的解决scheme涉及MS补丁(几年前它是一个“修补程序”,尽pipe如此,对于完整部署似乎不实用)和registry编辑,这对我的使用情况是不实际的。

我正在寻找一种方法来:

  1. 防止发生这种变化
  2. find最好的工作

网上对这个问题缺乏权威性的信息。 我打算张贴我的工作,但是,它甚至不理想,我更喜欢更好的解决scheme。

我的工作是以编程方式遍历工作表*上的所有OLE对象,并将代码写入debugging器,然后在工作表中包含一个基本上“调整对象大小”的button,并提供有关此问题发生原因的说明。

此方法将生成代码来驱动该button。

但是它不会自动更新 – 这是一个快照,应该在部署应用程序之前立即使用(如果最终用户将具有buttonfunction)。

然后序列变成:

  1. 运行使用以下方法生成的代码
  2. 立即保存工作簿 – 这不会阻止字体更改继续发生
  3. 重新打开工作簿,问题“解决”

 Private Sub printAllActiveXSizeInformation() Dim myWS As Worksheet Dim OLEobj As OLEObject Dim obName As String Dim shName As String 'you could easily set a for/each loop for all worksheets Set myWS = Sheet1 shName = myWS.name Dim mFile As String mFile = "C:\Users\you\Desktop\ActiveXInfo.txt" Open mFile For Output As #1 With myWS For Each OLEobj In myWS.OLEObjects obName = OLEobj.name Print #1, "'" + obName Print #1, shName + "." + obName + ".Left=" + CStr(OLEobj.Left) Print #1, shName + "." + obName + ".Width=" + CStr(OLEobj.Width) Print #1, shName + "." + obName + ".Height=" + CStr(OLEobj.Height) Print #1, shName + "." + obName + ".Top=" + CStr(OLEobj.Top) Print #1, "ActiveSheet.Shapes(""" + obName + """).ScaleHeight 1.25, msoFalse, msoScaleFromTopLeft" Print #1, "ActiveSheet.Shapes(""" + obName + """).ScaleHeight 0.8, msoFalse, msoScaleFromTopLeft" Next OLEobj End With Close #1 Shell "NotePad " + mFile End Sub 

*注意:不幸的是,这不会find被分组的对象。

唯一的100%可靠的解决方法是closures并重新启动Excel(包括任何不可见的实例)。 任何其他解决scheme有一些问题。

这是我尽可能避免控制的原因之一。 看这里的例子。

本单元由EE的dlmille于2011年3月20日创build

这是一个练习来将工作簿中的active-x控件设置存储在一个工作表的基础上,如果/当Excel变得“古怪”并且形状大小变化时,保留它们的设置当ListBox有一个IntegralHeight属性,其副作用是FALSE设置将保持控制不歪斜,而命令button具有像单元格移动/大小等属性,其他控件不够优美。

例程setControlsOnSheet():1)为活动工作表上的每个OLEObject(active-x)控件获取6个通用控件设置,2)将这些设置存储到string数组sControlSettings()中,3)添加/更新一个定义的名字(这是隐藏的)与这些设置。

工作表中每个控件的定义名称是基于活动工作表名称和控件名称(应该创build一个唯一的实例)

过程:用户创build工作表上将要进行的任何控制,在任何时候,setControlsOnSheet()例程都可以运行,以便最初存储所有控件的设置,刷新这些设置或添加新的设置(因为它这对于工作表中的每个控件都是这样的)。

应注意确保所有设置“看起来不错”(例如,Excel还没有变得“古怪”,或者用户已经调整了一个到多个控件,并准备好“保存”它们的设置,否则,不适当的大小控制的设置将被存储。

而不是使这个例行程序密集,表单激活的ThisWorkbook事件将“重新初始化”刚刚select的工作表上存在的所有控件的所有设置。 这样,工作表上的控制设置就会“恢复”到最近保存的设置,从而“永远”? 避免Excel“古怪”的重新调整后果。

作为一个潜在的增强,这个应用程序可以作为插件的一部分embedded到类模块中,从而将任何相关代码保留在用户“正常”编程环境之外。 例如,表单激活事件陷印将被捕获在类模块中,而不是用户必须将其添加到他/她的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 

类似的问题存在评论和形状。 一种解决方法是编写一个macros来logging.Width.Height属性以及每个对象在一个未使用的工作表上的表单位置属性。 然后编写第二个macros来按需重新build立这些属性。

我有几个button的问题,字体大小是其中之一。 我也调整了button大小和其中的图片大小。 我可以编程方式更改button大小,但无法find一种方法来改变图片的大小。 我想我已经find了解决这些问题的最终方法。

如果我从(在我的情况下)C:\ Users {用户名} \ AppData \ Local \ Temp \ Excel8.0中删除MSForms.exd文件,当你在屏幕分辨率,你想查看button,然后重新启动Excel,这些问题似乎消失。 还有其他.exd文件,您可能需要删除其他应用程序。 他们之中有一些是:

 C:\Users\[user.name]\AppData\Local\Temp\Excel8.0\MSForms.exd C:\Users\[user.name]\AppData\Local\Temp\VBE\MSForms.exd C:\Users\[user.name]\AppData\Local\Temp\Word8.0\MSForms.exd 

这发生在我以前(在使用遥远的连接到我的电脑之后),但我想出了一个解决scheme来调整命令button和他们的字体使用Workbook_WindowActivate事件(这可以通过“重置设置“button以及我想)。

无论如何,我认为所有的事情都是固定的,直到今天,当我再次使用一个遥远的连接,两个命令button开始行为不端。 我发现这两个命令button的Placement属性设置为2(Object与单元格一起移动),而其他人在过去已将其设置为3(Object是自由浮动的)。

但在find这个之前,我试着将button的字体大小设置为我想要的(通过属性窗口),但是Windows忽略了我使用的任何数字,直到我改变了button的高度…全部突然它读取字体大小属性并相应地调整它。

我不确定展示位置属性是否是问题的一部分,但是可以肯定的是,我使用了两种解决scheme:

(1)布置设置为3

(2)与Workbook_WindowActivate事件触发的我的“自动resize”function增加了button和字体大小之前,减less他们回到他们应该。 但也许解决scheme(1)就足够了…我现在没有时间去testing。 以下是我的Workbook_Activate事件的代码:

 Worksheets(1).Shapes("CommandButton1").Top = 0 Worksheets(1).Shapes("CommandButton1").Left = 206.25 Worksheets(1).Shapes("CommandButton1").Width = 75 Worksheets(1).OLEObjects(1).Object.Font.Size = 10 Worksheets(1).Shapes("CommandButton1").Height = 21 Worksheets(1).Shapes("CommandButton1").Height = 18.75 Worksheets(1).OLEObjects(1).Object.Font.Size = 8 

现在一切正常。 过去花了我一些时间在网上find一个解决scheme。 我希望这将有助于至less有一个人在那里;-)

我觉得@RuiHonori有最好的答案,但是为了让我把所有的床单都放到我想要的地方 – 所有的东西都是相同的 – 我用这个:

 Sub SizeControls() Dim myControl As OLEObject Dim WS As Worksheet For Each WS In ThisWorkbook.Worksheets For Each myControl In WS.OLEObjects myControl.Height = 42.75 myControl.Width = 96 Next myControl Next WS End Sub