这让我很头疼。我试图做以下事情:
这是我拥有的数据,我有元素的名称,开始日期和结束日期。 我想在白天获得这些数据,而不是在范围内(所以我可以将它上传到我所拥有的数据库中。)
我不知道我是否可以在不使用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 ║
╚═══════╩════════════╝
提前谢谢。
答案 0 :(得分:1)
结合@ SorenHoltenHansen的回答,这应该可以让你到达目的地。此类将接受开始日期和结束日期范围,它将计算您可以在代码中使用的完整日期范围。
创建一个新类,将其命名为“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
您可以全力以赴并实施收集界面,但这应该足以满足您的需求。如果您要拥有非常大的日期范围并且想要明智,那么您可以只存储开始日期和结束日期,并仅在需要时生成中间日期,但我希望能够使用For ...每个都不需要定义[_NewEnum]和Collection的所有子属性。
以下是模块“mdlMain”中的一些测试,因此您可以看到如何使用它:
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
顺便提一下,dates are actually just 64-bit floating point numbers,Doubles。它们代表the range January 1, 100 to December 31, 9999。每天是1,因此整个范围是[-657434,2958465]。一天中的时间表示为小数部分。午夜是* .0,中午是* .5,3:30是〜* .645833333333333。目前(在我的时区),它是2013年12月6日下午1:27。根据VBA在即时窗口?CDbl(now())
,这是41614.5608680556。
这就是为什么我可以在for循环中运行日期范围的原因,每次增加一个来增加一天。
答案 1 :(得分:0)
最快最简单的方法可能是使用VBA。以下代码遍历列A
和C
中的值,将这些值写入列A
和B
中的现有数据下方,并删除列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
更新:由于评论中存在后续问题,因此现在更改了代码,以便变量nCol
定义在日期列之前具有名称的列数。如果宏应该在原始问题中显示的数据上运行,那么nCol = 1
。如果在日期前的三个列中有名称,则为nCol = 3
。