公式和一些背景:
如果您想约会,请查看一些使用公式的想法,这将有助于您理解以后使用 VBA。最终,您需要创建一个可以解析为日期的字符串。在您引用的示例中,CDate 函数能够将字符串识别为日期并将其转换为日期数据类型。
1) 如果Apr 5, 2018, 10:00 AM 在A2 中,您可以使用简单的:
=DATE(RIGHT(SUBSTITUTE(LEFT(A2,FIND(", ",A2,FIND(", ",A2)+1)-1),",",""),4),MONTH(1&LEFT(SUBSTITUTE(LEFT(A2,FIND(", ",A2,FIND(", ",A2)+1)-1),",",""),3)),TRIM(MID(SUBSTITUTE(LEFT(A2,FIND(", ",A2,FIND(", ",A2)+1)-1),",",""),5,2)))
内心
=SUBSTITUTE(LEFT(A2,FIND(", ",A2,FIND(", ",A2)+1)-1),",","")
获取第二个 "," 之前的字符串,然后将剩余的 "," 替换为 "" 给出
Apr 5 2018
公式的其余部分使用 Date 函数从日期部分(即年、月、日)创建日期。
假设 Month 始终是 3 个字母的缩写。字符串内有单个空格,两边都没有额外的空格。
2) 如果没有这样的假设,您最终可能会得到以下结果:
=DATE(RIGHT(LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),CHAR(32),CHAR(1),3))-1),4),MONTH(1&LEFT(LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),CHAR(32),CHAR(1),3))-1),3)),MID(A4,4,FIND(CHAR(1),SUBSTITUTE(LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),CHAR(32),CHAR(1),3))-1),CHAR(32),CHAR(1),2))-FIND(CHAR(1),SUBSTITUTE(LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(TRIM(SUBSTITUTE(SUBSTITUTE(A2,",",""),CHAR(32)," ")),CHAR(32),CHAR(1),3))-1),CHAR(32),CHAR(1),1))))
这是一个表格,解释了这两个步骤的每个步骤:
图像中的公式按参考编号
1) 删除了 "," 和多余的空格
=TRIM(SUBSTITUTE(SUBSTITUTE(B2,",",""),CHAR(32)," "))
2) 获取没有时间的日期部分
=LEFT(TRIM(SUBSTITUTE(SUBSTITUTE(B2,",",""),CHAR(32)," ")),FIND(CHAR(1),SUBSTITUTE(B3,CHAR(32),CHAR(1),3))-1)
3) 第一个空格“”的位置
=FIND(CHAR(1),SUBSTITUTE(B4,CHAR(32),CHAR(1),1))
4) 第二个空格“”的位置
=FIND(CHAR(1),SUBSTITUTE(B4,CHAR(32),CHAR(1),2))
5) 月份数
=MONTH(1&LEFT(B4,3))
6) 年份
=RIGHT(B4,4)
7) 天
=MID(B4,4,FIND(CHAR(1),SUBSTITUTE(B4,CHAR(32),CHAR(1),2))-FIND(CHAR(1),SUBSTITUTE(B4,CHAR(32),CHAR(1),1)))
8) 日期部分 Y、M、D 中的日期
=DATE(B8,B7,B9)
9) 上面已经给出的长公式作为第二种解决方案
10) 获取第二个 "," 之前的字符串,然后将剩余的 "," 替换为 ""
=SUBSTITUTE(LEFT(B2,FIND(", ",B2,FIND(", ",B2)+1)-1),",","")
11) 顶部给出的公式作为带有大量假设的第一个解决方案
VBA:
编辑:
@Darren Bartrup-Cook 指出 CDate 比我想象的更有效,你可以简单地做到:
CDate(Replace(.Range("B2").Text, ",", ""))
这将保留时间元素。如果需要,我已经介绍了在答案前面删除时间元素。或者你可以这样做
Int(CDate(Replace(.Range("B2").Text, ",", "")))
原文:
使用 vba,您可以使用 Instr 或 Instrrev 函数而不是 Find 来定位字符串中某个字符的出现位置。在使用 VBA 时,Find 与范围对象一起使用,而不是与其中的字符串一起使用。 Instr 从字符串的开头开始搜索,InstrRev 从结尾开始搜索,即从右到左。这意味着参数顺序会发生变化。有关这方面的更多信息,请参阅参考资料。
根据您引用的答案,使用 CDate 函数作为 vba 代码的简单公式。
Public Sub test()
With ThisWorkbook.Worksheets("Sheet1")
Debug.Print CDate(Left$(.Range("B2").Text, InStr(InStr(.Range("B2").Text, ", ") + 1, .Range("B2").Text, ", ") - 1))
End With
End Sub
您可以在要转换值的范围内循环使用上述内容。
类似:
.Range("B2") = CDate(Left$(.Range("B2").Text, InStr(InStr(.Range("B2").Text, ", ") + 1, .Range("B2").Text, ", ") - 1))
或者,
您可以将其转换为用户定义的函数并从工作表中调用:
Public Function GetDate(ByVal rng As Range)
GetDate = CDate(Left$(rng.Text, InStr(InStr(rng.Text, ", ") + 1, rng.Text, ", ") - 1))
End Function
在工作表中调用 UDF
请注意,您要么将单元格格式化为日期格式以获得正确的格式,要么将函数更改为:
GetDate = Format$(CDate(Left$(rng.Text, InStr(InStr(rng.Text, ", ") + 1, rng.Text, ", ") - 1)), "dd/mm/yyyy")
参考资料:
-
Instrrev
- Instr
- Range.Find
- Substitute
- Char
- User Defined Functions UDF
- CDate