Excel 将解析时间开始的UDF转换为数组公式
我创建了一个UDF来解析从分隔字符串开始的时间。Excel 将解析时间开始的UDF转换为数组公式,excel,vba,array-formulas,Excel,Vba,Array Formulas,我创建了一个UDF来解析从分隔字符串开始的时间。 -返回表示一天中小时数的数组(0到23) -每次开始都用逗号分隔 -@用于表示多次启动 例如5@8p返回5作为基于0的数组中的第20个元素 我想将此函数转换为数组公式,但不知道从何处开始。如能提供从何处开始的参考或建议,将不胜感激 我也对我可以改善我的UDF感兴趣。最终,我将使用性能最好的函数。 我会坚持使用UDF——它将更易于维护 我不想麻烦加入 我会稍微修改一下您的例程,但保留类似的逻辑: 除非你要处理分数或非常大的数字,否则我会使用Lo
-返回表示一天中小时数的数组(0到23) -每次开始都用逗号分隔 -
@
用于表示多次启动
例如5@8p
返回5作为基于0的数组中的第20个元素
我想将此函数转换为数组公式,但不知道从何处开始。如能提供从何处开始的参考或建议,将不胜感激
我也对我可以改善我的UDF感兴趣。最终,我将使用性能最好的函数。- 我会坚持使用UDF——它将更易于维护
- 我不想麻烦加入
- 我会稍微修改一下您的例程,但保留类似的逻辑:
- 除非你要处理分数或非常大的数字,否则我会使用Long而不是Double
什么意思?函数返回一个数组。转换成“数组公式”会有什么不同?@RonRosenfeld我应该澄清我的问题。我想使用标准工作表公式复制我的UDF的功能。所以,你真正的问题是:“如何在原生Excel公式中执行循环?”@AJD。我读过关于使用Sumproduct的帖子,但我不知道如何构建数组。那么使用VBA
Join
而不是工作表函数如何?所有有效点。我使用的是Double
,因为有些作业是4人小组,有时可能会包括一个额外的人员(例如=4*AssignmentList(…)
返回5)。如果可能,我希望使用工作表函数。该工作簿为.xlsx
。格式。问题是它被上传到一个我无法更改的系统中。我可能会使用UDF
并生成.xlsx
。谢谢
AssignmentList("2@12a,3@6a,10@12p,6p,5@8p")(0)
Sub Setup()
Range("A1:AA1").Value = Array("1st", "2nd", "3rd", "12PM", "1AM", "2AM", "3AM", "4AM", "5AM", "6AM", "7AM", "8AM", "9AM", "10AM", "11AM", "12PM", "1PM", "2PM", "3PM", "4PM", "5PM", "6PM", "7PM", "8PM", "9PM", "10PM", "11PM")
Range("A2:C2").Value = Array("12a", "10a,3@12p", "6p,5@8p")
Range("D2:AA2").FormulaArray = "=AssignmentList($A2:$C2)"
End Sub
Function AssignmentList(ByRef Source As Variant) As Variant
Dim Assignments(0 To 23) As Double
Dim Item As Variant, At As Variant
Dim Text As String
Text = WorksheetFunction.TextJoin(",", True, Source)
For Each Item In Split(Text, ",")
If InStr(Item, "@") > 0 Then
At = Split(Item, "@")
Assignments(Hour(At(1))) = Assignments(Hour(At(1))) + At(0)
Else
Assignments(Hour(Item)) = Assignments(Hour(Item)) + 1
End If
Next
AssignmentList = Assignments
End Function
Function AssignmentList(Source) As Long()
Dim Assignments(1 To 1, 1 To 24) As Long
Dim I As Long, V As Variant, W As Variant
Dim vSrc As Variant
Dim t As Date, l As Long
vSrc = Source 'assumed to be a single horizontal row
For I = LBound(vSrc, 2) To UBound(vSrc, 2)
V = Split(vSrc(1, I), ",")
For Each W In V
If InStr(W, "@") > 0 Then
l = Split(W, "@")(0)
t = Split(W, "@")(1)
Else
l = 1
t = W
End If
Assignments(1, Hour(t) + 1) = l
Next W
Next I
AssignmentList = Assignments
End Function