vba excel 循环遍历数据集,根据日期填充并跳过周末

问题描述 投票:0回答:1

我在尝试将条件集成到循环中时遇到问题。此条件填充一行中的前 5 个单元格(工作日),然后跳过接下来的 2 个单元格(周末)。这取决于天数。 在读取具有不同天数、值和开始日期的不同行数时会发生这种情况(外循环?) 应根据所述开始日期填充数据。 为了解决这个问题,我将当前数据的开始日期与之前的数据进行比较,得到天数的差异。然后抵消列中那些日子的新数据。 我的问题是跳过第 6 和第 7 列/值部分。 提前致谢。 我尝试了从“业力”发布的相关解决方案,它适用于一行。但是在尝试遍历所有数据(读取我的所有数据)时会出现一些错误。在这种情况下的错误,只有一行被填充到 Excel 中的最后一列,忽略天数作为条件,并且不遍历下一行。而且我仍然需要根据开始日期填充信息。

对于缺少跳过部分的第一个代码:

Sub xt4_LoopDate()
Dim ii1, jj1, osi1, osj1 As Integer
Dim in1Days As Integer, in2Value As Integer
Dim xiStart, in3Datum As Date
Dim xiDiff As Long
Dim jbound As Integer
Range("F3:XFD7").ClearContents

osi1 = 2  'Row
osj1 = 5  'Column
jbound = 5  'Upper Bound
xiStart = Range("C3") 'Start Date

For ii1 = 1 To jbound
    in1Days = Range("A" & ii1 + osi1)   'Get Dauer
    in2Value = Range("B" & ii1 + osi1)   'Get Leistung
    in3Datum = Range("C" & ii1 + osi1)   'Get Start
    xiDiff = DateDiff("D", xiStart, in3Datum)  'DifferenceDates

    For jj1 = 1 To in1Days  'Loop the Length
        Cells(ii1 + osi1, jj1 + osj1 + xiDiff) = in2Value
    Next jj1
Next ii1
End Sub

对于循环错误的第二个代码,缺少从特定日期开始的条件:

Sub LSATURDAY_V1()
Dim in1Days As Integer, in2Value As Integer
Dim osii1, osjj1 As Integer
Dim ii1 As Integer, NumberRows As Integer
Dim i As Integer, f As Integer, s As Integer, oFill As Range

Range("F3:XFD6").ClearContents

osii1 = 2  'Offset Row
osjj1 = 5  'Offset Column
f = 5: s = 2

NumberRows = 2
For ii1 = 1 To NumberRows
    in1Days = Range("A" & ii1 + osii1)
    in2Value = Range("B" & ii1 + osii1)
    Debug.Print "D&L -> "; in1Days & "  "; in2Value

Set oFill = Range("F" & ii1 + osii1)
    Do
        For i = 1 To f
            oFill.Value = in2Value
            Set oFill = oFill.Offset(0, 1)
            'works for one Row -> Range("N3:XFD3")
            If Application.CountA(Range("F" & ii1 & ":XFD" & ii1)) = in1Days Then Exit Sub
        Next i
        Set oFill = oFill.Offset(0, s)
    Loop
Next ii1
End Sub
excel loops conditional-statements weekday vba6
1个回答
1
投票

再一次,我不确定我是否理解正确。
无论如何,下图是我认为是您预期的结果。

在运行子程序之前:

运行子程序后:

Sub test()
Dim in1Days As Integer, in2Value As Integer, i As Integer, oFill As Range
Dim dt As Date

With ActiveSheet
.Range("F3:XFD7").ClearContents
Set rg = .Range("A3", .Range("A3").End(xlDown))
End With

i = 6
Do
    txt = txt & "," & i & "," & i + 1
    i = i + 7
Loop Until i >= 50

For Each cell In rg
    in1Days = cell.Value
    in2Value = cell.Offset(0, 1).Value
    dt = cell.Offset(0, 2).Value

    Set c = ActiveSheet.Rows(2).Find(dt)
    If c Is Nothing Then Exit Sub

    Set oFill = Cells(cell.Row, c.Column)
    Set rgCnt = Range(oFill, oFill.End(xlToRight))
    i = c.Offset(-1, 0)

    Do
        If InStr(txt, "," & i) = False Then oFill.Value = in2Value
        Set oFill = oFill.Offset(0, 1): i = i + 1
    Loop Until Application.CountA(rgCnt) = in1Days
Next

End Sub

它将 rg 变量设置为 in1Days 值所在的范围。 (A 栏)

它使用6作为第一个限制编号,然后循环创建所有限制编号作为txt变量。所以在循环完成后,txt 值是第 1 行黄色的数字。

然后循环到 rg 中的每个单元格,创建所需的变量。 (in1Days, in2Value 和 dt)
它试图找到第 2 行中具有 dt 值作为 c 变量的单元格在哪里。如果没有找到就退出sub,如果找到则创建i,其值来自c.offset(-1,0),将oFill设置为要填充的起始单元格,并将rgCnt设置为countA的范围.

然后循环,如果i不是txt的instring,则将in2Value放入oFill。然后它设置 oFill (0,1) 并使 i = i+1。它循环直到 rgCnt = in1Days 的 countA。

请注意,如果找到的日期在黄色列中,它会将 in2Value 放入“允许”列。例如在最后一个数据中,2024 年 4 月 8 日为黄色(K1 单元格),4 月 9 日也是黄色(L1 单元格),因此它开始填充 M7 中的值,即 2024 年 4 月 10 日。

第 2 行的值是格式为

dd.m
的日期,因此它不是字符串“03.4”,而是“3-Apr-2024”。

Step 运行代码,所以你知道会发生什么。


另一个例子
在数据中,第 1 行空白(因此没有数字)。请忽略数字和黄色,因为它只是用来表示黄色是周末,数字是基于第 2 行日期的一周的第 n 天。

预期结果:

如果 dt(循环的 cell.offset(0,3) 值)落在一周的第 6 天或第 7 天,那么它将从下一周的第 1 天开始。在上面的示例图像中,第一个 dt 是 7-Apr-2024,属于一周的第 7 天,因此它开始填充单元格 K3。

Sub test2()
Dim in1Days As Integer, in2Value As Integer, i As Integer, oFill As Range
Dim dt As Date

With ActiveSheet
.Range("F3:XFD7").ClearContents
Set rg = .Range("A3", .Range("A3").End(xlDown))
End With

For Each cell In rg
    in1Days = cell.Value
    in2Value = cell.Offset(0, 1).Value
    dt = cell.Offset(0, 2).Value

    Set c = ActiveSheet.Rows(2).Find(dt)
    If c Is Nothing Then Exit Sub

    Set oFill = Cells(cell.Row, c.Column)
    Set rgCnt = Range(oFill, oFill.End(xlToRight))
    i = Weekday(dt, vbMonday)

    Do
        If i < 6 Then oFill.Value = in2Value
        Set oFill = oFill.Offset(0, 1)
        If i = 7 Then i = 1 Else i = i + 1
    Loop Until Application.CountA(rgCnt) = in1Days
Next

End Sub

通过使用循环 cell.offset(0,2) 值(dt 变量)的工作日函数发生跳过单元格。所以 i 将是从给定日期开始的一周的第 n 天。

在循环中,只要我< 6 it will write to oFill.
然后它偏移 0,1 oFill,如果 i = 7 它将 i 重置为 1 否则它添加 i + 1.

© www.soinside.com 2019 - 2024. All rights reserved.