我有以下用于计算加班时间的Excel表格。
我希望自动生成最后两列,最好使用公式,以便用户可以看到员工在哪些日期工作OT。
Bob的示例输出是:
Dates worked Normal OT : "2nd, 3rd, 4th, 5th, 10th & 12th"
Dates worked Double OT : "6th, 7th & 13th"
请注意,我没有Excel 2016,因此无法使用TEXTJOIN()
。另请注意,第1周和第2周的日期以数字格式存储,而不是日期格式,因此也无法使用WEEKDAY()
。
P.S。我已经尝试了TextJoin
UDF,但它似乎没有用,因为我在公式中有很多标准。
Excel 2016中TEXTJOIN
的工作公式为:
=TEXTJOIN(", ",TRUE,IF(WEEKDAY($B$3:$O$3,2)<6,IF($B5:$O5>0,TEXT($B$3:$O$3,"dd/mm/yyyy"),""),""))
这是使用日期格式。 UDF似乎不适用于这些参数。
答案 0 :(得分:0)
我在问题的最后忽略了PS中的所有内容,因为Jeeped是正确的,因为它与主体和屏幕截图相矛盾。
不使用UDF,公式太复杂了。别担心,我已经提供了我自己的基本TEXTJOIN()
UDF,绝对有效。
以下所有公式都需要&#34;数组输入&#34; (通过按 Ctrl + Shift + 输入)在单个单元格中,然后复制/填充。 (请记住不复制起始{
和}
。
两个公式的唯一区别在于,一个使用比较<5
,而另一个使用>=5
,每一个都使用适当的&#34;否。 of Days&#34;细胞。
第一个公式需要在数组中输入T5
(Bob&#39; Dates Worked Normal OT&#34;)然后填写:
{=SUBSTITUTE(TEXTJOIN(", ", TRUE, IF((MOD(COLUMN($B5:$O5)-COLUMN($B5), 7)<5)*($B5:$O5>0), $B$3:$O$3 & CHOOSE(IF($B$3:$O$3<4, $B$3:$O$3, IF($B$3:$O$3<21, 4, IF($B$3:$O$3<24, $B$3:$O$3-20, IF($B$3:$O$3<31, 4, 1)))), "st", "nd", "rd", "th"), "")), ", ", " & ", MAX(1, S5-1))}
以上公式的扩展,易于阅读的版本(如果你复制粘贴它也会有效):
{=
SUBSTITUTE(
TEXTJOIN(
", ",
TRUE,
IF(
(MOD(COLUMN($B5:$O5)-COLUMN($B5), 7)<5)*($B5:$O5>0),
$B$3:$O$3
&
CHOOSE(
IF($B$3:$O$3<4, $B$3:$O$3, IF($B$3:$O$3<21, 4, IF($B$3:$O$3<24, $B$3:$O$3-20, IF($B$3:$O$3<31, 4, 1)))),
"st", "nd", "rd", "th"
),
""
)
),
", ",
" & ",
MAX(1, R5-1)
)}
第二个公式需要在数组U5
(Bob&#39; Dates Worked Double OT&#34;)中进行数组输入,然后填写:
{=SUBSTITUTE(TEXTJOIN(", ", TRUE, IF((MOD(COLUMN($B5:$O5)-COLUMN($B5), 7)>=5)*($B5:$O5>0), $B$3:$O$3 & CHOOSE(IF($B$3:$O$3<4, $B$3:$O$3, IF($B$3:$O$3<21, 4, IF($B$3:$O$3<24, $B$3:$O$3-20, IF($B$3:$O$3<31, 4, 1)))), "st", "nd", "rd", "th"), "")), ", ", " & ", MAX(1, S5-1))}
上述公式的扩展版本是:
{=
SUBSTITUTE(
TEXTJOIN(
", ",
TRUE,
IF(
(MOD(COLUMN($B5:$O5)-COLUMN($B5), 7)>=5)*($B5:$O5>0),
$B$3:$O$3
&
CHOOSE(
IF($B$3:$O$3<4, $B$3:$O$3, IF($B$3:$O$3<21, 4, IF($B$3:$O$3<24, $B$3:$O$3-20, IF($B$3:$O$3<31, 4, 1)))),
"st", "nd", "rd", "th"
),
""
)
),
", ",
" & ",
MAX(1, S5-1)
)}
注意:
(MOD(COLUMN($B5:$O5)-COLUMN($B5), 7)>=5)*($B5:$O5>0)
只是一种编码AND((…), (…))
; CHOOSE()
函数和四个嵌套IF()
来选择序数指标。{
,在复制粘贴时包含公式末尾的}
。这些仅用于显示需要输入数组的公式。
我的TEXTJOIN
UDF版本:
'============================================================================================
' Module : <any standard module>
' Version : 0.1.0
' Part : 1 of 1
' References : Optional - Microsoft VBScript Regular Expressions 5.5 [VBScript_RegExp_55]
' Source : https://stackoverflow.com/a/49218794/1961728
'============================================================================================
Public Function TEXTJOIN( _
ByRef delimiter As String, _
ByRef ignore_empty As Boolean, _
ByRef text1 As Variant _
) _
As String
Dim ƒ As Excel.WorksheetFunction: Set ƒ = Excel.WorksheetFunction
Const DELIMITER_ As String = "#"
Const PATTERN_ As String = "^(?:#)+|(?:#)+$|(#){2,}"
Static rexDelimiterEscaper As Object ' VBScript_RegExp_55.RegExp ' ## Object
Static rexEmptyIgnorer As Object ' VBScript_RegExp_55.RegExp ' ## Object
If rexEmptyIgnorer Is Nothing _
Then
Set rexEmptyIgnorer = CreateObject("VBScript.RegExp") ' New VBScript_RegExp_55.RegExp ' ## CreateObject("VBScript.RegExp")
With rexEmptyIgnorer
.Global = True
.Pattern = PATTERN_ ' Replacement = "$1"
End With
Set rexDelimiterEscaper = CreateObject("VBScript.RegExp") ' New VBScript_RegExp_55.RegExp ' ## CreateObject("VBScript.RegExp")
With rexDelimiterEscaper
.Global = True
.Pattern = "(.)" ' Replacement = "\$1"
End With
End If
Dim varText1 As Variant
Select Case TypeName(text1)
Case "Range":
varText1 = ƒ.Transpose(text1.Value2)
If text1.Rows.Count = 1 Then
varText1 = ƒ.Transpose(varText1)
If text1.Columns.Count = 1 Then varText1 = Array(varText1)
End If
Case "Variant()":
varText1 = text1
Case Else:
varText1 = Array(text1)
End Select
If ignore_empty _
Then
With rexEmptyIgnorer
.Pattern = Replace(PATTERN_, DELIMITER_, rexDelimiterEscaper.Replace(delimiter, "\$1"))
TEXTJOIN = .Replace(Join(varText1, delimiter), "$1")
End With
Else
TEXTJOIN = Join(varText1, delimiter)
End If
End Function
注意:
#VALUE!
错误。