简体   繁体   English

Excel VBA-查找具有变量名的文件(工作日函数)

[英]Excel VBA - Find file with variable name (weekday function)

I have a script that, among other things, loads files with variable file names corresponding to dates. 我有一个脚本,除其他外,该脚本可以加载具有与日期对应的变量文件名的文件。 It can load dates within the last 7 days fine, however, I need it to load dates past that. 它可以加载最近7天内的日期,但是,我需要它加载超过此日期的日期。

The script will be run on Friday mornings, and I need it to pull the entire week, plus entire previous week. 该脚本将在星期五早上运行,我需要它来拉整整整整一周的时间,再加上整整一周的时间。 Currently, it will pull the previous Friday (7 days ago) up through the previous day (Thursday). 目前,它将把前一个星期五(7天前)拉到前一天(星期四)。

What I need is the correct code to get it to pull last Monday through last Thursday. 我需要的是正确的代码,可以将其从上周一拖到上周四。

The code to pull last Monday is below. 上周一要提取的代码如下。 I have tried changing Date - 1 to Date - 2, but that is not right. 我尝试将Date-1更改为Date-2,但这是不对的。 I know that vbMonday is supposed to correspond to a date within the last 7 days (if I understand correctly. Probably a simple thing I am missing, but no option seems to work. 我知道vbMonday应该对应于过去7天内的日期(如果我理解正确的话。可能是我遗漏的一件简单的事情,但似乎没有任何选择可行。

(FYI all variables are declared, just omitted so it is easier to see what is happening) (仅供参考,所有变量都已声明,因此省略了,因此更容易看到正在发生的情况)

LastMondayDate = Format(Date - (Weekday(Date - 1, vbMonday)), "m.d.yy")
fullFileNameLastMonday = strFilePath & LastMondayDate & ".xls"
If Dir(fullFileNameLastMonday) = "" Then
    MsgBox "File for last Monday doesn't exist!"
    GoTo ExitLastMonday
End If
Set wbkLastMonday = Workbooks.Open(fullFileNameLastMonday, False, True)
.......Do stuff.......
wbkLastMonday.Close SaveChanges:=False

ExitLastMonday: ExitLastMonday:

You can try something like this: 您可以尝试如下操作:

Public Sub LoveMondays()

    Dim i As Long

    For i = 1 To 15
        Debug.Print DateAdd("ww", i * -1, Date - (Weekday(Date, vbMonday) - 1))
    Next i

End Sub

It gives the dates of the last 15 Mondays. 它提供了最近15个星期一的日期。 Then, if applicable, a function of the Debug.Print with i as an input variable would be useful. 然后,如果适用,将i作为输入变量的Debug.Print函数将很有用。

Eg: 例如:

Public Function MondaysWeekBack(lngWeekBack As Long) As Date
    MondaysWeekBack = DateAdd("ww", lngWeekBack * -1, Date - (Weekday(Date, vbMonday) - 1))
End Function

Thus for the current week, you can get the Monday like this: MondaysWeekBack(0) and for the previous MondaysWeekBack(1) . 因此,对于当前一周,您可以这样获取星期一: MondaysWeekBack(0)和先前的MondaysWeekBack(1)

Here is the Microsoft reference of DateAdd - https://msdn.microsoft.com/en-us/library/hcxe65wz(v=vs.90).aspx 这是DateAdd的Microsoft参考DateAdd ( v= DateAdd

Edit: As suggested in the comment by @Robin Mackenzie, the function could be extended to make the day a variable as well. 编辑:正如@Robin Mackenzie的注释中所建议的那样,该函数可以扩展为使日也为变量。 Like this: 像这样:

Public Function WeekdayWeekBack(lngWeekBack As Long, _ 
                       Optional lngWeekday As Long = 2) As Date

    WeekdayWeekBack = DateAdd("ww", lngWeekBack * -1, Date - (Weekday(Date, lngWeekday) - 1))
End Function

Then if we want the last Sunday, we should go like this WeekdayWeekBack(0,1) or WeekdayWeekBack(0,vbSunday) . 然后,如果我们要最后一个星期日,则应该像WeekdayWeekBack(0,1)WeekdayWeekBack(0,vbSunday) Monday is by default, thus WeekdayWeekBack(0) would give us the last Monday. 默认情况下,星期一是星期一,因此WeekdayWeekBack(0)会给我们最后一个星期一。

The Weekday function returns a number between 1 and 7 representing the 7 days of the week. Weekday函数返回1到7之间的数字,代表一周中的7天。 Weekday(Date, vbMonday) specifies that Monday will be the day which has the number 1, the first day of the week. Weekday(Date, vbMonday)指定星期一将是数字1的一天,即一周的第一天。 Weekday(Date - 1, vbMonday) will always specify a Monday. Weekday(Date - 1, vbMonday)将始终指定星期一。 To specify another day change the -1 in the formula. 要指定另一天,请更改公式中的-1

Date - Weekday(Date - 1, vbMonday) specifies the same day for 7 days in a row because as the date advances (+ 1 every day) so does the Weekday which is subtracted from it. Date - Weekday(Date - 1, vbMonday)连续7天指定同一天,因为随着日期的增加(每天+ 1),从中减去的Weekday也是如此。 From Tuesday until Monday next week it will specify the current week's Monday. 从星期二到下周星期一,它将指定当前星期的星期一。 Then it will jump to the next Monday. 然后它将跳到下一个星期一。

In order to capture a Monday which is earlier, just modify the date component. 为了捕获更早的星期一,只需修改日期部分。 Date - 7 - Weekday(Date - 1, vbMonday) will do exactly the same as just described but 7 days further in the past. Date - 7 - Weekday(Date - 1, vbMonday)的功能与上述完全相同,但比过去多了7天。

Here try this 在这里试试

Private Sub that()

    Dim LastDate As Date
    Dim NewDate As Date
    Dim path As String
    Dim filename As String


        Select Case Weekday(Now())
            Case Is = 2
                LastDate = Format(DateAdd("d", -14, Date), "mm-dd-yyyy")
            Case Is = 3
                LastDate = Format(DateAdd("d", -14, Date), "mm-dd-yyyy")
            Case Is = 4
                LastDate = Format(DateAdd("d", -15, Date), "mm-dd-yyyy")
            Case Is = 5
                LastDate = Format(DateAdd("d", -16, Date), "mm-dd-yyyy")
            Case Is = 6
                LastDate = Format(DateAdd("d", -18, Date), "mm-dd-yyyy")
        End Select

        NewDate = LastDate + 11
        path = "" & "\"
        filename = Dir(path & "*.xl??")

         Do While Len(filename) > 0
            this = Mid(filename, InStrRev(filename, "\") + 1, InStrRev(filename, "."))
            this = Left(this, InStr(this, ".") - 1)
            If CDate(this) >= LastDate And CDate(this) <= NewDate Then
                ' do your stuff
            End If
         Loop
End Sub

This can be run any day of the week and gets the last two previous weeks. 该程序可以在一周的任何一天运行,并可以获取前两周的时间。 The section where it says "'do your stuff" is where you'd put the body of your action code. 说“做自己的事情”的部分是放置操作代码正文的位置。 I did some string manipulation, forced them to date values with a check that sees if the current file is within the date range you want to check for. 我进行了一些字符串操作,通过检查当前文件是否在您要检查的日期范围内,将它们强制设置为日期值。 This isnt tested but I am 100% on it working. 这未经测试,但我100%可以正常工作。 Also, you'll need to set the path variable, but i am sure its 100%==to strFilePath. 另外,您需要设置path变量,但是我确定它的100%==要设置为strFilePath。

I think it would be easier to change the code from LastMondayDate, LastTuesdayDate, LastWednesdayDate to something much easier: FirstDayToGet. 我认为将代码从LastMondayDate,LastTuesdayDate,LastWednesdayDate更改为更容易一些:FirstDayToGet。 Please note below is only the logic. 请注意以下仅是逻辑。 This logic will open all the date-files you need from the starting date to the current date - or alternatively you could add an ending date if current date is too broad 此逻辑将打开从开始日期到当前日期所需的所有日期文件-或者,如果当前日期太宽,则可以添加结束日期

Sub logicOnlyNotActualCode()
FirstDayToGet = datepicker or textbox value date or cell value date
toooooday = date() ' or some end date

for I = FirstDayToGet to FirstDayToGet + (toooooday - FirstDayToGet)
    run get_date_report(FirstDayToGet)
    FirstDayToGet = dateAdd("d",1,FirstDayToGet)
next i
End Sub

And your function would look something like: 您的函数将类似于:

function get_date_report(FirstDayToGet as date)
dim get_report as string
    get_report = strFilePath & Format(FirstDayToGet , "m.d.yy")  & ".xls"

Do events
End function

This function returns the date values from numDays days ago, up through yesterday's date, inclusive. 此函数返回从numDays昨天的日期(含)的日期值。 It does not account for exceptions like holidays or weekends, etc. What you should do is use this function to build the filenames, and then use the Dir function to test for presence of the file, and (obviously) if the file not exist, do not attempt to open or process it, just move on to the next iteration. 它不考虑假日或周末等异常情况。您应该使用此函数生成文件名,然后使用Dir函数测试文件是否存在,(显然)检查文件是否存在,不要尝试打开或处理它,只需继续下一个迭代。

Function GetFileNames(numDays As Long, optional dFormat as String = "m.d.yy")
'Function returns a string array (len = numDays) of formatted date values
'beginning from numDays days ago, until yesterday's date.
ReDim filenames(1 To numDays) As String
Dim LastDate As Date, i As Long

LastDate = Date 'Returns TODAY's date
'Use DateAdd function to calculate the last numDays:
For i = 1 To numDays
    filenames(i) = Format(DateAdd("d", -(numDays) + i - 1, LastDate), dFormat)
Next

GetFileNames = filenames
End Function

Here is a way you can test it: 您可以通过以下方法进行测试:

Sub TestMe()
Dim a
a = GetFileNames(1) 'Should return an array of len=1, yesterday's date only
MsgBox a(1) 
a = GetFileNames(14) 'Should return an array of len=14, fourteen days prior to and including Yesterday

End Sub

在此处输入图片说明

This is how you get all 14 filenames without creating 14 variable/workbook objects: 这是在不创建14个变量/工作簿对象的情况下获取所有14个文件名的方法:

Dim dateVals 
dateVals = GetFileNames(14)

Now, do something with the array (like open the corresponding workbooks and process them somehow: 现在,对数组进行一些操作(例如打开相应的工作簿并以某种方式处理它们:

Dim val, Dim wb as Workbook
For Each val in DateVals
    If Dir(strFilePath & val & ".xls") <> "" Then
        Set wb = Workbooks.Open(strFilePath & val & ".xls")
        'Do something with the workbook
        wb.Close
    End If
Next

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM