如何在办公室中自动停止ActiveX对象的大小?

时间:2013-10-15 16:00:30

标签: excel vba excel-vba activex

This thread讨论了我在Excel电子表格中使用ActiveX对象时遇到的问题。阅读是一团糟,最终没有一个有凝聚力的答案。

问题是100%可重现:

  1. 使用扩展坞时在电子表格中使用ActiveX对象打开工作簿
  2. 从扩展坞断开机器,触发分辨率更改(还有其他原因,我的是扩展坞,似乎改变分辨率会导致这种情况)
  3. 单击一个ActiveX控件 - 它们会立即调整大小并且字体会更改大小。 fontsize更改不是.Font.Size参数的函数,而是在问题发生后无法更改的内容,而不是不断增加fontsize
  4. 唯一看似权威的解决方案涉及一个MS补丁(几年前它是一个“修补程序”,因此对于完全部署似乎并不实用)和注册表编辑,这对我的用例来说是不切实际的。 / p>

    我正在寻找一种方法:

    1. 防止此更改发生
    2. 找到最佳作品
    3. 在线缺乏关于此问题的权威信息。我打算发布我的工作,然而,它甚至没有接近理想,我宁愿更好的解决方案。

7 个答案:

答案 0 :(得分:2)

我的工作是以编程方式迭代工作表*上的所有OLE对象并将代码写入调试器,然后在工作表上包含一个基本上“调整对象大小”的按钮 - 并说明为什么会出现此问题。

此方法将生成驱动该按钮的代码。

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

然后序列变为:

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

  4. 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
    

    *注意:不幸的是,这也找不到分组的对象。

答案 1 :(得分:1)

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

这是我尽可能避免控制的原因之一。有关示例,请参阅here

答案 2 :(得分:1)

该模块由E-E的dlmille于2011年3月20日创建

这是一个练习,可以在工作簿中以工作表的形式存储active-x控件设置,如果/当Excel获得" quirky"时保留其设置。和形状大小歪斜 虽然ListBox有一个IntegralHeight属性,其FALSE设置的副作用将使该控件不会被歪斜,而命令按钮 具有移动/大小与细胞等属性,其他控件不是很优雅。

例程setControlsOnSheet():   1)为活动工作表上的每个OLEObject(active-x)控件获取6个公共控件设置   2)将这些设置存储到字符串数组,sControlSettings()和   3)使用这些设置添加/更新已定义的名称(隐藏)。

工作表上每个控件的已定义名称是根据活动工作表名称和控件名称(应创建唯一实例)构建的。

过程:   用户创建工作表上的任何控件,并且可以在任何时候运行setControlsOnSheet()例程, 最初存储所有控件的设置,刷新这些设置或添加新设置(对于工作表上的每个控件都这样做。)

应注意确保所有设置"正确" (例如,Excel尚未获得"古怪"或者用户刚刚调整了一个到多个 他的控制,并准备好"保存"他们的设置。否则,任何尺寸不合适的控件都会被控制。设置将被存储。

而不是使这个例程过程密集,工作表激活的ThisWorkbook事件将重新初始化"所有控件的所有设置 存在于刚刚选中的工作表上。这样,工作表上的控制设置就会被恢复"到他们最近保存的设置, 因此"永远?"避免Excel" quirky"调整后果。

作为潜在的增强功能,此应用程序可以嵌入到类模块中作为加载项的一部分,从而保留任何相关代码 用户"正常"编程环境。例如,表格激活事件陷印将被捕获在类模块中,而不是用户具有 将其添加到他/她的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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

过去发生这种情况(使用远程连接到我的电脑之后或之后),但我想出了一个解决方案,使用Workbook_WindowActivate事件来调整命令按钮及其字体的大小(这可能也可以通过“重置设置”按钮来完成。)

无论如何,我认为所有问题都已解决,直到今天我再次使用远程连接并且两个命令按钮开始行为不端。我发现那些2个命令按钮的Placement属性设置为2(Object与单元格一起移动),而我在过去为其他人设置为3(对象是自由浮动的)。

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

我不确定展示位置属性是否实际上是问题的一部分,但为了确定,我使用了2个解决方案:

(1)展示位置设为3

(2)我的“自动调整大小”功能会在Workbook_WindowActivate事件触发时增加按钮和字体大小,然后再将它们缩减回原点。但也许解决方案(1)就足够了......我现在没时间进行测试。这是我的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

现在一切正常。我花了一些时间在网上找到解决方案。我希望这对至少有一个人有帮助; - )

答案 5 :(得分:0)

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

如果我在屏幕分辨率你想要查看按钮时从(在我的情况下)C:\ Users {UserName} \ AppData \ Local \ Temp \ Excel8.0中删除MSForms.exd文件在然后重启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

还有一个用于PowerPoint,但我似乎无法找到相关的支持文档(就我记忆而言,它并没有真正提出这些具体问题)

答案 6 :(得分:0)

我觉得@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