每 30 秒提取一次数据的 VBA 脚本

时间:2021-03-11 15:24:55

标签: excel vba

我有一个电压输出列表和记录它们的时间戳。对于某些背景,我的测试从 0 - 5V 每 30 秒将电压增加 1mV。系统每隔一秒左右读取一次,可能会不一致。工作表有 70000 多行,但我只需要 5000 多行。

到目前为止,我已经使用 =RIGHT(TEXT(A1, "hh:mm:ss"),2) 从时间中提取秒数。不幸的是,时间戳总是每 30 秒完美一次,所以我不能简单地过滤每 0 和 30 秒。有时会跳过 30 秒,读取到 35 秒。

如何创建每 30 秒提取一次增量的 VBA 脚本,如果没有完美的 30 秒跳跃,请选择最接近的匹配(即 29 或 31)?

任何指导将不胜感激!

1 个答案:

答案 0 :(得分:0)

好的,我认为以下方法可行。请注意,这需要在 Flags 输出列中作为 Excel 公式数组输入,函数的输入参数是包含时间的相应列。 (因此输出列的公式应如下所示:{=FlagEvery30Sec(D2:D36)}

' Returns 1 if the corresponding row should be used, and 0 otherwise
Public Function FlagEvery30Sec(SourceTimes As Range) As Integer()
    Dim Times() As Variant
    Dim Flags() As Long
    
    ' get the source values
    Times = SourceTimes
    
    ' set the output values array to the same size
    Dim First As Long, Last As Long
    First = LBound(Times, 1)
    Last = UBound(Times, 1)
    ReDim Flags(First To Last, 1 To 1)
    
    Dim curr As Long, prev As Long
    prev = First
    curr = First
    Flags(curr, 1) = 1
    curr = curr + 1
    
    Dim currTime As Date
    Dim currSecs As Double, prevSecs As Double, lastFlagSecs As Double
    lastFlagSecs = CDbl(Times(curr, 1)) * 24 * 60 * 60
    
    While curr <= Last
        Flags(curr, 1) = 0    ' assume not flagged, change later
        currSecs = CDbl(Times(curr, 1)) * 24 * 60 * 60
        If (currSecs - lastFlagSecs) >= 30 Then
            If ((currSecs - lastFlagSecs) - 30) <= (30 - (prevSecs - lastFlagSecs)) Then
                Flags(curr, 1) = 1
                lastFlagSecs = currSecs
            Else
                Flags(prev, 1) = 1
                lastFlagSecs = prevSecs
            End If
        End If
        
        prevSecs = currSecs
        prev = curr
        curr = curr + 1
    Wend
    
    FlagEvery30Sec = Flags
End Function

请注意,基本上有两种方法:

  1. 取第一个时间戳,每 30 秒标记一次,然后找到最接近每个标记的条目并标记它。或者,

  2. 取第一个时间戳并找到最接近其后 30 秒的以下条目。然后将该条目的时间作为基本时间戳,并找到最接近 30 秒之后的下一个条目。重复此操作,直到到达终点。

我上面的函数使用了第二种方法。您应该注意,这可能会有所偏差,最终结果可能会比 TotalSeconds/30 多或少。

相关问题