繁体   English   中英

使用 Excel VBA 事件检测单元格的合并/取消合并?

[英]Using Excel VBA Events to detect merging/unmerging of cells?

我试图找到一种方法来检测合并(或取消合并)单元格的立即使用。 更改事件触发也不选择更改。 我尝试了其他一些,但似乎没有事件触发合并 - 我觉得这很奇怪。 我在更改事件中的代码当前根据单元格的内容更改 Interior.Color。 如果单元格先合并后又取消合并,则颜色会保留在整个选区中。 但我希望它只在带有文本的单元格中保留颜色,其余部分返回到 xlNone 。 无论如何要把它拉下来?

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column < 3 Then Exit Sub
If Target.Row <> 3 Then Exit Sub
Select Case Target.Text
    Case "Blackberry Serrano", "BS"
        Target.Interior.Color = RGB(120, 33, 111)
    [...more of the same...]
    Case ""
        Target.Interior.Color = xlNone
End Select
End Sub

据我所知,无法检测单元格上的格式更改。 合并被视为格式更改,因此无法通过 VBA 事件检测到。 然而,我做了一些挖掘,发现了这个有趣的列表:

  • 更改单元格的格式不会触发 Change 事件(如预期)。 但是复制和粘贴格式确实会触发 Change 事件。 选择 Home=>Editing=>Clear=>Clear Formats 命令也会触发该事件。
  • 合并单元格不会触发 Change 事件,即使在此过程中删除了某些合并单元格的内容。
  • 添加、编辑或删除单元格注释不会触发 Change 事件。
  • 即使单元格一开始是空的,按 Delete 也会生成一个事件。
  • 使用 Excel 命令更改的单元格可能会也可能不会触发 Change 事件。 例如,对范围进行排序或使用 Goal Seeker 更改单元格不会触发该事件。 但是使用拼写检查器确实如此。
  • 如果你的VBA过程更改单元格的内容,但触发Change事件。

来自Excel 2013 Power Programming with VBA by John Walkenbach Source

所以基本上,如果有人只是合并或取消合并单元格,则无法通过 VBA 事件检测到。

我找到了自己的工作方式来使我想要的事情发生。 不确定是否有更有效/更快的方法来做到这一点,但到目前为止它至少可以正常工作而没有任何错误。 它在选择更改后触发,这比我想要的要慢,但 VBA 就是这样。

对于工作表:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Call EnforceFormatting(Target)
End Sub

在一个模块中:

Public oldR As Range
Public newR As Range

Sub EnforceFormatting(ByVal Target As Range)
    Set newR = Target
    If oldR Is Nothing Then
        Set oldR = newR
        Exit Sub
    End If

    If oldR.Column < 3 Then
        Set oldR = newR
        Exit Sub
    End If
    If oldR.Row <> 3 And oldR.Row <> 7 And oldR.Row <> 11 Then
        Set oldR = newR
        Exit Sub
    End If
    If oldR.Rows.Count > 1 Then
        Set oldR = newR
        Exit Sub
    End If
    If oldR.Count > 1 Then
        Application.ScreenUpdating = False
        Dim c As Range
        For Each c In oldR
            c.Value = c.Text
        Next c
        Application.ScreenUpdating = True
    End If

    Set oldR = newR
End Sub

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM