您好我的Access
database
中有一个列,我从日志文件导入。我在日志文件中的日期和时间格式如下:
2016:6:28:10:15:0:390000000
基本上是:
yyyy:mm:dd:hh:mm:ss:ms
当我在访问中导入日志文件时,它将其作为文本读取为一列。但是,我希望将其分为两列,并将其读作:
column1:yyyy:mm:dd
第2栏:hh:mm:ss
格式为Datetime
而不是文字。我需要使用Excel
VBA
执行此操作。我无法找到解决方案。请帮忙!
答案 0 :(得分:1)
由于字符串的长度可变,这有点棘手。
但是这样做:切断毫秒,替换datepart的分隔符以及datepart和timepart之间的间隔。然后转换为日期或时间:
DateColoumn = DateValue(Replace(Replace(Left([DateTimeText], Len([DateTimeText]) - 10), ":", "-", , 2), ":", " ", , 1))
TimeColoumn = TimeValue(Replace(Replace(Left([DateTimeText], Len([DateTimeText]) - 10), ":", "-", , 2), ":", " ", , 1))
如果这是针对数据库表, Rene的建议是正确的:仅使用一个字段:
LogTime = CDate(Replace(Replace(Left([DateTimeText], Len([DateTimeText]) - 10), ":", "-", , 2), ":", " ", , 1))
编辑:
组合值也可以通过用户显示的 Split 获得,但我会稍微简化一下:
LogTime = ConvertLog([DateTimeText])
使用这样的函数:
Public Function ConvertLog(ByVal Entry As String) As Date
Dim Parts As Variant
Dim LogTime As Date
Parts = Split(Entry, ":")
LogTime = DateSerial(Parts(0), Parts(1), Parts(2)) + TimeSerial(Parts(3), Parts(4), Parts(5))
ConvertLog = LogTime
End Function
答案 1 :(得分:0)
这种表示法对于非常大的日志来说是典型的,并且通过非常慢的字符串函数解析它,就像Gustav解决方案一样,并不好。更多 - 它没有考虑部分秒数部分。
Sub sb_SplitDate()
Dim dDate As Date, dDatDat As Date, dDatTim As Date
Dim i&, lArr&(), lLB&, lUB&
Dim sDatInc$, sArr$(), sClm1$, sClm2$
sDatInc = "1999:12:31:23:59:59:50000000000000000"
sDatInc = "1999:12:31:23:59:59:49999999999999999"
sDatInc = "2016:6:28:10:15:0:49999"
sDatInc = "2016:6:28:10:15:0:50"
sDatInc = "2016:6:28:10:15:0:5"
sDatInc = "2016:6:28:10:15:0:499999999999"
sDatInc = "2016:6:28:10:15:0:999999999999999999999999999"
sDatInc = "2016:6:28:10:15:0:390000000" ' Original
sArr = Split(sDatInc, ":")
lLB = LBound(sArr): lUB = UBound(sArr)
ReDim lArr(lLB To lUB)
For i = lLB To (lUB - 1)
lArr(i) = CLng(sArr(i))
Next
'lArr(6) = CLng(Left$(sArr(6), 1))
lArr(6) = CLng(AscW(sArr(6)) - 48) ' significantly faster
' or AscB
dDatDat = DateSerial(lArr(0), lArr(1), lArr(2))
dDatTim = TimeSerial(lArr(3), lArr(4), lArr(5))
dDate = dDatDat + dDatTim - _
CLng(lArr(6) > 4) / 86400
' standard (school) rounding of the fractional part of seconds
' may gives increasing time, date, month & year ;)
sClm1 = Format$(dDate, "yyyy:mm:dd")
sClm2 = Format$(dDate, "hh:mm:ss")
Debug.Print sDatInc & vbLf & _
sClm1 & " " & sClm2 & _
IIf(lArr(6) > 4, " ' *** Rounded Up!", "") & _
vbLf
Stop
End Sub
回复:古斯塔夫
>通常你将时间部分缩小
通常情况下,我的任务是站立。
如果它是时间戳 - 向下。如果它是时间diapason (勾选了多少?) - Up 。
此外,即使在第一种情况下,它也可能被舍入用于特殊目的,例如避免近时钟零事件提升。任务正在进行......
> 4/5舍入只会改变......
什么意思"只有"?你是否还等待上述简单的给定数据移动到边界之一?由于任务由OP确定,任何舍入都会转移一些值: " hh:mm:ss:ms" - > " HH:MM:SS" 强>
> ...将所有日志记录移动0.5秒
你确定吗?如果给出原始" 2016:6:28:10:15:0:390000000" ?
它将被移动0.39-Down或0.61-Up ......
我提出了一些很复杂但很常见的解决方案,很容易从一个舍入转换到另一个舍入。它只需要添加唯一的' = Chr(39)符号:)
dDate = dDatDat + dDatTim ' - CLng(lArr(6) > 4) / 86400
这不难,是吗? 但它是这个任务陷阱之一及其解决方案的直观表现。
>我相信只需要一个阵列
- 是的......我明白了我并不感到惊讶,因为您认为字符串操作在数字解析等任务中是可以接受的。 第二个数组的目的是为了避免超低级字符串操作。对于我自己,我根本不会使用Split(),而只是解析字节数组...
而且,顺便说一句, - 的任务是尽量减少使用过的数组的数量,或者尝试用一两串代码填充解决方案吗?..
对不起,明星们现在不赞成字符串:)