Excel VBA – 从格式不正确的date中提取正确的date?

我目前正在学习VBA编程,遇到了以下情况,希望能对你们有所帮助。 理想情况下,不仅仅是寻找解决scheme,还要理解解决scheme的工作方式和原因。

假设有一个数据库可以导出数据的电子表格。 其中一列具有date值,但从导出格式错误。 系统发送date为mm / dd / yyyy hh:mm AM / PM,例如, 04/11/2014 09:24 AM ,但电子表格将其标识为dd / mm / …,表示它进入04作为一天,11作为一个月。

在本专栏中,如果一天在本月12日之前或之中,则该单元格将被格式化为date。 如果一天过了12日,这个单元格将被格式化为一般格式。

我的问题是,我可以编写一个VBAmacros,可以反转date和月份的值,并在新的列中创build正确的date? 我认为它首先必须确定一个单元格是否被格式化为date,然后以某种方式将date和月份提取到正确的位置,或者将其格式化为一般格式,然后使用不同的代码来提取正确的date。

如果这对于这个社区来说太基础了,还有另一个更适合的社区,我会很乐意在那里重新发布我的问题。

编辑:

在我的评论下面我玩了function,并寻找其他类似的function,可以帮助做我所需要的,切换date值的月份值,到目前为止,我有:

 'for dates with general format: 04/14/2014 11:20 AM =DATE(MID(A1,7,4),LEFT(A1,2),MID(A1,4,2)) 'in a column for the date =TIME(MID(A1,12,2),MID(A1,15,2),"00") 'in a column for time, since I may need this 'for dates with a date format: 4/11/2014 7:35:00 PM =DATE(TEXT(A1,"yyyy"),TEXT(A1,"dd"),TEXT(A1,"mm")) 'in a column for the date =TEXT(A1,"hh:mm AM/PM") 'in a column for time 

现在我只需要找出一个条件函数来确定何时根据值或格式或列A来应用每组公式。

但是有没有相同的function来通过VBA实现这一点? 我需要这些date和时间列只保存值,而不是公式,以便我可以直接导出数据。 不知怎的,把这个VBA代码看起来更“干净”,使用公式感觉像一个不稳定的解决scheme。 我不知道如何正确解释这个,但是在我的数据操作背后,我有一些更合适的编码。

EDIT2:

我已经解决了如下的工作表函数解决scheme。 我花了一段时间才弄清楚如何使用date格式化的单元格来查找FIND错误,并且只有在写入= IF的时候才在Excel列表中发现IFERROR函数。

 'to get the correct date =IF(IFERROR(FIND("/",A1),0)>0,DATE(MID(A1,7,4),LEFT(A1,2),MID(A1,4,2)),DATE(TEXT(A1,"yyyy"),TEXT(A1,"dd"),TEXT(A1,"mm"))) 'to get the correct time =IF(IFERROR(FIND("/",A1),0)>0,TIME(MID(A1,12,2),MID(A1,15,2),"00"),TEXT(A1,"h:mm AM/PM")) 

现在至less我有一个工作解决scheme,但我仍然对这些公式的VBA翻译感兴趣,并将继续寻找这些解决scheme。

看一下这个。 举个例子,你的公式是:

=IF(IFERROR(FIND("/",A1),0)>0,DATE(MID(A1,7,4),LEFT(A1,2),MID(A1,4,2)),DATE(TEXT(A1,"yyyy"),TEXT(A1,"dd"),TEXT(A1,"mm")))

VBA等效function:

Find = Instr
Date = DateSerial
文本=格式(不完全一样,但最近)

相同的代码:

 Dim mydate As Date Dim myformat As String myformat = "mm/dd/yyyy hh:mm AM/PM" If InStr(1, [A1], "/") > 0 Then mydate = DateSerial(Mid(Format([A1], myformat), 7, 4), _ Left(Format([A1], myformat), 2), Mid(Format([A1], myformat), 4, 2)) Else mydate = DateSerial(Year([A1]), Month([A1]), Day([A1])) End If [B1] = mydate 

注意[A1]是一个快捷的Evaluate函数,也可以写成Evaluate("A1")
我用这个来指代你的公式中的单元格A1。 您可以像这样使用传统的Range Object引用: Range("A1") 。 我使用的捷径,因为它看起来更干净。 但是在庞大的数据集中是不可取的。

为你的时间公式:

=IF(IFERROR(FIND("/",A1),0)>0,TIME(MID(A1,12,2),MID(A1,15,2),"00"),TEXT(A1,"h:mm AM/PM"))

代码等同:

 Dim mytime As Date If InStr(1, [A1], "/") > 0 Then mytime = TimeValue([A1]) Else '~~> myformat is declared above mytime = TimeValue(Format([A1], myformat)) End If [C1] = mytime 

您也可以检查如下单元格的格式:

 Select Case True Case [A1].NumberFormat = "General" mydate = DateSerial(Year([A1]), Month([A1]), Day([A1])) mytime = TimeValue(Format([A1], myformat)) Case [A1].NumberFormat = myformat '~~> again this is declared above mydate = DateSerial(Mid(Format([A1], myformat), 7, 4), _ Left(Format([A1], myformat), 2), Mid(Format([A1], myformat), 4, 2)) mytime = TimeValue([A1]) Case Else MsgBox "Invalid Format. Cannot be evaluated" End Select [B1] = mydate: [C1] = mytime 

不知道以上是否真的能解决您的问题。
从数据库中提取date时间戳时有很多可能性。
如果你提到的情况只是你遇到的问题,那么上面的解决scheme可能工作。