字符串到日期的转换 Excel VBA
String to date conversion with Excel VBA
有一个字符串日期时间,其中包含需要删除的待定 'AEST',以便进行日期计算
使用查找并用空白作品替换 'AEST' 手动执行此操作。
但是想在 VBA 中执行此操作是行不通的。
- 例如,当有 4 个样本日期时存在不一致,并且其中 2 个日期被转换为美国时间而不是澳大利亚时间。
- 不知道这种不一致的根本原因
Sub KPIM_RptMth()
Range("H:H").Select
Selection.Replace What:="AEST", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
End Sub
e.g. sample dates:
[REQ] WOC Date and Time
12-04-2019 01:03:32 PM AEST
22-06-2019 08:33:04 AM AEST
11-06-2019 03:30:00 PM AEST
17-06-2019 02:50:00 PM AEST
the correct output is:
[REQ] WOC Date and Time
12/04/2019 13:03
22/06/2019 8:33
11/06/2019 15:30
17/06/2019 14:50
the actual output after the VBA script above runs is:
[REQ] WOC Date and Time
4/12/2019 13:03
22-06-2019 08:33:04 AM
6/11/2019 15:30
17-06-2019 02:50:00 PM
问题是计算机无法知道此字符串日期的格式
12-04-2019 01:03:32 PM AEST
可以是以下两种
dd-mm-yyyy
mm-dd-yyyy
所以你所做的就是让计算机猜测,但它失败了。即使是人也不能说这两种格式中哪一种是正确的。因此,日期是字符串而不是真正的日期是非常无用的(除非您有关于格式的其他信息,这不是日期字符串本身的一部分)。
因此,将字符串转换为日期的唯一可行的解决方案是如果您知道这两种格式中哪种格式是正确的第一,使用此信息将日期拆分成多个部分并使用 DateSerial function 从中创建一个真实日期。
您需要对每个单元格执行类似下面的操作作为字符串-日期转换。
一个例子
Public Sub ConvertTimeStampToRealDateTime()
Dim TimeStampString As String
TimeStampString = "12-04-2019 01:03:32 PM AEST"
'split by spaces
Dim SplitTimeStamp As Variant
SplitTimeStamp = Split(TimeStampString, " ")
'SplitTimeStamp(0) = "12-04-2019"
'SplitTimeStamp(1) = "01:03:32"
'SplitTimeStamp(2) = "PM"
'SplitTimeStamp(3) = "AEST"
'split date by dash
Dim SplitDate As Variant
SplitDate = Split(SplitTimeStamp(0), "-")
'SplitDate(0) = "12"
'SplitDate(1) = "04"
'SplitDate(2) = "2019"
'now we add the information which of the 3 split parts is day, month and year
'and put it together to a real date
Dim RealDate As Date
RealDate = DateSerial(SplitDate(2), SplitDate(1), SplitDate(0))
'cast time string into a date
Dim RealTime As Date
RealTime = SplitTimeStamp(1) & " " & SplitTimeStamp(2)
'casting from string to date works good for times but not for dates
'so we can do that with the time
'Add date and time to make it a datetime
Dim RealDateTime As Date
RealDateTime = RealDate + RealTime 'note that we need to ADD them mathematically (+) this is not a string concatenation (&)!!!
'AEST: This information about how many hours you need to add or subtract
' from this datetime to convert it into your desired time zone needs
' needs to be done manually
Dim RealDateTimeInMyZone As Date
RealDateTimeInMyZone = DateAdd("h", -3, RealDateTime) 'for example subtract 3 hours
End Sub
最后,您可以将您的真实日期时间写入单元格,并使用 Range("A1").NumberFormat
将其格式化为您喜欢的格式。
图 1:字符串到日期转换期间的变量值。
请注意上面的代码只是这个概念的一个例子。如果你需要让它变得可靠,你可能需要一些检查和错误处理,因为它会在意外的输入字符串上失败。
此外,从中创建一个可以重复使用的函数可能是个好主意,例如:
Public Function ConvertDDMMYYYYTimeStampToRealDateTime(ByVal TimeStampString As String) As Date
End Function
您也可以使用 Power Query
又名 Get & Transform
在 Excel 2010+
中可用
所有步骤都可以通过 GUI 完成
- 获取来自Table/Range
的数据
- 按
space
分隔符拆分列(仅限最右边的实例)
- 更改格式 -- 通过语言环境 选择
DateTime
格式和 English(Australia)
语言环境
完成此操作一次后,如果刷新数据源 table,则可以更新查询。
工作表现在将包含“真实”Excel date/times,如果格式不符合您的要求,只需更改单元格格式即可。
原创
结果
M-Code(你真的不需要这个,但是如果你把它粘贴到高级编辑器中,它会重新创建 GUI 步骤遇到问题了。
如果使用此方法,您可能需要更改 Table
名称。)
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Split Column by Delimiter" = Table.SplitColumn(Source, "[REQ] WOC Date and Time", Splitter.SplitTextByEachDelimiter({" "}, QuoteStyle.Csv, true), {"[REQ] WOC Date and Time.1", "[REQ] WOC Date and Time.2"}),
#"Removed Columns" = Table.RemoveColumns(#"Split Column by Delimiter",{"[REQ] WOC Date and Time.2"}),
#"Changed Type with Locale" = Table.TransformColumnTypes(#"Removed Columns", {{"[REQ] WOC Date and Time.1", type datetime}}, "en-AU")
in
#"Changed Type with Locale"
有一个字符串日期时间,其中包含需要删除的待定 'AEST',以便进行日期计算
使用查找并用空白作品替换 'AEST' 手动执行此操作。 但是想在 VBA 中执行此操作是行不通的。 - 例如,当有 4 个样本日期时存在不一致,并且其中 2 个日期被转换为美国时间而不是澳大利亚时间。 - 不知道这种不一致的根本原因
Sub KPIM_RptMth()
Range("H:H").Select
Selection.Replace What:="AEST", Replacement:="", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False
End Sub
e.g. sample dates:
[REQ] WOC Date and Time
12-04-2019 01:03:32 PM AEST
22-06-2019 08:33:04 AM AEST
11-06-2019 03:30:00 PM AEST
17-06-2019 02:50:00 PM AEST
the correct output is:
[REQ] WOC Date and Time
12/04/2019 13:03
22/06/2019 8:33
11/06/2019 15:30
17/06/2019 14:50
the actual output after the VBA script above runs is:
[REQ] WOC Date and Time
4/12/2019 13:03
22-06-2019 08:33:04 AM
6/11/2019 15:30
17-06-2019 02:50:00 PM
问题是计算机无法知道此字符串日期的格式
12-04-2019 01:03:32 PM AEST
可以是以下两种
dd-mm-yyyy
mm-dd-yyyy
所以你所做的就是让计算机猜测,但它失败了。即使是人也不能说这两种格式中哪一种是正确的。因此,日期是字符串而不是真正的日期是非常无用的(除非您有关于格式的其他信息,这不是日期字符串本身的一部分)。
因此,将字符串转换为日期的唯一可行的解决方案是如果您知道这两种格式中哪种格式是正确的第一,使用此信息将日期拆分成多个部分并使用 DateSerial function 从中创建一个真实日期。
您需要对每个单元格执行类似下面的操作作为字符串-日期转换。
一个例子
Public Sub ConvertTimeStampToRealDateTime()
Dim TimeStampString As String
TimeStampString = "12-04-2019 01:03:32 PM AEST"
'split by spaces
Dim SplitTimeStamp As Variant
SplitTimeStamp = Split(TimeStampString, " ")
'SplitTimeStamp(0) = "12-04-2019"
'SplitTimeStamp(1) = "01:03:32"
'SplitTimeStamp(2) = "PM"
'SplitTimeStamp(3) = "AEST"
'split date by dash
Dim SplitDate As Variant
SplitDate = Split(SplitTimeStamp(0), "-")
'SplitDate(0) = "12"
'SplitDate(1) = "04"
'SplitDate(2) = "2019"
'now we add the information which of the 3 split parts is day, month and year
'and put it together to a real date
Dim RealDate As Date
RealDate = DateSerial(SplitDate(2), SplitDate(1), SplitDate(0))
'cast time string into a date
Dim RealTime As Date
RealTime = SplitTimeStamp(1) & " " & SplitTimeStamp(2)
'casting from string to date works good for times but not for dates
'so we can do that with the time
'Add date and time to make it a datetime
Dim RealDateTime As Date
RealDateTime = RealDate + RealTime 'note that we need to ADD them mathematically (+) this is not a string concatenation (&)!!!
'AEST: This information about how many hours you need to add or subtract
' from this datetime to convert it into your desired time zone needs
' needs to be done manually
Dim RealDateTimeInMyZone As Date
RealDateTimeInMyZone = DateAdd("h", -3, RealDateTime) 'for example subtract 3 hours
End Sub
最后,您可以将您的真实日期时间写入单元格,并使用 Range("A1").NumberFormat
将其格式化为您喜欢的格式。
请注意上面的代码只是这个概念的一个例子。如果你需要让它变得可靠,你可能需要一些检查和错误处理,因为它会在意外的输入字符串上失败。
此外,从中创建一个可以重复使用的函数可能是个好主意,例如:
Public Function ConvertDDMMYYYYTimeStampToRealDateTime(ByVal TimeStampString As String) As Date
End Function
您也可以使用 Power Query
又名 Get & Transform
在 Excel 2010+
所有步骤都可以通过 GUI 完成
- 获取来自Table/Range 的数据
- 按
space
分隔符拆分列(仅限最右边的实例) - 更改格式 -- 通过语言环境 选择
DateTime
格式和English(Australia)
语言环境
完成此操作一次后,如果刷新数据源 table,则可以更新查询。
工作表现在将包含“真实”Excel date/times,如果格式不符合您的要求,只需更改单元格格式即可。
原创
结果
M-Code(你真的不需要这个,但是如果你把它粘贴到高级编辑器中,它会重新创建 GUI 步骤遇到问题了。
如果使用此方法,您可能需要更改 Table
名称。)
let
Source = Excel.CurrentWorkbook(){[Name="Table1"]}[Content],
#"Split Column by Delimiter" = Table.SplitColumn(Source, "[REQ] WOC Date and Time", Splitter.SplitTextByEachDelimiter({" "}, QuoteStyle.Csv, true), {"[REQ] WOC Date and Time.1", "[REQ] WOC Date and Time.2"}),
#"Removed Columns" = Table.RemoveColumns(#"Split Column by Delimiter",{"[REQ] WOC Date and Time.2"}),
#"Changed Type with Locale" = Table.TransformColumnTypes(#"Removed Columns", {{"[REQ] WOC Date and Time.1", type datetime}}, "en-AU")
in
#"Changed Type with Locale"