Excel VBA使用范围属性设置命名单元格公式

Excel VBA使用范围属性设置命名单元格公式,vba,excel,range,formula,Vba,Excel,Range,Formula,希望你能帮忙。这时我的头撞到了墙上。对编写VBA相当陌生。我有下面列出的一些VBA代码。从本质上说,我试图做的是锁定/解锁,更改填充颜色,并使用工作表更改事件和ActiveSheet根据下拉菜单中的输入为一系列单元格设置公式。代码保存在工作表本身上。除了配方设定块外,一切正常 Private Sub Worksheet_Change(ByVal Target As Range) With ActiveSheet .Unprotect Password:="somepw" If Range

希望你能帮忙。这时我的头撞到了墙上。对编写VBA相当陌生。我有下面列出的一些VBA代码。从本质上说,我试图做的是锁定/解锁,更改填充颜色,并使用工作表更改事件和ActiveSheet根据下拉菜单中的输入为一系列单元格设置公式。代码保存在工作表本身上。除了配方设定块外,一切正常

Private Sub Worksheet_Change(ByVal Target As Range)
With ActiveSheet
.Unprotect Password:="somepw"
    If Range("d17").Value = "Yes" Then
        .Range("D22:D78").Locked = False
        .Range("D22:D78").Interior.Color = RGB(115, 246, 42)
        .Range("Inc_06PCTotRev").Formula = "=SUM($D$22:$D$25)"
    ElseIf WorksheetFunction.CountA(Range("d22:D78")) <> 0 Then
        If .Range("D22").Locked = True Then
            With Range("D22:D78")
                .Locked = False
                .ClearContents
                .Interior.Color = RGB(217, 217, 217)
            End With
        Else:  .Range("D22:D78").ClearContents
        End If
    Else: .Range("D22:D78").Interior.Color = RGB(217, 217, 217)
          .Range("D22:D78").Locked = True
    End If
.Protect Password:="somepw"
End With
End Sub
Private子工作表\u更改(ByVal目标作为范围)
使用ActiveSheet
.Unprotect密码:=“somepw”
如果范围(“d17”).Value=“是”,则
.Range(“D22:D78”).Locked=False
.Range(“D22:D78”).Interior.Color=RGB(11524642)
.Range(“Inc_06PCTotRev”)。公式=“=总额($D$22:$D$25)”
ElseIf WorksheetFunction.CountA(范围(“d22:D78”))0然后
如果.Range(“D22”).Locked=True,则
带量程(“D22:D78”)
.Locked=False
.ClearContents
.Interior.Color=RGB(217217217217)
以
其他:。范围(“D22:D78”)。ClearContents
如果结束
其他:。范围(“D22:D78”).Interior.Color=RGB(217217217217217)
.Range(“D22:D78”).Locked=True
如果结束
.保护密码:=“somepw”
以
端接头

当包含这些内容时,我收到一个错误,说明“对象的方法范围\u工作表失败”,excel崩溃。如果我把它评论出来,它就会毫无问题地开火。任何帮助都将不胜感激。如果这不够具体或没有意义,请告诉我,我会尽力扩展。

正如我在评论中所说,您处于一个永无止境的循环中,因为您在工作表更改事件中更改了工作表。您需要跟踪更改呼叫。可以通过创建一个变量来跟踪调用更改的时间来缓解这种情况,这也是假设名称范围为1个单元格

Public bRunning As Boolean 'keeps track of when we are making the change

Private Sub Worksheet_Activate()
    bRunning = False 'set to false when the sheet is activated
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
    If bRunning = False Then 'check to see if this is the first change
    bRunning = True 'set the variable letting us know we are making the change.
    With ActiveSheet

    .Unprotect Password:="somepw"
        If Range("d17").Value = "Yes" Then
        .Range("D22:D78").Locked = False
        .Range("D22:D78").Interior.Color = RGB(115, 246, 42)
        .Range("Inc_06PCTotRev").Formula = "=SUM($D$22:$D$25)"
        ElseIf WorksheetFunction.CountA(Range("d22:D78")) <> 0 Then
        If .Range("D22").Locked = True Then
            With Range("D22:D78")
            .Locked = False
            .ClearContents
            .Interior.Color = RGB(217, 217, 217)
            End With
        Else:  .Range("D22:D78").ClearContents
        End If
        Else: .Range("D22:D78").Interior.Color = RGB(217, 217, 217)
          .Range("D22:D78").Locked = True
        End If
    .Protect Password:="somepw"
    End With
    Else
    bRunning = False 'reset the variable as we are done making changes
    End If
End Sub
Public bRunning As Boolean'跟踪我们何时进行更改
专用子工作表_Activate()
当工作表激活时,bRunning=False'设置为False
端接头
私有子工作表_更改(ByVal目标作为范围)
如果bRunning=False,则“检查这是否是第一次更改
bRunning=True'设置变量,让我们知道我们正在进行更改。
使用ActiveSheet
.Unprotect密码:=“somepw”
如果范围(“d17”).Value=“是”,则
.Range(“D22:D78”).Locked=False
.Range(“D22:D78”).Interior.Color=RGB(11524642)
.Range(“Inc_06PCTotRev”)。公式=“=总额($D$22:$D$25)”
ElseIf WorksheetFunction.CountA(范围(“d22:D78”))0然后
如果.Range(“D22”).Locked=True,则
带量程(“D22:D78”)
.Locked=False
.ClearContents
.Interior.Color=RGB(217217217217)
以
其他:。范围(“D22:D78”)。ClearContents
如果结束
其他:。范围(“D22:D78”).Interior.Color=RGB(217217217217217)
.Range(“D22:D78”).Locked=True
如果结束
.保护密码:=“somepw”
以
其他的
bRunning=False“在进行更改时重置变量
如果结束
端接头

如果在调用例程时只需要执行求和,则可以使用
工作表.SUM函数

Application.WorksheetFunction.Sum(Range("$D$22:$D$25"))
.Range("Inc_06PCTotRev").FormulaR1C1 = "=SUM(...)"

如果你真的需要那个单元格中的公式,考虑使用<代码> Frimule1C1函数< /> >:

Application.WorksheetFunction.Sum(Range("$D$22:$D$25"))
.Range("Inc_06PCTotRev").FormulaR1C1 = "=SUM(...)"
在Excel下查找公式R1C1有助于更好地理解R1C1引用语法。如果要在其中插入公式的单元格是
$D$26
,则应将上面的“…”替换为“R[-4]C:R[-1]C”。如果公式应该在单元格$E$20中,您可以将上面的“…”替换为“R[2]C[-1]:R[5]C[-1]”


R[#]引用来自目标范围/单元格的行数,C[#]引用来自目标范围/单元格的列数

命名范围是工作簿还是工作表命名范围?每次添加该公式时,都会再次调用工作表更改事件。我猜你最终会陷入一个永恒的循环。名称范围代表什么,即实际范围是什么?你可以在启动工作表时禁用事件,然后更改代码,最后再次启用。谢谢Alex。这正是我最后所做的,而且效果很好。我走开了一会儿,但是该死的。谢谢。我觉得有点傻。在这一点上完全理解碰撞部分。之前正在更新代码中的单元格属性,但完全忽略了这些属性不会生成永久循环,因为它们不会更改单元格内容。真的很感谢,说得太快了。这实际上并没有对我起作用,因为公式块实际上是为多个单元格设置的,而不仅仅是一个单元格。然而,最终还是让代码正常工作了。在开头添加了Application.EnableEvents=False,在结尾添加了Application.EnableEvents=True,并添加了一个错误处理程序,用于在出错时将值设置为True。现在效果很好。