通过用户定义函数更改另一个单元格的值
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
的公式
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