如何设置Excel以始终将CSV文件的所有列都导入为“文本”?


68

尽管我尝试避免这种情况,但偶尔还是需要在Excel中打开CSV文件。当我这样做时,它将格式化包含数字的列,这使它们对我的目的无用。据我所知,防止这种情况在导入时发生的唯一方法是重命名文件,使扩展名不是.csv,并使用导入向导分别指定每列的格式。对于具有50至60列的文件,这是不切实际的。

由于在互联网上这个经常问到的问题的每个答案都建议使用某种方法在文件打开后将格式化的数字转换回去(这对我不起作用-我想解决一般性问题,而不是少数几种情况)或手动选择每列的格式类型(我不想这样做),我正在寻找一种设置全局首选项或样式的方法,以使打开的所有C​​SV文件的所有列都始终设置为文本格式。我也知道用引号将数字“装甲”,但是我得到的文件不是那样,我希望避免对文件进行预处理,以免Excel搞砸它们。

有没有办法做到明确这一点:始终格式化所有列在打开CSV文件作为文本,不导入过程中每次手动选择每列?

我正在使用Excel 2003,但是如果您知道的话,我将为2007年提供答案。


1
嘿Scripting Guy撰写了一篇有关将CSV导入Excel的博客文章,该文章可能对您有用。在Powershell中使用数据对象可以使您做自己想做的事情。由于它实际上只是一个脱机链接,因此未发布为答案,但可能会对您有所帮助。
Matrix Mole

Answers:


7

这有效:

Sub OpenCsvAsText(ByVal strFilepath As String)

    Dim intFileNo As Integer
    Dim iCol As Long
    Dim nCol As Long
    Dim strLine As String
    Dim varColumnFormat As Variant
    Dim varTemp As Variant

    '// Read first line of file to figure out how many columns there are
    intFileNo = FreeFile()
    Open strFilepath For Input As #intFileNo
    Line Input #intFileNo, strLine
    Close #intFileNo
    varTemp = Split(strLine, ",")
    nCol = UBound(varTemp) + 1

    '// Prepare description of column format
    ReDim varColumnFormat(0 To nCol - 1)
    For iCol = 1 To nCol
        varColumnFormat(iCol - 1) = Array(iCol, xlTextFormat)
        ' What's this? See VBA help for OpenText method (FieldInfo argument).
    Next iCol

    '// Open the file using the specified column formats
    Workbooks.OpenText _
            Filename:=strFilepath, _
            DataType:=xlDelimited, _
            ConsecutiveDelimiter:=False, Comma:=True, _
            FieldInfo:=varColumnFormat

End Sub

用法:

OpenCsvAsText "C:\MyDir\MyFile.txt"

现在,以逗号分隔的文件作为Excel工作表打开,所有列均设置为文本格式。

请注意,@ Wetmelon的向导解决方案效果很好,但是如果您打开许多文件,则可能像我一样每次都感到厌倦,滚动到第60列以便按住Shift并单击它。

EDIT @GSerg在下面的评论中指出,这“无效”,并且“占用空格和前导零”。我只引用该问题的评论,它更具描述性:

由于未知的原因,即使您明确为VBA中的所有列提供格式,如果文件扩展名是CSV,Excel也会忽略它。更改扩展名后,相同的代码将产生正确的结果。

因此,上面的代码“有效”,但是被这种可笑的Excel行为杀死了。无论采用哪种方式剪切,都不得不将扩展名更改为“ .csv”以外的其他内容,对不起!之后,您将有空。


1
不起作用 吃的空间,吃前导零等
GSerg


1
所使用的方法Workbooks.OpenText在设计上存在缺陷(请参阅下面的答案)。使用QueryTables代替。
nixda

71

如何在Excel中打开CSV

好办法

  • Excel→数据→获取外部数据→使用选择所有列,Shift然后选择文本

    好处:将所有值正确地视为文本,没有任何异常

    缺点:比简单的双击更多的步骤

不好的方法

  • 双击打开CSV 或Excel的“ 打开方式”对话框

    缺点:Excel的内部CSV处理程序将开头-=符号的值误解为公式而不是文本

    缺点:0001由于Excel的自动检测列格式,您将失去二进制值的前导零

好方法(适用于VBA)

  • 使用QueryTables(与VBA相对应Get external data)→ 示例代码

    好处:将所有值正确地视为文本,没有任何异常

    缺点:比OpenText方法略多的代码

不好的方法(对于VBA)

  • 使用Workbooks.OpenText方法→ 示例代码

    缺点:此方法仍在使用Excel的内部CSV导入处理程序,但存在所有缺陷

    缺点:此外,如果扩展名为CSV fieldinfoOpenText则会忽略的参数。通常,此参数使您可以选择每种列格式,但是如果扩展名为CSV,则不能。您可以在Stack Overflow上了解有关此行为的更多信息

    如果您完全控制源文件,则将源扩展名从CSV临时重命名为TXT,然后再重新命名为CSV是一种有效的解决方法

其他方法

  • 如果您有权访问创建CSV的源,则可以更改CSV语法。
    每个值都用双引号引起来,并在等号之前="00001"加上前缀,或在每个值之前添加制表符。两种方法都将强制Excel将值视为文本

    原始CSV内容
    在此处输入图片说明

    通过双击打开Excel中的CSV
    在此处输入图片说明

    请注意第2行(双引号方法)和第3行(制表符方法)如何不被Excel更改

  • 记事本中打开CSV,然后将所有值复制并粘贴到Excel。然后使用数据-文本到列的
    缺点:将列格式从常规更改为文本时,列中的文本会产生不一致的结果。如果一个值包含一个-用字符括起来的字符(例如“ = E1-S1”),Excel会尝试将该值分成多列。该单元格右边的值可能会被覆盖

    (“ 文本到列 ”的行为在Excel 2007和2013之间已更改,因此不再起作用)


Excel加载项以打开CSV并将所有值导入为文本

这是一个Excel插件,可以简化CSV导入操作。
主要优点:它是一键式解决方案,并使用QueryTables,与获取外部数据后的防弹方法相同

  • 它向Excel添加了一个新的菜单命令,使您可以导入CSV和TXT文件。从当前选定的单元格开始,所有值都将导入到活动工作表中
  • Excel加载项可用于Windows和Mac上的所有Office版本
  • 整个加载项只有35行代码。如果您感到好奇,请检查注释的源代码
  • 使用的CSV列表分隔符(逗号或分号)取自您本地的Excel设置
  • 编码设置为UTF-8

安装

  1. 下载外接程序并将其保存到您的外接程序文件夹中:%appdata%\Microsoft\AddIns
  2. 打开Excel并激活加载项:,File tab → Options → Add-Ins → Go To然后选择ImportCSV.xla
  3. 启用VBA宏: File tab → Options → Trust Center → Trust Center Settings → Macro Settings → Enable all macros
  4. 重新启动Excel

您会注意到一个名为“加载项”的新菜单栏条目,并且使用此按钮可以快速打开CSV文件,而无需经历“导入”对话框的麻烦

在此处输入图片说明


PowerShell脚本可直接从Windows资源管理器打开CSV

您可以使用PowerShell脚本打开CSV文件并将其自动传递给Excel。该脚本以静默方式使用Excel的文本导入方法,该方法始终将值视为文本,并且作为奖励使用UTF-8编码

  1. 创建一个新的文本文件并粘贴以下脚本。可以在这里找到评论版本
$CSVs = @()
$args.ForEach({
    If ((Test-Path $_) -and ($_ -Match "\.csv$|\.txt$")) {
        $CSVs += ,$_
    } 
})

if (-Not $null -eq $CSVs) {

    $excel = New-Object -ComObject excel.application 
    $excel.visible = $true
    $excel.SheetsInNewWorkbook = $CSVs.Count    
    $workbook = $excel.Workbooks.Add()

    for ($i=0; $i -lt $CSVs.Count; $i++){

        $csv = Get-Item $CSVs[$i]
        $worksheet = $workbook.worksheets.Item($i + 1)
        $worksheet.Name = $csv.basename

        $TxtConnector = ("TEXT;" + $csv.fullname)
        $Connector = $worksheet.QueryTables.add($TxtConnector,$worksheet.Range("A1"))
        $query = $worksheet.QueryTables.item($Connector.name)
        $query.TextFilePlatform = 65001
        $query.TextFileTextQualifier = 1
        $query.TextFileOtherDelimiter = $Excel.Application.International(5) 
        $query.TextFileParseType  = 1
        $arrFormats = ,2 * $worksheet.Cells.Columns.Count
        $query.TextFileColumnDataTypes = $arrFormats
        $query.AdjustColumnWidth = 1
        $query.Refresh()
        $query.Delete()
    }
}
  1. 将其保存在C:\my\folder\myScript.ps1。(注意扩展名.ps1
    • 通过WinR» shell:sendto» 打开sendto文件夹Enter
  2. 通过右键单击»新建»快捷方式创建新的快捷方式,然后粘贴此行。不要忘记将路径更改为放置脚本的路径。命名快捷方式,例如Excel

“%SystemRoot%\ system32 \ WindowsPowerShell \ v1.0 \ powershell.exe” -NoProfile -NonInteractive -WindowStyle隐藏-文件“ C:\ my \ folder \ myScript.ps1”

现在,您可以选择(多个)CSV,并通过以下方式在Excel中打开它们 Right-click » SendTo » Excel


1
加载项在Office 2003和2013中进行了测试
nixda

最佳的“最佳方式”正是我一次性进口所需的。无需弄乱VBA,甚至可以控制将哪些列作为日期/数字(其余作为文本)。我希望Excel会在双击CSV时打开此导入向导。
ADTC

@Vadzim您好,感谢您为修复无效链接所做的努力。实际上,ge.tt在最近几个月中遇到了一些问题。但是我想我已经解决了所有问题,旧的原始链接应该可以再次使用。我不知道为什么Google Chrome浏览器会在从ge.tt下载任何内容之前发出警告。但是所有其他浏览器都可以正常运行,我可以向您保证它们不是恶意软件
nixda

@nixda,谢谢您恢复链接并做出了出色的回答
Vadzim

@nixda ge.tt的链接再次断开。大多数人说,由于所有者违反了服务条款,因此无法使用它们。但是,用于OpenCSV.exe的文件说:“这些文件违反了服务条款,因此不再可用。” 哪个让我问,您是ImportMyCSV Excel函数的作者吗?(pastebin上仍提供源代码)这是一个很棒的工具-我在工作中使用它,并已推荐给其他人。但是我对代码的起源很感兴趣,如果没有其他原因的话,可以使作者感到满意。
GlennFromIowa

5

您可以尝试先打开.xlsx,然后创建数据连接并导入.csv。选择“逗号”定界,然后选择将所有列视为文本而不是“常规”的选项。

编辑:哦,我没有完全阅读问题。在导入向导中,选择要作为文本导入的第一个列标题,滚动到最后一个列标题,然后按住Shift键并单击标题。然后选择“文本”放射状选项。


2
是的,这很好用-只要文件的扩展名不是“ .csv”即可。1
让弗朗索瓦科贝特

4

如果执行以下操作,则Wetmelon的建议会起作用(即使使用.CSV也是如此):

  1. 将Excel打开到空白工作簿或工作表
  2. 单击数据> [从文本获取外部数据]
  3. 使用Wetmelon所描述的“文本导入向导”(逗号分隔,选择第一列,按SHIFT + CLICK,最后一行,将所有内容设置为“文本”)。

我知道这是更多步骤,但至少可以让我以这种方式打开CSV,而不必更改扩展名


2

小心!

使用手动方法“ Excel→数据→获取外部数据→选择所有列并选择文本”时……

这只会将列设置为文本“第一行中有数据”(通常是标题行)。该向导不会向您显示更右侧的列,这些列可能在下方但在第一行中没有数据。例如:

Row1Col1,Row1Col2,Row1Col3

Row2Col1,Row2Col2,Row2Col3,Row2Col4

您将永远不会在导入向导中看到Col 4,因此您将无法在导入之前选择将其从常规格式更改为文本格式!


1
一个很好的警告,因为在99.9999%的时间内,人们不会在导入向导中向下滚动,即使那样,也很难捕获所有列。但是,从技术上讲,您可以在“导入”向导中向下滚动,并捕获第一行中没有数据的其他列。
GlennFromIowa

1

这是Jean-FrançoisCorbett在上面发布的代码的替代过程

此过程会将csv文件导入Excel,所有列的格式均设置为“文本”

Public Sub ImportCSVAsText()
    Dim TempWorkbook As Workbook
    Dim TempWorksheet As Worksheet
    Dim ColumnCount As Integer
    Dim FileName As Variant
    Dim ColumnArray() As Integer

    'Get the file name
    FileName = Application.GetOpenFilename(FileFilter:="All Files (*.*),*.*", FilterIndex:=1, Title:="Select the CSV file", MultiSelect:=False)

    If FileName = False Then Exit Sub

    Application.ScreenUpdating = False

    'Open the file temporarily to get the count of columns
    Set TempWorkbook = Workbooks.Open(FileName)
    ColumnCount = TempWorkbook.Sheets(1).Range("A1").SpecialCells(xlCellTypeLastCell).Column
    TempWorkbook.Close SaveChanges:=False

    'Resize the array to number of columns
    ReDim ColumnArray(1 To ColumnCount)

    For i = 1 To ColumnCount
        ColumnArray(i) = xlTextFormat
    Next i

    Set TempWorkbook = Workbooks.Add
    Set TempWorksheet = TempWorkbook.Sheets(1)

    Application.DisplayAlerts = False
    TempWorkbook.Sheets(2).Delete
    TempWorkbook.Sheets(2).Delete
    Application.DisplayAlerts = True

    With TempWorksheet.QueryTables.Add("TEXT;" & FileName, TempWorksheet.Cells(1, 1))
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .TextFilePromptOnRefresh = False
        .TextFilePlatform = 1251
        .TextFileStartRow = 1
        .TextFileParseType = xlDelimited
        .TextFileTextQualifier = xlTextQualifierDoubleQuote
        .TextFileConsecutiveDelimiter = False
        .TextFileTabDelimiter = False
        .TextFileSemicolonDelimiter = False
        .TextFileCommaDelimiter = True
        .TextFileSpaceDelimiter = False
        .TextFileColumnDataTypes = ColumnArray
        .TextFileTrailingMinusNumbers = True
        .Refresh BackgroundQuery:=False
    End With

End Sub

欢迎使用SuperUser,而不是添加新答案,您应该已经编辑了Corbett的答案并对其进行了改进。我知道您还没有足够的声誉来做到这一点,但是您可以在您要求他阅读的评论中链接您的更改。
VlastimilOvčáčík2015年

0

如果您始终导入相同的数据(恒定记录格式,布局等),则可以使用导入规范编写一个Access宏,然后将数据转储回Excel。这样做可能会倍。我做过的另一种方法是使用VBA并将数据一次读入工作表中的一条记录,并在读取时将其解析出来。据我所知,无法在Excel导入期间设置默认格式,即使您可能会在尝试解析的下一个文件类型上引起问题。


1
事情是这样的-除了在导入时将逗号之间的文本字符串放入列中之外,我没有尝试进行任何解析。如果我需要以某种方式对其进行格式化,则可以执行此操作(例如,使日期字符串成为日期等),但是最初只需要保留数据。为什么要这么难?
威廉·冈恩

0

根据要求,提交我的评论作为答案(添加了更多信息):

嘿Scripting Guy撰写了一篇有关将CSV导入Excel的博客文章,该文章可能对您有用。在Powershell中使用数据对象可以使您做自己想做的事情。

尽管本文专门提到将数据导入可能会保留数字格式的单元格中,但是可以尝试使用一些Excel ComObject属性和方法来强制数据以原始文本的形式输入单元格(或强制在导入之前或之后将单元格格式化为文本)。


0

由于未知的原因,即使文件扩展名是CSV,即使您显式提供所有列的格式,Excel也会忽略它。

一些选项:

  • 按照Wetmelon的建议创建一个查询以导入数据。
    缺点:您可能在64位计算机上缺少CSV数据库驱动程序。

  • 使用Jean的代码,但包括将文件复制到临时文件夹并更改副本的扩展名。
    缺点:没有链接到原始文件(保存将覆盖副本);您之后必须手动删除副本。不过,您可以手动将另存为另存为原始CSV。

  • 在记事本中打开CSV, ,Ctrl+ACtrl+C粘贴到Excel中,然后数据-文本分列,那么这是通常的向导,您可以设置所有列一气呵成为文本。它与以前的选项有所不同,因为它还隐藏了Excel中的宝贵扩展名。
    缺点:手动。

  • 有一个非常简单的VBA循环,该循环将整个文件读入内存,并将其逐个单元地放到工作表上。
    缺点:速度较慢,难看。


所有这些方法的缺点是“没有链接到原始[CSV]文件”不是一个缺点吗?我喜欢复制到临时文件夹并在其中更改扩展名的想法...打开副本后,甚至可以覆盖原始文件(CSV格式)。
让·弗朗索瓦·科贝特

@Jean-FrançoisCorbett,我一直使用导入向导将扩展名为csv的 .csv文件导入Excel2010 。我将列的格式明确指定为Text,并将单元格格式保留为text。也许这是旧版Excel的问题?
GlennFromIowa'3

-2

如果我理解正确的问题,这是使用粘贴,特别是描述的移调选项迎刃而解这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.