通过用户定义函数更改另一个单元格的值

Change value of another cell via a User Defined Function

Function TotalHours() 旨在接受两个范围。第一个范围通常应该是一行乘七列(一周的七天),第二个范围是一个接受值的单元格。

我在设置一个单元格的值时遇到问题。

我遇到问题的线路:

rCell.Value = sngOT

我明白了

"Application-defined or object-defined error".

我尝试了 rCell.Cells(1,1).Value = sngOT 并得到了同样的错误。

Function TotalHours(myRange As Range, rOT As Range) As Single
Dim sngHours As Single, sngNormal As Single, sngOT As Single
Dim rCell As Range

    sngHours = 0
    sngNormal = 0
    sngOT = 0
    For Each rCell In myRange
        If rCell.Value > 8 Then
            sngOT = sngOT + rCell.Value - 8
            sngNormal = sngNormal + 8
        Else
            sngNormal = sngNormal + rCell.Value
        End If
    Next rCell
    If sngNormal > 40 Then
        sngOT = sngOT + (sngNormal - 40)
        sngNormal = 40
    End If
    sngHours = sngNormal + sngOT
    Set rCell = rOT
    rCell.Value = sngOT
    Set rCell = Nothing
    TotalHours = sngHours

End Function

与 Scott Craner 一样,我假设错误是在您的函数被用作 UDF 时引发的(否则您不会收到错误)。假设这是真的,有一种方法可以从 UDF 中更改其他单元格。

下面就是你想要的。
注意:我进行了其他更改并添加了代码说明以说明原因。

Function TotalHours(rgHours As Range, rgWriteOT As Range) As Single
    
''' Declare hour values as doubles
''' Note: doubles declares as zero
    Dim dbTotalHrs#, dbNormalHrs#, dbOTHrs#, rgCell As Range

''' Get normal hours (max 8 per day) and bandwidth OT (i.e. any hours > 8 on any given day)
    For Each rgCell In rgHours
        dbNormalHrs = dbNormalHrs + WorksheetFunction.Min(rgCell, 8)
        dbOTHrs = dbOTHrs + WorksheetFunction.Max(rgCell - 8, 0)
    Next rgCell
    
''' For any given week worked more than 40 hours: All hours after 40 are OT
    If dbNormalHrs > 40 Then
        dbOTHrs = dbOTHrs + (dbNormalHrs - 40)
        dbNormalHrs = 40
    End If
    
''' Round results to 4 places (to avoid floating point rounding issues)
    dbOTHrs = Round(dbOTHrs, 4)
    dbTotalHrs = Round(dbNormalHrs + dbOTHrs, 4)
    
''' Return Total Hours
    TotalHours = dbTotalHrs

''' Write OT Hours to rgWriteOT (via SetOTValue)
    With rgWriteOT
        .Parent.Evaluate "SetOTValue(" & .Address(False, False) & "," & dbOTHrs & ")"
    End With

End Function

''' Sub to set a value in another cell
Sub SetOTValue(Target As Range, Value#)
    Target = Value
End Sub

所有这些都涵盖了,重要的是要指出,您可以使用公式轻松完成所有这些:
假设您的每日工时在单元格 A2:G2 中,总时数在单元格 H2 中,加班时数在 I2 中,以下是您想要的:
总时数 (H2) 的公式:=SUM(A2:G2)
加班时间 (I2) 的公式:{=IF(H2>40,H2-40,SUM(IF(A2:G2>8,A2:G2-8)))}

注意开盘 { 和收盘 } 在 I2:
o 这是一个数组公式。您没有输入 {}
o 相反,您 'commit' 使用 Ctrl、Shift 和 Enter

的公式