通过macros导入CSV时date格式不一致

我是一个完整的Excel VBA新手。 我最近设法将下面的macros安装到我的个人工作簿中,以便可以通过点击一个button来导入CSV文件(select必要的选项):

Sub OpenTextFile() filetoopen = Application.GetOpenFilename("Text Files (*.txt;*.csv), *.txt;*.csv") If filetoopen = Null Or filetoopen = Empty Then Exit Sub Workbooks.OpenText Filename:=filetoopen, _ Origin:=65001, DataType:=xlDelimited, Comma:=True End Sub 

有用。 但是,它并不一致。 我用它来处理不同的CSV文件(所有这些都是在ISO 8601date系统中预先格式化的),但是我得到了不同的结果。 在其中一些date输出是DD / MM / YYYY hh:mm,但在其他一些奇怪的我不明白(如00:00,0或50:00,0)。 我可以手动select行内容并将格式更改为长期的,所以至less我确信,Excel可以将数据识别为date而不是文本。

我怎样才能确保date都格式化? 这取决于什么?

谢谢!

不同的date格式在导入到excel时出了名,因为Windows本地化(使用默认的分隔符,date和数字格式)很难处理。

不要乱搞windows本地化只是为了导入一个文件。

重复导入csv-Files时,我使用以下方法:

  1. 我为有问题的csv-Files设置了schema.ini文件。 看到这个更多的信息

  2. 我也是

    • 用SQL和ADODB查询csv-File,它允许一个简单的SELECT *简单的预处理(重新排列列,过滤logging…)。 我可以将生成的ADODB.Recordset输出到我的工作簿中

    • 我在工作簿中设置了一个链接表ADODB.Connection。 数据可以用一个简单的macros或右键点击来更新。

无论哪种方式:国际海事组织使用schema.ini文件有以下优点

  • 允许您处理任何date和数字格式,而无需调整您的Excel工作簿或vba代码
  • 结构简单透明,可读性强
  • 一套设置。 每个excel表单或数据库都可以使用相同的schema.ini文件来处理您的数据。

编辑:这可以提供一个起点。

  1. 在存储csv的文件夹中创build一个名为schema.ini的新文本文件
  2. 在记事本(或更好:记事本++)中打开,将其粘贴到它

     [yourfile.csv] CharacterSet = ANSI ColNameHeader = FALSE Format = Delimited(;) DateFormat = "DD.MM.YYYY" DateTimeFormat = "DD.MM.YYYY hh:nn,ss" Col1 = yourdatefield DateTime Col2 = somelongfield Long 
  3. 阅读后点击进入下面的链接描述进行调整

    • 文件名
    • 格式(什么分隔符,或者是固定的)
    • DateFormat和/或DateTimeFormat。 意识到分钟是nn而不是常见的mm
    • 你想要的列标题和列数据types。 你需要ColNameHeader = FALSE
  4. 在VBA中设置一个ADO连接,使您能够运行SQL语句并返回ADOlogging集。

  5. 像这样运行一个SQL语句

    SELECT * FROM [Text;DATABASE=C:\Users\yourFolder].yourfile.csv

  6. 与logging集一起工作

注意:你提到了一些混合时间十进制写( 50:00,0 )。 只要列中的任何数字都指时间单位,例如秒或分钟,则将该字段声明为DateTime字段没有问题。

但是,如果像00:00,50意思是半分钟而不是50秒,那么可能需要将其作为文本读取,然后在SQL语句中使用FORMAT()LEFT()

解决了:问题不在于Excel,而在于为我提供了CSV文件的服务。 显然,他们有两个select从他们的网站下载CSV,他们格式化date不同。 其中一个正确使用ISO-8601,另一个是在datestring的末尾添加“.0”,所以Excel将其翻转并视为文本string。

无论如何,谢谢你的回复。

CSV意味着逗号分隔值。 如果你有00:00,0那么你有两个值。 除非你的分隔符是别的 – 例如;-

编辑:导入后,只需要通过每个单元格循环,并检查是否是dateisdate(range) 。 如果是这种情况,你可以自己格式化,如你所愿。 例如 – > my_cell.NumberFormat = "mmmm"

因此类似于:

 for each my_cell in my_sheet.UsedRange if isdate(my_cell) then my_cell.numberformat = "mmmm" next my_cell