Excel VBA工作集更改-仅针对特定范围限制更改

Excel VBA工作集更改-仅针对特定范围限制更改,excel,vba,Excel,Vba,我有一个触发器,我想在某些工作表中使用-就在2个特定列中。但当我在另一个范围内输入一个值时,它会触发该工作表的私有子项。 我希望它能在E列或H列中的值开始工作。 有人知道如何做对吗 Private Sub Worksheet_Change(ByVal Target As Range) Dim LR As Long Dim rng1 As Range Dim rng2 As Range 'WE WANT TO KEEP THE TARGET COLUMNS BETWEEN 0% TO 100%

我有一个触发器,我想在某些工作表中使用-就在2个特定列中。但当我在另一个范围内输入一个值时,它会触发该工作表的私有子项。 我希望它能在E列或H列中的值开始工作。 有人知道如何做对吗

Private Sub Worksheet_Change(ByVal Target As Range)

Dim LR As Long
Dim rng1 As Range
Dim rng2 As Range

'WE WANT TO KEEP THE TARGET COLUMNS BETWEEN 0% TO 100%
LR = Cells(Rows.Count, "A").End(xlUp).Row

Set rng1 = Intersect(Target, Range(Cells(2, "E"), Cells(LR, "E")))

On Error GoTo 1
If Target.Value < 0 Or Target.Value > 1 Then
    MsgBox "bla bla bla", vbCritical + vbMsgBoxRtlReading + vbMsgBoxRight, "error"
    Target.Value = 0
    Exit Sub
End If

On Error GoTo 1
Set rng2 = Intersect(Target, Range(Cells(2, "H"), Cells(LR, "H")))
If Target.Value < 0 Or Target.Value > 1 Then
    MsgBox "bla bla bla", vbCritical + vbMsgBoxRtlReading + vbMsgBoxRight, "error"
    Target.Value = 0
    Exit Sub
End If


1
End Sub
Private子工作表\u更改(ByVal目标作为范围)
变暗LR为长
变暗rng1 As范围
变暗rng2 As范围
'我们希望将目标列保持在0%到100%之间
LR=单元格(Rows.Count,“A”).End(xlUp).Row
设置rng1=相交(目标、范围(单元格(2,“E”)、单元格(LR,“E”))
错误转到1
如果目标值<0或目标值>1,则
MsgBox“bla bla bla”,vbCritical+vbMsgBoxRtlReading+vbMsgBoxRight,“错误”
Target.Value=0
出口接头
如果结束
错误转到1
设置rng2=相交(目标、范围(单元格(2,“H”)、单元格(LR,“H”))
如果目标值<0或目标值>1,则
MsgBox“bla bla bla”,vbCritical+vbMsgBoxRtlReading+vbMsgBoxRight,“错误”
Target.Value=0
出口接头
如果结束
1.
端接头

您只需检查目标是否与所需范围相交。我会在这张支票中将两列合并在一起

正如DisplayName所说的那样,由于
Target
可以包含多个单元格,所以应该分别检查Target中的每个单元格。或者,如果您希望
Target
始终有一个单元格,那么您可以避免使用
for…for…Each
语句,并使用此检查:
如果Target.Cells.Count>1,则退出Sub
以在更改多个单元格时不运行该过程

我还添加了另一个intersect目标,
Me.Rows(“2:&Rows.count)
,以避免更新您可能有的任何标题。如果数据不包含标题,则可以从
Intersect()
中删除此范围

Private子工作表\u更改(ByVal目标作为范围)
错误转到安全出口
Dim rngIntersect As范围
Set rngIntersect=Intersect(目标、并集(Me.Columns(“E”)、Me.Columns(“H”)_
Me.Rows(“2:&Rows.Count))
如果不是的话rngIntersect什么都不是
Application.EnableEvents=False
暗淡的cel As范围
对于rngIntersect中的每个cel
如果单元值<0或单元值>1,则
MsgBox“bla bla bla bla”,vbCritical+vbMsgBoxRtlReading+vbMsgBoxRight_
“错误”
单元值=0
如果结束
下一个细胞
如果结束
安全出口:
Application.EnableEvents=True
端接头

作为旁注,当您不止一次使用相同的精确范围时,最好继续将该范围设置为变量。因此,我们在这段代码中使用了两次
rngIntersect
,这样就避免了对
Intersect()
Union()
函数发出多个调用。最重要的是,当您只需在代码中的一个位置而不是多次更新范围时,您会遇到较少的调试问题。

intersect可以检查Target中的任何单元格(是的,Target可以是多个单元格)是否与列E和H的并集相交

Private Sub Worksheet_Change(ByVal Target As Range)

    ' this next line could also be,
    'If Not Intersect(Target, Range("E:E, H:H")) Is Nothing Then
    If Not Intersect(Target, Union(Range("E:E"), Range("H:H"))) Is Nothing Then
        On Error GoTo bye_bye
        Application.EnableEvents = False
        Dim t As Range
        For Each t In Intersect(Target, Union(Range("E:E"), Range("H:H")))
            If (t.Value2 < 0 Or t.Value2 > 1) And t.Row > 1 Then
                MsgBox "bla bla bla", vbCritical + vbMsgBoxRtlReading + vbMsgBoxRight, "error"
                t = 0
            End If
        Next t
    End If

bye_bye:
    Application.EnableEvents = True
End Sub
Private子工作表\u更改(ByVal目标作为范围)
"下一行也可能是,,
'如果不相交(目标,范围(“E:E,H:H”))则为零
如果不相交(目标、并集(范围(“E:E”)、范围(“H:H”))则什么都不是
出错时转到“再见”
Application.EnableEvents=False
调光范围
对于相交的每个t(目标、并集(范围(“E:E”)、范围(“H:H”))
如果(t.Value2<0或t.Value2>1)和t.Row>1,则
MsgBox“bla bla bla”,vbCritical+vbMsgBoxRtlReading+vbMsgBoxRight,“错误”
t=0
如果结束
下一个t
如果结束
再见!
Application.EnableEvents=True
端接头

1)为了避免(可能的)无休止的循环,最好添加适当的
应用程序。启用事件处理。2) 
rng1
似乎没有什么用处。我并没有像我应该做的那样彻底检查他的代码。我同意
rng1
看起来是多余的,但如果OP提供了代码的简化版本并实际使用了它,我不愿意删除它。但我确实根据您对事件的建议进行了更新。尽管我接受了您的建议,但您的回答仍然存在一些相关的未处理问题,@user10794223正确地解决了这些问题。您可能希望为Rafael和未来的读者增强您的答案(并避免自己成为一些
的目标,因此_DownVoteNotPerfectAnswer()
事件处理程序,我看到一些大多数沮丧的用户在这里运行),因为您(正确地)以某种相关方式更改了OP的代码,您可能需要添加一些关于添加和删除内容/原因的注释
Private Sub Worksheet_Change(ByVal Target As Range)

    ' this next line could also be,
    'If Not Intersect(Target, Range("E:E, H:H")) Is Nothing Then
    If Not Intersect(Target, Union(Range("E:E"), Range("H:H"))) Is Nothing Then
        On Error GoTo bye_bye
        Application.EnableEvents = False
        Dim t As Range
        For Each t In Intersect(Target, Union(Range("E:E"), Range("H:H")))
            If (t.Value2 < 0 Or t.Value2 > 1) And t.Row > 1 Then
                MsgBox "bla bla bla", vbCritical + vbMsgBoxRtlReading + vbMsgBoxRight, "error"
                t = 0
            End If
        Next t
    End If

bye_bye:
    Application.EnableEvents = True
End Sub