将时间范围分成每行半小时 [英] Split Time Range into Half Hour Each Row

查看:53
本文介绍了将时间范围分成每行半小时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像这样的数据集

I have a data set that look like this

我想将其拆分,以便数据变得像这样

And i want to split it so the data becomes like this

有任何VBA代码构想吗?谢谢!

Any vba code idea? Thank you!

我曾在另一个论坛上从用户那里尝试过此代码,但它仅显示1小时时间间隔.您能帮我把它变成30分钟的时间间隔吗?

I have tried this code from user in another forum but it only show 1 hour time interval. Could you please help me to make it become 30 min time interval?

Sub sample()
Dim bufF As String, bufT As String, NO As String, name As String, 
day As String
Dim i As Long, j As Long, LastR1 As Long, LastR2 As Long
Dim ws1 As Worksheet, ws2 As Worksheet
Dim x() As String, y() As String, cnt As Long
Set ws1 = Sheets("data") '<--change the sheet name
Set ws2 = Sheets("result") '<--change the sheet name

With ws1
    LastR1 = .Cells(Rows.Count, 1).End(xlUp).Row
    For i = 2 To LastR1
        NO = .Cells(i, 1).Value
        name = .Cells(i, 2).Value
        bufF = InStr(Format(.Cells(i, 3).Value, "ddmmyyyy hh:mm"), " ")
        bufF = Mid(Format(.Cells(i, 3).Value, "ddmmyyyy hh:mm"), bufF 
        + 1, 2)
        bufT = InStr(Format(.Cells(i, 4).Value, "ddmmyyyy hh:mm"), " ")
        bufT = Mid(Format(.Cells(i, 4).Value, "ddmmyyyy hh:mm"), bufT 
        + 1, 2)
        day = Format(.Cells(i, 3).Value, "dd-mm-yyyy ")
            If bufT = "00" Then bufT = 24
            With ws2
                LastR2 = .Cells(Rows.Count, 1).End(xlUp).Row
                ReDim x(bufT * 1 - bufF * 1)
                ReDim y(bufT * 1 - bufF * 1)

                For j = bufF * 1 To bufT * 1 - 1
                    x(cnt) = day & j & ":00"
                    y(cnt) = NO & "-" & j
                    cnt = cnt + 1
                Next
                .Range(.Cells(LastR2 + 1, 1), .Cells(LastR2 + cnt, 1)).Value = WorksheetFunction.Transpose(y)
                .Range(.Cells(LastR2 + 1, 3), .Cells(LastR2 + cnt, 3)).Value = WorksheetFunction.Transpose(x)
                .Range(.Cells(LastR2 + 1, 2), .Cells(LastR2 + cnt, 2)).Value = name
            End With
            cnt = 0
    Next
End With
End Sub

推荐答案

重写您现有的代码,该代码已经过测试并且可以工作.可读性要容易得多,使用描述性的变量名,可以更轻松地看到每一行的内容.

Rewriting your existing code, this is tested and works. Readability is much easier and with descriptive variable names it's easier to see what each line is doing.

注意::这只会找到1小时之间的半小时间隔.例如,如果开始时间为09:00,结束时间为11:00,则只会返回09:00和09:30的时间.

Note: This will only find half hour intervals between 1 hour. If for example the start time is 09:00 and the end time is 11:00 it would only return the times for 09:00 and 09:30.

Sub RevisedSample()
Dim myName As String 'Name could be confused with the Excel '.Name' property.
Dim StartTime As Date, EndTime As Date
Dim Activity As String, Detail As String
Dim LastRowSource As Long, LastRowDestination As Long, LoopCountSource As Long, LoopCountDestination As Long
Dim ThirtyMinInterval As Boolean: ThirtyMinInterval = False 'Explicitly assigning False to variable
Dim StringStartTime As String, StringEndTime As String
Dim Time As String
Dim TimeArray As Variant
Dim ArrayCounter As Long

Set SourceSheet = Sheets("Sheet1") '<--change the sheet name
Set DestinationSheet = Sheets("Sheet2") '<--change the sheet name

With SourceSheet
    LastRowSource = .Cells(Rows.Count, 1).End(xlUp).Row
    For LoopCountSource = 2 To LastRowSource
        myName = .Cells(LoopCountSource, 1).Value
        Activity = .Cells(LoopCountSource, 2).Value
        StartTime = .Cells(LoopCountSource, 4).Value
        EndTime = .Cells(LoopCountSource, 5).Value

        If DateDiff("n", StartTime, EndTime) > 30 Then
            ThirtyMinInterval = True

            StringStartTime = CStr(StartTime)
            StringEndTime = CStr(EndTime)

            Time = InStr(Format(StringStartTime, "ddmmyyyy hh:mm"), " ")
            Time = Mid(Format(StringStartTime, "ddmmyyyy hh:mm"), Time + 1, 2)
            Time = Time & ":30"
            StringEndTime = Format(Mid(StringStartTime, 1, 8), "dd/mm/yyyy") & " " & Time

            ReDim TimeArray(1 To 2)
            TimeArray(1) = StartTime
            TimeArray(2) = CDate(StringEndTime)
        End If

        Detail = .Cells(LoopCountSource, 3).Value

        With DestinationSheet
            LastRowDestination = .Cells(Rows.Count, 1).End(xlUp).Row + 1
            If ThirtyMinInterval = True Then
                ArrayCounter = 1
                For LoopCounterDestination = LastRowDestination To LastRowDestination + (UBound(TimeArray) - 1)
                    .Range("A" & LoopCounterDestination).Value = myName
                    .Range("B" & LoopCounterDestination).Value = TimeArray(ArrayCounter)
                    .Range("C" & LoopCounterDestination).Value = Activity
                    .Range("D" & LoopCounterDestination).Value = Detail

                    ArrayCounter = ArrayCounter + 1
                Next LoopCounterDestination
            Else
                    .Range("A" & LastRowDestination).Value = myName
                    .Range("B" & LastRowDestination).Value = StartTime
                    .Range("C" & LastRowDestination).Value = Activity
                    .Range("D" & LastRowDestination).Value = Detail
            End If
        End With
        ThirtyMinInterval = False
    Next LoopCountSource
End With

End Sub

源工作表( Sheet1 )和目标工作表( Sheet2 )的屏幕截图:

Screenshots of Source Sheet (Sheet1) and Destination Sheet(Sheet2):

这篇关于将时间范围分成每行半小时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆