为什么我的代码运行时总是出现 "object 'Range' failed" 错误,但当我将此代码附加到按钮时却没有?

Why do I keep getting a "object 'Range' failed" error my code runs but not when I attach this code to a button?

我正在开发一个以 psi 和 bar 为单位的计算器。在我的 sheet 上,我有一个区域,用户可以在其中输入他们的值,并且在这些输入的旁边,它会在相反的单元中提供辅助输入。最初我在我的 sheet 中使用公式解决辅助输入,但是当我添加我的宏按钮让用户使用辅助输入翻转初始输入值时,我的公式消失了。我尝试创建一个私有 sub 来完成同样的事情,但我一直收到“Ranged Failed”错误。

Private Sub Worksheet_Change(ByVal Target As Range)

    Dim unit As Range
    Dim ip As Range
    Dim ad As Range
    Dim op As Range
    Dim unit2 As Range
    Dim ip2 As Range
    Dim ad2 As Range
    Dim op2 As Range
    Dim barcon As Integer

        barcon = 14.5038
        Set unit = ActiveSheet.Range("B3")
        Set ip = ActiveSheet.Range("B4")
        Set ad = ActiveSheet.Range("B5")
        Set op = ActiveSheet.Range("B6")
        Set unit2 = ActiveSheet.Range("D3")
        Set ip2 = ActiveSheet.Range("D4")
        Set ad2 = ActiveSheet.Range("D5")
        Set op2 = ActiveSheet.Range("D6")

        If unit = "PSI" Then
            unit2 = "Bar"
            ip2 = ip / barcon
            ad2 = ad / barcon
            op2 = op / barcon
        Else
            unit2 = "PSI"
            ip2 = ip * barcon
            ad2 = ip * barcon
            op2 = op * barcon
        End If

End Sub

我曾尝试使用 public sub 但我一直遇到同样的错误。我确实注意到,如果我将它附加到一个按钮上,代码就可以正常工作。这是因为我在两个宏之间使用了相同的变量吗? 这是我用来填充输入的宏。

Sub Convert()
    Dim ip As Range, ad As Range, op As Range
    Dim ip2 As Range, ad2 As Range, op2 As Range
    Dim tran1 As Integer, tran2 As Integer, tran3 As Integer
    Dim unit As Range, unit2 As Range

        Set unit = ActiveSheet.Range("B3")
        Set ip = ActiveSheet.Range("B4")
        Set ad = ActiveSheet.Range("B5")
        Set op = ActiveSheet.Range("B6")
        Set unit2 = ActiveSheet.Range("D3")
        Set ip2 = ActiveSheet.Range("D4")
        Set ad2 = ActiveSheet.Range("D5")
        Set op2 = ActiveSheet.Range("D6")

        tran1 = ip
        tran2 = ad
        tran3 = op

            If unit = "PSI" Then
            Application.EnableEvents = False
                unit = "Bar"
                unit2 = "PSI"
                ip = ip2
                ad = ad2
                op = op2
                ip2 = tran1
                ad2 = tran2
                op2 = tran3
            Else
            Application.EnableEvents = False
                unit = "PSI"
                unit2 = "Bar"
                ip = ip2
                ad = ad2
                op = op2
                ip2 = tran1
                ad2 = tran2
                op2 = tran3
            End If
            Application.EnableEvents = True

        ip.NumberFormat = "0"
        ad.NumberFormat = "0"
        op.NumberFormat = "0"
        ip2.NumberFormat = "0"
        ad2.NumberFormat = "0"
        op2.NumberFormat = "0"

End Sub

首先,变量限定在 Sub 范围内,因此您可以对它们命名。

您的问题是您处于 worksheet_change 事件中,因此当代码修改工作表时,它会重新启动代码,循环直到它崩溃并崩溃。使用 Application.EnableEvents = False

我添加了错误处理,以便在发生崩溃时重新打开事件,您可能希望通过处理特定错误(例如输入非数字)来使其更健壮。

不要使用整数来使用 long 来存储数字,尽管在这种情况下您实际上需要 double 来处理小数。

您可能还应该使用 target.offsetrange.intersect,但我不确定您计划的全部范围,所以我将它们排除在外。

Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    On Error GoTo safeexit
    Dim unit As Range
    Dim ip As Range
    Dim ad As Range
    Dim op As Range
    Dim unit2 As Range
    Dim ip2 As Range
    Dim ad2 As Range
    Dim op2 As Range
    Dim barcon As Double

        barcon = 14.5038
        Set unit = ActiveSheet.Range("B3")
        Set ip = ActiveSheet.Range("B4")
        Set ad = ActiveSheet.Range("B5")
        Set op = ActiveSheet.Range("B6")
        Set unit2 = ActiveSheet.Range("D3")
        Set ip2 = ActiveSheet.Range("D4")
        Set ad2 = ActiveSheet.Range("D5")
        Set op2 = ActiveSheet.Range("D6")

        If unit = "PSI" Then
            unit2 = "Bar"
            ip2 = ip / barcon
            ad2 = ad / barcon
            op2 = op / barcon
        Else
            unit2 = "PSI"
            ip2 = ip * barcon
            ad2 = ip * barcon
            op2 = op * barcon
        End If
safexit:
    Application.EnableEvents = True
End Sub