我正在开发一个 Excel 2010 工作簿,采用手动公式计算模式。
(
file
-> options
-> formulas
-> Workbook calculation
-> manual
)
我在工作表中有一些命令按钮(ActiveX 控件),我将它们设置为使用单元格移动和调整大小(右键单击按钮 -> 格式控件 -> 属性 -> 使用文本移动和调整大小)。
这是因为我在某些条件下过滤掉了一些行,并且我希望放置在这些行中的按钮也根据其托管行的显示模式显示和消失。
一切都很顺利,直到我在某些行(因此按钮)被过滤掉(即不显示)时保存工作表。
当我再次重新打开文件并展开筛选的行时,按钮不显示。在检查它们的属性时,我发现它们的
visible
属性是 True
,但它们的 height
是 0,当我取消过滤它们的托管行时,这不会改变。
我想再次强调,在保存文件之前 - 过滤和取消过滤按钮效果都很好。
非常感谢这里的任何帮助。
好的,我使用 ActiveX 或表单控件得到相同的结果。无论出于何种原因,控件的原始高度似乎在保存并关闭之后不会持续存在。
另一个选项是简单地清除工作簿的
Close
和 Save
事件上的自动筛选。但是,如果您想在保存并重新打开文件时保留某些过滤器,这可能不是您想要的。可能可以将过滤器参数保存在隐藏表中或通过直接操作 VBE/VBA,但这似乎比其价值更麻烦。然后,您可以在重新打开工作簿时重新应用过滤器。
这是我建议的代码注意:
我依赖于工作表的 _Calculate
事件和隐藏的
CountA
公式(设置、更改或清除自动筛选将触发此事件)。我将公式放在 E1 中,以便您可以看到它的样子:由于您的应用程序依赖于
Calculation = xlManual
,那么这种方法并不完全适合您,但在任何情况下,子例程
UpdateButtons
都可以重复使用。您需要根据需要将其与应用程序中的另一个事件或函数联系起来。这是代码
Option Explicit
Private Sub UpdateButtons()
'## Assumes one button/shape in each row
' buttons are named/indexed correctly and
' the first button appears in A2
Dim rng As Range
Dim shp As Shape
Dim i As Long
Application.EnableEvents = False
'## use this to define the range of your filtered table
Set rng = Range("A1:A6")
'## Iterate the cells, I figure maybe do this backwards but not sure
' if that would really make a difference.
For i = rng.Rows.Count To 2 Step -1
Set shp = Nothing
On Error Resume Next
Set shp = Me.Shapes(i - 1)
On Error GoTo 0
If Not shp Is Nothing Then
DisplayButton Me.Shapes(i - 1), Range("A" & i)
End If
Next
Application.EnableEvents = True
End Sub
Private Sub DisplayButton(shp As Shape, r As Range)
'# This subroutine manipulates the shape's size & location
shp.Top = r.Top
shp.TopLeftCell = r.Address
shp.Height = r.Height
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox "_Change"
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
''## Assumes one button/shape in each row
'' buttons are named/indexed correctly and
'' the first button appears in A2
'Dim rng As Range
'Dim shp As Shape
'Dim i As Long
'
''## Uncomment this line if you want an annoying message every time
''MsgBox "Refreshing Command Buttons!"
'
'Application.EnableEvents = False
''## use this to define the range of your filtered table
'Set rng = Range("A1:A6")
'
''## Iterate the cells, I figure maybe do this backwards but not sure
'' if that would really make a difference.
'For i = rng.Rows.Count To 2 Step -1
' Set shp = Nothing
' On Error Resume Next
' Set shp = Me.Shapes(i - 1)
' On Error GoTo 0
'
' If Not shp Is Nothing Then
' DisplayButton Me.Shapes(i - 1), Range("A" & i)
' End If
'Next
'
'Application.EnableEvents = True
End Sub
请参阅本文。您可以通过 RibbonXML 自定义重新调整现有命令的用途。虽然本文面向 C# 和 Visual Studio,但可以使用 CustomUI 编辑器来完成。
我发现的一个解决方案是在列标题上方添加一行,以便按钮仍然出现在列的顶部,但不会触及放置过滤器的行。
添加/删除过滤器不会干扰按钮的位置。
看起来像一个真正的错误,虽然我不知道链接在哪里。
通过将表单按钮更改为 ActiveX 按钮,按钮不再消失,而是在隐藏行时开始移动/聚集到屏幕顶部。我刚刚添加了一些 vba 来重新定位按钮(例如 CommandButton1.Top = Range(A12:A12).Top --> 将 ActiveX 命令按钮移动到第 12 行)。