首页 > 解决方案 > Excel VBA从两个日期在表格中创建和添加多行

问题描述

我希望在 Excel 中创建一个 UserForm1,当用户添加开始日期和结束日期时,它将在 table1 中创建新行,使用 VBA 填充如下:

Example: User enters - START DATE: 5/9/2020 & END DATE: 5/16/2020

表返回(添加到表 1 的行和计算):

DATE          COUNT          P1/P2       START DATE      END DATE
5/9/2020        1              1          5/9/2020       5/16/2020
5/10/2020       2              2          5/9/2020       5/16/2020
5/11/2020       3              2          5/9/2020       5/16/2020
5/12/2020       4              2          5/9/2020       5/16/2020
5/13/2020       5              2          5/9/2020       5/16/2020
5/14/2020       6              2          5/9/2020       5/16/2020
5/15/2020       7              2          5/9/2020       5/16/2020

日期列显示: 5/9 和 5/16 之间的每一天的开始日期和一行,但不包括 5/16

计数列:计算从一个输入中添加的行数

P1/P2 列:显示 1 表示从命令中添加的第一行(仅记录),其余的显示 2

开始日期:将输入的日期显示为 [开始日期]

结束日期:显示为 [结束日期] 输入的日期

如果有人输入了一个包含 365 天的日期,则该表最终会添加 365 行。希望找到一种简单的方法,我可以像使用 SQL 一样做到这一点 - 但我无法在 VBA 中找到任何示例。

我已经能够从用户窗体上的按钮输入数据,该按钮在最后添加到表中 - 我真的需要有关如何创建多行和操作数据以在 VBA 中执行我想要的操作的指导。

感谢您提供的任何帮助。

标签: excelvba

解决方案


我无法为您编写整个程序,但这个示例解决方案将为您提供一个工作模型。我将发布一些代码,然后在下面解释它在做什么。

注意:我正在创建一个新工作簿,其中包含默认工作表名称和一个新用户表单,其中包含表单及其控件的所有默认名称。

用户表单代码:

Private Sub CommandButton1_Click()
Dim StartDate As Date
Dim EndDate As Date
Dim DateRangeLength As Long
Dim LoopCounter As Long
Dim RowAfterLast As Long

StartDate = CDate(Me.TextBox1.Value)
EndDate = CDate(Me.TextBox2.Value)

DateRangeLength = (EndDate - StartDate)

With Sheet1
    For LoopCounter = 1 To DateRangeLength
        RowAfterLast = .Cells(Rows.Count, "A").End(xlUp).Row + 1
        If LoopCounter = 1 Then
            .Range("A" & RowAfterLast).Value = StartDate
            .Range("B" & RowAfterLast).Value = LoopCounter
            .Range("C" & RowAfterLast).Value = 1
            .Range("D" & RowAfterLast).Value = StartDate
            .Range("E" & RowAfterLast).Value = EndDate
        Else
            .Range("A" & RowAfterLast).Value = StartDate + (LoopCounter - 1)
            .Range("B" & RowAfterLast).Value = LoopCounter
            .Range("C" & RowAfterLast).Value = 2
            .Range("D" & RowAfterLast).Value = StartDate
            .Range("E" & RowAfterLast).Value = EndDate
        End If
    Next LoopCounter
End With

End Sub

我将两个日期从用户窗体传递给StartDateEndDate分别使用将CDate()其转换为日期值的函数(否则您可能会遇到某些日期的问题)。

我发现日期之间的差异为整数,并将其分配给使用数据类型DateRangeLength声明的日期。Long

然后使用For...Next以 DateRangeLength 作为循环上限的循环,将数据写入工作表。在我的示例中,范围在列"A""E". 该行在每次循环迭代开始时通过查找 A 列中最后使用的行并将分配给 的 1 相加来找到RowAfterLast

截图:

输出范围和用户窗体准备点击“开始!” 带有测试数据: 空输出范围 带有测试数据的用户窗体

代码运行后的输出:
测试数据运行后的输出范围


我应该提到

明智的做法是使用用户输入数据添加某种错误检查,例如确保值是有效日期且格式正确的某些语句或函数。

如果您不太确定该做什么或从哪里开始,Google 就是您的朋友。

为了给你一个很好的例子来说明为什么这很重要,如果我以MM/DD/YYYY格式在你的问题中输入日期值,由于我的日期设置,我最终没有输出 - 我的 reigon 的正确格式是DD /MM/YYYY所以开始日期被理解为,结束日期被理解为,但是因为没有第 16 个月,转换为您的预期,导致等于 -112,因此循环退出甚至没有开始第一次迭代。05/09/2020September 5th, 202005/16/2020May 16th, 2020DateRangeLength


推荐阅读