Select excel 中的按钮基于其位置(范围)

Select a button in excel based on its position (range)

我一直在寻找,似乎没有明确的答案。

在 excel 中,使用 VBA, 有没有办法 select 基于其位置的表单按钮(例如在单元格 'A3' 上方)? 找到按钮所在的单元格是可能的,但相反的似乎是不可能的(当然,除了遍历所有按钮)。

我问的原因是我有一列,其中每个单元格都有 2 个可能的值。如果选择其中一个值,我希望能够删除同一行但不同列中的按钮。

有人可以提出解决方案吗?

我不建议使用以下方法,因为必须满足很多要求才能使其正常工作。这绝对不是一个好习惯。但是,由于您不想重复,这可能就是您要查找的内容。

想法

通过 ActiveSheet.Buttons() collection 中的位置访问所需按钮,并使用当前单元格的 确定一下。

ActiveSheet.Buttons(ActiveCell.Row - [Number of initial rows without a button]).Visible = False

要求

  1. 所有按钮都按升序排列,这意味着第一个按钮被放置在带有按钮的第一行,第二个按钮在下一行,依此类推。
  2. 你有每行一个按钮(你也可以调整代码,如果你有每行相同数量的按钮 )
  3. 所有按钮都位于 连续行 中(如果每个 行之间的行数相同 也可以工作 =]按钮行。当然,你得调整代码)
  4. 您可以 隐藏而不是删除 按钮(显然您不能删除按钮,因为它会影响 ActiveSheet.Buttons 的索引 collection)

截图

下面的截图是在 C3 被激活并且宏是 运行 之后制作的。

问题的前提似乎是迭代 sheets 上的按钮不知何故“不好”。我猜这里的“坏”是指慢。

在给定单元格上定位按钮的“明显”方法是迭代 sheet 上的按钮并测试 TopLeftCell 属性。测试此策略表明此 慢。但不是迭代按钮很慢,访问 TopLeftCell 属性 很慢

那么,我们在迭代时还能测试什么?事实证明,访问 .Top.Left.Height.Width 属性非常快。这些属性可用于相对于单元格定位按钮。

OP 没有具体说明他们使用的是 ActiveX 控件还是表单控件。以下代码是为 表单控件编写的。 如果需要,它可以很容易地适应 ActiveX。

假设:

  1. 按钮是表单控件。
  2. sheet 上只有按钮。如果存在其他形状,那么它可能会找到其中之一。
  3. 它正在寻找左上角在传递范围的左上角单元格内的按钮。
  4. 它只在非隐藏范围内调用。如果它需要为隐藏范围工作,那么它将需要额外的逻辑来避免误报。
  5. 如果找不到按钮 returns Nothing
Function GetButtonOverCell(rng As Range) As Object
    Dim btn As Object 
    Dim TL As Range

    Set TL = rng.Cells(1, 1)
    If TL.EntireRow.Hidden = True Or TL.EntireColumn.Hidden = True Then 
        Exit Function
    End If
    For Each btn In rng.Worksheet.Shapes
        If TL.Top <= btn.Top Then
            If TL.Left <= btn.Left Then
                If TL.Top + TL.Height >= btn.Top Then
                    If TL.Left + TL.Width >= btn.Left Then
                        If btn.TopLeftCell.EntireRow.Hidden = False And btn.TopLeftCell.EntireColumn.Hidden = False Then
                            Set GetButtonOverCell = btn
                            Exit Function
                        End If
                    End If
                End If
            End If
        End If
    Next

End Function

在我的硬件上,在包含 1600 个按钮的 sheet 上进行测试,运行时间约为 0.1 秒。相比之下,使用测试 .TopLeftCell 的方法大约需要 27s