我使用两个公式来生成指定范围内的随机非重复值。
1st是=IFERROR(RANDBETWEEN($A$1,$A$2),"")
第二名是=IFERROR(LARGE(ROW(INDIRECT(CONCATENATE("$",$A$1,":$",$A$2)))*NOT(COUNTIF($B$1:B1,ROW(INDIRECT(CONCATENATE("$",$A$1,":$",$A$2))))),RANDBETWEEN(1,($A$2+2-$A$1)-ROW(B1))),"")
这两个公式生成一组50个值(取决于我向下拖动第二个公式的位置),彼此是唯一的。
这也适用于日期。但是,我想要包含一个排除周末的选项。我已经创建了一个VBA用户表单,其中用户可以输入开始和结束日期。但是我也希望包含一个复选框,以确定是否从该范围中排除周末。如果可行,我希望扩展这一点,以便用户可以选择排除他/她希望排除的日期。
我在谷歌上搜索时发现了以下公式:
=DATE(2014, 1, 1)+(LARGE(IF(WEEKDAY((DATE(2014, 1, 1)+ROW($1:$365)-1)*((COUNTIF($A$1:A1, DATE(2014, 1, 1)+ROW($1:$365)-1))=0), 2)<6, ROW($1:$365)-1, ""), RANDBETWEEN(1, SUM(--(WEEKDAY((DATE(2014, 1, 1)+ROW($1:$365)-1)*((COUNTIF($A$1:A1, DATE(2014, 1, 1)+ROW($1:$365)-1))=0), 2)<6)))))
然而,经过一些调整和尝试后,我无法让它为我工作。此外,它在2014年1月1日的开始日期加上365天开始(这是相对简单的纠正)。我唯一的问题是试图从50个随机生成的非重复日期中排除周末。将此结合到用户表单是我已经可以做到的事情。
有了这个,请问你的帮助。谢谢!
答案 0 :(得分:2)
您正在寻找WorksheetFunction.WorkDay(Arg1, Arg2, Arg3)
或者您可以在VBA中将其用作WorksheetFunction.WorkDay
WORKDAY
方法返回表示a的数字 日期是指之前或之后的指定工作日数 日期(开始日期)。工作日不包括周末和任何日期 确定为假期。使用boolean
排除周末或假日 当您计算发票到期日,预计交货时间或 工作天数。Arg1必需变体 Start_date - 表示开头的日期 日期。
Arg2必需变体天数 - 非周末数和 start_date之前或之后的非节假日。天数的正值 产生未来的日期;负值会产生过去的日期。
Arg3可选变体假期 - 一个或多个日期的可选列表 从工作日历中排除,例如州和联邦 假期和浮动假期。该列表可以是一系列的 包含日期或序列的数组常量的单元格 表示日期的数字
直接来自MS Doc
$expr
如何使用此方法的一个很好的示例 MS Excel:如何使用WORKDAY函数(WS) https://msdn.microsoft.com/en-us/vba/excel-vba/articles/worksheetfunction-workday-method-excel
另外,我建议您阅读文章使用工作日 https://www.techonthenet.com/excel/formulas/workday.php
答案 1 :(得分:1)
这样可以合理地生成2014年周一至周五的随机日期。
=WORKDAY.INTL(41640, RANDBETWEEN(0, NETWORKDAYS.INTL(41640, 42004, 1)), 1)
请注意,日期并非完全唯一且不重复。
我使用了2014年1月1日的序列日期41,640和2014年12月31日的42,004,但这些可以用任何形式的真实日期替换;例如日期(2014年,1,1)。 WORKDAY.INTL和NETWORKDAYS.INTL都支持可选的假日列表参数。
对于真正独特且不重复的日期,我会使用vba字典。
答案 2 :(得分:0)
另一种方法是管理列表而不是试图操纵随机数。
Function MyRandomNumbers() As Collection ' could be anything
Dim tSourceList As New Collection ' could be a list of anything
Dim iterator As Long
' populate the list - for this example it will only be simple numbers
For iterator = 1 To 500
tSourceList.Add iterator ' New list item is the iterator. Could be anything
Next iterator
Dim tResultList As New Collection ' the same thing as put in the source list
Dim index As Long
For iterator = 1 To 50 ' How ever many numbers you want to pull out of the list
index = CInt(tSourceList.Count * Rnd()) '<randomly generated number between 0 and length of tSourceList>
tResultList.Add tSourceList(index)
tSourceList.Remove (index)
Next iterator
Set MyRandomNumbers = tResultList
End Function
Sub testMRN()
Dim v As Collection
Dim r As Variant
Set v = MyRandomNumbers
Debug.Print v.Count,
For Each r In v
Debug.Print r & " ";
Next r
End Sub
您可以使用更好的播种随机数修改index =
部分。