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

时间:2016-01-12 19:41:56

标签: excel vba excel-vba merge

我试图找到一种方法来检测合并(或取消合并)单元格的立即使用。更改事件触发也不会更改选择。我尝试了其他一些,但似乎没有事件触发合并 - 我觉得很奇怪。我在change事件中的代码当前根据单元格的内容更改了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

2 个答案:

答案 0 :(得分:0)

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

  
      
  • 更改单元格的格式不会触发Change事件(如预期的那样)。但复制和粘贴格式确实会触发   改变事件。选择Home =&gt; Editing =&gt; Clear =&gt; Clear Formats   命令也会触发事件。
  •   
  • 合并单元格不会触发Change事件,即使在此过程中删除了某些合并单元格的内容。
  •   
  • 添加,编辑或删除单元格注释不会触发Change事件。
  •   
  • 如果单元格为空,则按Delete键会生成一个事件。
  •   
  • 使用Excel命令更改的单元格可能会也可能不会触发Change事件。例如,排序范围或使用目标   搜索者更改单元格不会触发事件。但是使用了   拼写检查器。
  •   
  • 如果您的VBA程序更改了单元格的内容,则 会触发Change事件。
  •   

来自 Excel 2013使用VBA进行电源编程作者:John Walkenbach Source

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

答案 1 :(得分:0)

我找到了自己的一种工作来使事情发生在我想要的事情上。不确定是否有更高效/更快速的方法,但它至少在没有任何错误的情况下工作。它会在选择更改后触发,这比我想要的要慢但是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