VBA Excel在单元格中分隔date范围

这是给我头痛..我试图做到以下几点:

这是我有的数据,我有元素的名称和开始date和结束date。 我想在白天有这个数据,而不是在范围内(所以我可以上传到我有白天的数据库)。

我不知道如果我不使用VBA,我可以做到这一点,但我猜快速是VBA。

当前数据:

╔═══════╦════════════╦════════════╗ ║ name ║ start date ║ end date ║ ╠═══════╬════════════╬════════════╣ ║ foo1 ║ 25-11-2013 ║ 28-11-2013 ║ ║ foo2 ║ 25-11-2013 ║ 28-11-2013 ║ ║ foo3 ║ 25-11-2013 ║ 28-11-2013 ║ ║ foo4 ║ 25-11-2013 ║ 28-11-2013 ║ ║ foo5 ║ 25-11-2013 ║ 28-11-2013 ║ ║ foo6 ║ 28-11-2013 ║ 28-11-2013 ║ ║ foo7 ║ 28-11-2013 ║ 28-11-2013 ║ ║ foo8 ║ 28-11-2013 ║ 28-11-2013 ║ ║ foo9 ║ 28-11-2013 ║ 28-11-2013 ║ ║ foo10 ║ 28-11-2013 ║ 28-11-2013 ║ ║ foo11 ║ 29-11-2013 ║ 30-11-2013 ║ ║ foo12 ║ 29-11-2013 ║ 30-11-2013 ║ ║ foo13 ║ 29-11-2013 ║ 30-11-2013 ║ ║ foo14 ║ 29-11-2013 ║ 30-11-2013 ║ ║ foo15 ║ 29-11-2013 ║ 30-11-2013 ║ ╚═══════╩════════════╩════════════╝ 

我希望白天将名字分开,以获得这个:

 ╔═══════╦════════════╗ ║ name ║ date ║ ╠═══════╬════════════╣ ║ foo1 ║ 25-11-2013 ║ ║ foo2 ║ 25-11-2013 ║ ║ foo3 ║ 25-11-2013 ║ ║ foo4 ║ 25-11-2013 ║ ║ foo5 ║ 25-11-2013 ║ ║ foo1 ║ 26-11-2013 ║ ║ foo2 ║ 26-11-2013 ║ ║ foo3 ║ 26-11-2013 ║ ║ foo4 ║ 26-11-2013 ║ ║ foo5 ║ 26-11-2013 ║ ║ foo1 ║ 27-11-2013 ║ ║ foo2 ║ 27-11-2013 ║ ║ foo3 ║ 27-11-2013 ║ ║ foo4 ║ 27-11-2013 ║ ║ foo5 ║ 27-11-2013 ║ ║ foo6 ║ 28-11-2013 ║ ║ foo7 ║ 28-11-2013 ║ ║ foo8 ║ 28-11-2013 ║ ║ foo9 ║ 28-11-2013 ║ ║ foo10 ║ 28-11-2013 ║ ║ foo11 ║ 29-11-2013 ║ ║ foo12 ║ 29-11-2013 ║ ║ foo13 ║ 29-11-2013 ║ ║ foo14 ║ 29-11-2013 ║ ║ foo15 ║ 29-11-2013 ║ ║ foo11 ║ 30-11-2013 ║ ║ foo12 ║ 30-11-2013 ║ ║ foo13 ║ 30-11-2013 ║ ║ foo14 ║ 30-11-2013 ║ ║ foo15 ║ 30-11-2013 ║ ╚═══════╩════════════╝ 

先谢谢你。

最快和最简单的方法可能是使用VBA。 以下代码循环遍历列AC的值,将这些值写入列AB现有数据的下方,并删除列C中的数据。

 Sub SeperateDateRange() Dim Ws As Worksheet Dim nCol As Integer 'Define sheet Set Ws = ActiveSheet nCol = 1 '<~~ Defines the number of columns before the date columns Application.ScreenUpdating = False 'Loops throuh cells For i = 1 To ActiveSheet.Cells(Rows.Count, nCol + 2).End(xlUp).Row - 1 Step 1 For j = 0 To Ws.Cells(i + 1, nCol + 2).Value - Ws.Cells(i + 1, nCol + 1).Value Step 1 With Ws.Cells(Ws.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1) For k = 0 To nCol - 1 Step 1 .Offset(0, k).Value = Ws.Cells(i + 1, k + 1).Value Next k .Offset(0, nCol).Value = DateSerial(Year(Ws.Cells(i + 1, nCol + 1).Value), Month(Ws.Cells(i + 1, nCol + 1).Value), Day(Ws.Cells(i + 1, nCol + 1).Value) + j) End With Next j Next i 'Deletes last column with dates Ws.Cells(1, nCol + 2).EntireColumn.Delete Application.ScreenUpdating = True End Sub 

更新:由于注释中的后续问题,现在更改代码,以便variablesnCol定义在date列之前具有名称的列数。 如果macros应该运行原始问题中提供的数据,则nCol = 1 。 如果在date可行数之前有三列名称,则nCol = 3

与@ SorenHoltenHansen的答案相结合,这应该让你到你想去的地方。 该课程将接受开始date和结束date范围,并计算您可以在代码中使用的所有date范围。

创build一个新类,将其称为“clsDateRange”,并添加以下代码:

 Option Compare Database Option Explicit Private m_colDates As Collection Public Sub InitStartEnd(ByVal dtStart As Date, ByVal dtEnd As Date) Set m_colDates = New Collection Dim tempDate As Date For tempDate = dtStart To dtEnd Step 1 m_colDates.Add DateValue(tempDate) Next End Sub Public Property Get Dates() As Collection Set Dates = m_colDates End Property 

你可以去整个猪,并实施收集界面,但这应该足以满足您的需求。 如果你打算拥有非常大的date范围,而且你想要明智的话,你可以只存储开始date和结束date,并且只在需要的时候生成中间date,但是我希望能够使用For …每个都不需要定义[_NewEnum]和Collection的所有子属性。

以下是模块“mdlMain”中的一些testing,以便您了解如何使用它:

 Public Sub Main() Dim oDateRange As New clsDateRange Dim varDate As Variant oDateRange.InitStartEnd "25-11-2013", "27-11-2013" For Each varDate In oDateRange.Dates() MsgBox varDate Next oDateRange.InitStartEnd "28-11-2013", "28-11-2013" For Each varDate In oDateRange.Dates() MsgBox varDate Next oDateRange.InitStartEnd "29-11-2013", "30-11-2013" For Each varDate In oDateRange.Dates() MsgBox varDate Next End Sub 

顺便提一句, date实际上只是64位浮点数 , 双倍 。 它们代表了9999年1月1日至9月12日的范围 。 每天是1,所以整个范围是[-657434,2958465]。 一天中的时间以小数部分表示。 午夜是* .0,中午是* .5,3:30是〜* .645833333333333。 目前(在我的时区),2013年12月6日下午1点27分。 根据立即窗口中的VBA ?CDbl(now()) ,即41614.5608680556。

所以这就是为什么我可以在for循环中运行date范围的原因,每次增加一个来增加一天。