2010-04-14 105 views
3

我知道這是一個相當普遍的問題,但我還沒有找到可靠的解決方案。Excel VBA:導入CSV日期爲dd/mm/yyyy

我有一個csv文件格式爲dd/mm/yyyy的第一列的數據。當我用Workbooks.OpenText打開它時,默認爲mm/dd/yyyy,直到它發現它認爲的月份超過12,然後恢復爲dd/mm/yyyy。

這是我的測試代碼,它試圖強制它爲xlDMYFormat,並且我也試過了文本格式。我知道這個問題只適用於* .csv文件,而不是* .txt,但這不是一個可接受的解決方案。

Option Base 1 
Sub TestImport() 

Filename = "test.csv" 

Dim ColumnArray(1 To 1, 1 To 2) 

ColumnsDesired = Array(1) 
DataTypeArray = Array(xlDMYFormat) 

' populate the array for fieldinfo 
For x = LBound(ColumnsDesired) To UBound(ColumnsDesired) 
    ColumnArray(x, 1) = ColumnsDesired(x) 
    ColumnArray(x, 2) = DataTypeArray(x) 
Next x 

Workbooks.OpenText Filename:=Filename, DataType:=xlDelimited, Comma:=True, FieldInfo:=ColumnArray 

End Sub 

test.csv包含:

Date 
11/03/2010 
12/03/2010 
13/03/2010 
14/03/2010 
15/03/2010 
16/03/2010 
17/03/2010 

回答

-1

試試這個:

Workbooks.OpenText Filename:=Filename, DataType:=xlDelimited, Comma:=True 

Excel中應該正確地解釋這些日期值日期,即使你喜歡一個不同的格式。執行OpenText方法後,確定哪一列包含日期值並更改格式以適合您:

CsvSheet.Columns(1).NumberFormat = "dd/mm/yyyy" 
+0

> Excel應該正確地將這些日期值解釋爲日期 是的,它應該但不是。這就是整個問題。 – 2010-04-14 06:57:40

+0

嗯。你確定? * excel將什麼類型的值解釋爲?你有沒有檢查,或者你只是在做假設? – 2010-04-14 18:06:30

+0

順便說一句,你也可以很容易地將這些值複製到一個日期數組,然後將它們粘貼回工作表中,然後按照需要的方式格式化單元格,*不管數據類型Excel最初是否將值解釋爲正在處理的值。三行代碼,四個上衣。 – 2010-04-14 18:44:29

0

我用過的解決方案是;

  1. 變化從.csv文件名改爲.txt,然後再次嘗試導入(但聽起來好像這是不恰當的
  2. 更改您的PC上的區域設置。如果你的英語,澳大利亞,新西蘭等等,通常使用dd/mm/yyyy,然後Windows可能被錯誤地安裝爲美國的日期格式等。
  3. 要麼將​​它全部導入爲文本,然後轉換,或者編寫一些代碼來解析文件。需要確保你得到正確的日期。這是通用日期格式和CDATE()可以幫助你的地方。

下面的函數讀取一個字符串並將其更改爲dd/mm/yyyy日期。儘管如此,你必須格式化單元格。請注意,如果您已經將值作爲日期導入,這將無濟於事。

如果您將其用於模塊中,則可以在代碼中或作爲函數(UDF)使用它。

Function TextToDate(txt As String) As Date 

    Dim uDate As String 
    Dim d, m, y As String 
    Dim aDate() As String 

    aDate = Split(txt, "/") 
    If UBound(aDate) <> 2 Then 
    Exit Function 
    End If 

    d = Lpad(aDate(0), "0", 2) 
    m = Lpad(aDate(1), "0", 2) 
    y = aDate(2) 

    If Len(y) = 2 Then ''# I'm just being lazy here.. you'll need to decide a rule for this. 
    y = "20" & y 
    End If 

    ''# Universal Date format is : "yyyy-mm-dd hh:mm:ss" this ensure no confusion on dd/mm/yy vs mm/dd/yy 
    ''# VBA should be able to always correctly deal with this 

    uDate = y & "-" & m & "-" & d & " 00:00:00" 
    TextToDate = CDate(uDate) 
End Function 


Function Lpad(myString As String, padString As String, padLength As Long) As String 
    Dim l As Long 
    l = Len(myString) 
    If l > padLength Then 
    padLength = l 
    End If 

    Lpad = Right$(String(padLength, padString) & myString, padLength) 
End Function 
+0

區域設置設置爲英語(NZ),日期格式預期正確爲dd/mm/yyyy。 感謝您的代碼,但我在使用OpenText時遇到了問題,並且導入的值與文本(如Q中所列)相同。在旁邊,可以使用正常的日期(y,m,d)函數,而不是創建一個字符串並將其轉換。 你有幸使用OpenText的FieldInfo參數嗎? – 2010-04-14 07:14:58

+0

不好意思,我記得我的頭撞在牆上,有一個古怪的.csv文件,裏面有不同的日期格式,尾部有負片等等......最後我寫了一個類似於上面日期的解析器。它比Workbooks.OpenText慢,但它只花了幾個小時來編寫和運行速度足夠每月導入。因人而異 – 2010-04-14 11:41:43

3

我有完全相同的問題。這是一個將dd/mm/yyyy轉換爲mm/dd/yyyy的函數。只需一次給它提供一個日期。希望能幫助到你。

Function convertDate(x As String) As Date 
'convert a dd/mm/yyyy into mm/dd/yyyy' 
Dim Xmonth 
Dim XDay 
Dim XYear 
Dim SlashLocation 
Dim XTemp As String 


XTemp = x 
SlashLocation = InStr(XTemp, "/") 
XDay = Left(XTemp, SlashLocation - 1) 

XTemp = Mid(XTemp, SlashLocation + 1) 
SlashLocation = InStr(XTemp, "/") 
Xmonth = Left(XTemp, SlashLocation - 1) 

XTemp = Mid(XTemp, SlashLocation + 1) 
XYear = XTemp 

convertDate = Xmonth + "/" + XDay + "/" + XYear 

End Function 
0

這似乎是做伎倆,但仍然是一個破解。我將添加一個檢查範圍中的任何日期都不超過一天,以確保正確導入的數據不會反轉爲dd/mm/yyyy。

問題仍然是解決方案,而不是解決問題的方法。

感謝到目前爲止的帖子。

Function convertDate(x As String) As Date 
' treat dates as mm/dd/yyyy unless mm > 12, then use dd/mm/yyyy 
' returns a date value 

Dim aDate() As String 

aDate = Split(x, "/") 

If UBound(aDate) <> 2 Then 
    Exit Function 
End If 

If aDate(0) > 12 Then 
    d = aDate(0) 
    m = aDate(1) 
Else 
    d = aDate(1) 
    m = aDate(0) 
End If 

y = aDate(2) 

d = Lpad(d, "0", 2) 
m = Lpad(m, "0", 2) 

If Len(y) = 4 Then 
    Exit Function ' full year expected 
End If 

uDate = y & "-" & m & "-" & d & " 00:00:00" 
convertDate = CDate(uDate) 

End Function 

Function Lpad(myString, padString, padLength) 
    Dim l As Long 
    l = Len(myString) 
    If l > padLength Then 
    padLength = l 
    End If 

    Lpad = Right$(String(padLength, padString) & myString, padLength) 
End Function 
0

這是代碼...我的第一列是DD/MM/YYYY日期,第二列是文本... Array(1,4)是關鍵...

Workbooks.OpenText Filename:= _ 
    "ttt.txt", Origin:=437, StartRow _ 
    :=1, DataType:=xlDelimited, TextQualifier:=xlDoubleQuote, _ 
    ConsecutiveDelimiter:=False, Tab:=False, Semicolon:=False, Comma:=True _ 
    , Space:=False, Other:=False, FieldInfo:=Array(Array(1, 4), Array(2, 1)), _ 
    TrailingMinusNumbers:=True 

該值被確認爲適當的日期...您需要在此之後將DD/MM/YY格式應用於第一列。

1

我想讀一個txt文件,然後使用澳大利亞的日期格式dd/mm/yyyy,但我知道,如果你與Workbooks.Open功能,您可以設置時間爲當地打開一個文本文件..加入Local:=True

防爆

Workbooks.Open Filename:=VarOpenWorkbook, Local:=True 

這個工作對我來說...

1

意識到這是一個有點晚,但如果結合本地和陣列預選賽它應該正常工作:

Workbooks.OpenText Filename:=FileName, _ 
    FieldInfo:=Array(Array(1, 4), Array(2, 1)), Local:=True 
1

在你的 「Workbooks.OpenText」 行的末尾,添加本地:=真

Workbooks.OpenText filename:=filename, DataType:=xlDelimited, Comma:=True, FieldInfo:=ColumnArray, Local:=True 

這個工作在我的電腦,當我改變了我的區域爲英語(NZ)。

編輯:而現在我看到別人給出了相同的答案。 :-)

0

我剛剛發現的是,您必須將當地日期分配給變量類型Date。我不明白爲什麼它有幫助,但它確實如此。

dim xDate As Date 

xDate = PresDate.Value ' it is my form object let say it has 03/09/2013 

curRange.Value = xDate ' curRange is my cur cell 

雖然transfering dd/mm/yyyyxDate它仍然dd/mm/yyyy並把它在Excel中後,不會改變它。爲什麼?我不知道。但經過多次嘗試後,它有所幫助希望它會對很多人有幫助=)