说我有一个电子表格,该电子表格允许用户输入以下元数据:
Date range start: mm/dd/yyyy
Date range end: mm/dd/yyyy
Mondays: (y/n)
Tuesdays: (y/n)
Wednesdays: (y/n)
Thursdays: (y/n)
Fridays: (y/n)
基于此,我想生成一种格式为mm/dd/yyyy
的日期列表,该日期列表以4/1/2019
开始,以4/30/2019
结尾,并且仅包括指示的日期y
。
因此,如果用户仅在星期一和星期三输入start date = 04/01/2019
,end date = 04/30/2019
,y
,则列表如下所示:
04/01/2019
04/03/2019
04/08/2019
04/10/2019
04/15/2019
04/17/2019
04/22/2019
04/24/2019
04/29/2019
找不到开始的Excel函数。我不知道VBA,但可以想象这样做。
如果我想使用Pyxll
之类的插件用Python编写此代码,是否需要每个拥有Excel文件副本的人都安装Pyxll
?
答案 0 :(得分:1)
@simplycoding:VBA没有开箱即用的功能或代理程序即可完成您要寻找的功能。但是,您可以根据提供的任何VBA来编写自己的文件。
这是我的启动方案:
我在大约20分钟内编写,测试并评论了以下SUB。当我说我不是第一行VBA编码器时,请相信我。
Sub DateList()
'(C) Antonio Rodulfo, 2019
Dim dEnd, dStart, dCounter As Date
Dim iaDays(1 To 5) As Integer
Dim iCounter, iRow As Integer
' Indent your sentences properly
' Reading parameters
dStart = Cells(2, 1).Value
dEnd = Cells(2, 2)
For iCounter = 1 To 5
If Cells(2, 2 + iCounter) = "y" Then
iaDays(iCounter) = 1
Else
iaDays(iCounter) = 0
End If
Next iCounter
' Here's where the list of dates will start
iRow = 4
' I process the dates: Excel stores dates in its own
' coding, which we can use to run a for..next loop
For dCounter = dStart To dEnd
' Weekday(datecode,type) returns the day of week
' type 2 means the week starts with monday being day 1
iCounter = Weekday(dCounter, 2)
' The sub only sets dates for working days
' monday to friday
If iCounter <= 5 Then
' date must be set if found "y" in the matching day
If iaDays(iCounter) = 1 Then
' I like setting the proper numberformat so
' that no surprises are found when reading it
Cells(iRow, 1).NumberFormat = "dd/mmm/yyyy"
Cells(iRow, 1) = dCounter
' Increasing iRow sets the focus on next row
iRow = iRow + 1
End If
End If
' Adding the index name to the next sentence helps
' tracking the structures
Next dCounter
End Sub
我总是建议在编码时使用Option Explicit
。乍一看似乎很烦人,但是它将在测试和调试代码时为您提供很多帮助。
祝你好运!
答案 1 :(得分:0)
您的要求完全不使用VBA令我受到挑战,因此我正在使用一些Excel函数,这是我希望您尝试的方法。
我在以下单元格中使用了您的元数据:
选项1-简单
将以下数组函数输入到单元格D1中(Ctrl + Shift + Enter),并将其一直拖动到右侧(例如,向上拖动到单元格AW1):
=IF(AND(ISNUMBER(MATCH(WEEKDAY($B$1+COLUMN()-4,2),--($B$3:$B$7="y")*(ROW($B$3:$B$7)-2),0)),($B$1+COLUMN()-4)<=$B$2),$B$1+COLUMN()-4,"")
显示在开始日期和结束日期之间以及所需工作日中的所有日期。但是,此选项不能防止出现间隙,因此之间会有很多空白列。
选项2-完成
在单元格D2中输入以下Array函数(Ctrl + Shift + Enter)并将其一直拖动到右侧:
=IFERROR(SUMPRODUCT(SMALL(($B$1+ROW($B$1:$B$30)-1)*(IF(ISNUMBER(MATCH(WEEKDAY($B$1+ROW($B$1:$B$30)-1,2),(--($B$3:$B$7="y")*(ROW($B$3:$B$7)-2)),0)),1,0)),30-COUNT(MATCH(WEEKDAY($B$1+ROW($B$1:$B$30)-1,2),(--($B$3:$B$7="y")*(ROW($B$3:$B$7)-2)),0))+COLUMN()-3)),"")
如您所见,此选项将所有“适当的”日期彼此相邻显示,没有任何空格。
希望您会发现这很有用-第二种选择让我玩得很开心,而且我相信它仍然可以改进。
保重, Justyna