是否可以直接在Excel中打开带有逗号和分号(以分号为分隔符)的CSv / Txt文件,然后将其保存回去而不会变形?

时间:2019-02-15 04:31:30

标签: excel vba csv text

这是参考我对@Drzemlik发表的帖子macro separates .csv by comma, despite separator set to semicolon和后续帖子Saving .txt as .csv cancels all changes made by macro in the file. How to prevent it?的答复。在准备答案的过程中,一开始就被认为是一些已经投反对票的简单解决方案,但发现问题值得我们赏金吗?

在我的试用版中,我发现在从excel保存以分号分隔的txt / csv文件时,它可能会在保存的文件中引入一些双引号(取决于逗号,空格,双引号和分号在一行中的位置)。可以引用链接Saving a Excel File into .txt format without quoteslink1link2

但是,我对使用I / O模式中的Open语句打开Csv / Txt文件并重命名的解决方法完全不满意。我仍然相信我错过了一些东西,并且必须有简单直接的方法只能在excel中打开和保存文件。

  1. 涉及的文本文件应包含逗号,空格,双引号和分号,而分号应视为定界符。

  2. 文件可使用‘OpenText or TextToColumns`直接在excel中打开,或者类似地,对列执行一些简单的截断操作(例如col 2),然后直接从excel保存。

  3. 任务可以尽可能简单地执行。最可取的是使用我错过的OpenText和/或saveAs的一些参数/调整。进程应没有文件内容操纵和引入的双引号的查找替换类型。

  4. 最后,最具挑战性的是打开扩展名为.csv的文件,而直接保存扩展名为.csv的文件将是一个荣誉。

我不会复制任何代码(所有代码都在提供的链接中),而是提供示例文件文本以便于试用。

Ln,1  "AND" Col,1;  Ln,1  "AND" Col,2;  Ln,1  "AND" Col,3;  Ln,1  "AND" Col,4;  Ln,1  "AND" Col,5;  Ln,1  "AND" Col,6;  Ln,1  "AND" Col,7;  Ln,1  "AND" Col,8;
Ln,2  "AND" Col,1;  Ln,2  "AND" Col,2;  Ln,2  "AND" Col,3;  Ln,2  "AND" Col,4;  Ln,2  "AND" Col,5;  Ln,2  "AND" Col,6;  Ln,2  "AND" Col,7;  Ln,2  "AND" Col,8;
Ln,3  "AND" Col,1;  Ln,3  "AND" Col,2;  Ln,3  "AND" Col,3;  Ln,3  "AND" Col,4;  Ln,3  "AND" Col,5;  Ln,3  "AND" Col,6;  Ln,3  "AND" Col,7;  Ln,3  "AND" Col,8;
Ln,4  "AND" Col,1;  Ln,4  "AND" Col,2;  Ln,4  "AND" Col,3;  Ln,4  "AND" Col,4;  Ln,4  "AND" Col,5;  Ln,4  "AND" Col,6;  Ln,4  "AND" Col,7;  Ln,4  "AND" Col,8;
Ln,5  "AND" Col,1;  Ln,5  "AND" Col,2;  Ln,5  "AND" Col,3;  Ln,5  "AND" Col,4;  Ln,5  "AND" Col,5;  Ln,5  "AND" Col,6;  Ln,5  "AND" Col,7;  Ln,5  "AND" Col,8;
Ln,6  "AND" Col,1;  Ln,6  "AND" Col,2;  Ln,6  "AND" Col,3;  Ln,6  "AND" Col,4;  Ln,6  "AND" Col,5;  Ln,6  "AND" Col,6;  Ln,6  "AND" Col,7;  Ln,6  "AND" Col,8;
Ln,7  "AND" Col,1;  Ln,7  "AND" Col,2;  Ln,7  "AND" Col,3;  Ln,7  "AND" Col,4;  Ln,7  "AND" Col,5;  Ln,7  "AND" Col,6;  Ln,7  "AND" Col,7;  Ln,7  "AND" Col,8;
Ln,8  "AND" Col,1;  Ln,8  "AND" Col,2;  Ln,8  "AND" Col,3;  Ln,8  "AND" Col,4;  Ln,8  "AND" Col,5;  Ln,8  "AND" Col,6;  Ln,8  "AND" Col,7;  Ln,8  "AND" Col,8;
Ln,9  "AND" Col,1;  Ln,9  "AND" Col,2;  Ln,9  "AND" Col,3;  Ln,9  "AND" Col,4;  Ln,9  "AND" Col,5;  Ln,9  "AND" Col,6;  Ln,9  "AND" Col,7;  Ln,9  "AND" Col,8;
Ln,10  "AND" Col,1; Ln,10  "AND" Col,2; Ln,10  "AND" Col,3; Ln,10  "AND" Col,4; Ln,10  "AND" Col,5; Ln,10  "AND" Col,6; Ln,10  "AND" Col,7; Ln,10  "AND" Col,8;
Ln,11  "AND" Col,1; Ln,11  "AND" Col,2; Ln,11  "AND" Col,3; Ln,11  "AND" Col,4; Ln,11  "AND" Col,5; Ln,11  "AND" Col,6; Ln,11  "AND" Col,7; Ln,11  "AND" Col,8;
Ln,12  "AND" Col,1; Ln,12  "AND" Col,2; Ln,12  "AND" Col,3; Ln,12  "AND" Col,4; Ln,12  "AND" Col,5; Ln,12  "AND" Col,6; Ln,12  "AND" Col,7; Ln,12  "AND" Col,8;
Ln,13  "AND" Col,1; Ln,13  "AND" Col,2; Ln,13  "AND" Col,3; Ln,13  "AND" Col,4; Ln,13  "AND" Col,5; Ln,13  "AND" Col,6; Ln,13  "AND" Col,7; Ln,13  "AND" Col,8;
Ln,14  "AND" Col,1; Ln,14  "AND" Col,2; Ln,14  "AND" Col,3; Ln,14  "AND" Col,4; Ln,14  "AND" Col,5; Ln,14  "AND" Col,6; Ln,14  "AND" Col,7; Ln,14  "AND" Col,8;

3 个答案:

答案 0 :(得分:0)

这是我最短的方法(既不使用查找/替换也不使用双引号),并在空白的新ActiveSheet上用您的平均CSV示例进行了测试。
第二部分可能不是您想要的方法,但是很简短:

Public Sub DealingMeanCSVexample()
    With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & _
       Application.DefaultFilePath & "\Source.csv", Destination:=Range("$A$1"))
        .TextFileParseType = xlDelimited
        .TextFileTextQualifier = xlTextQualifierDoubleQuote
        .TextFileSemicolonDelimiter = True
        .Refresh
        .Delete
    End With

    Dim r As Long, s As String
    For r = 1 To ActiveSheet.UsedRange.Rows.Count
        s = s & WorksheetFunction.TextJoin(";", True, ActiveSheet.UsedRange.Rows(r)) & ";" & vbCrLf
    Next r
    s = Left(s, Len(s) - 2)

    Dim handle As Long: handle = FreeFile
    Open Application.DefaultFilePath & "\Dest.csv" For Binary As #handle
    Put #handle, , s
    Close #handle
End Sub

由于TextJoin是较新的Excel版本的一部分,因此可以通过以下方式交换循环:

Dim r as long, Dim c As Long
For r = 1 To ActiveSheet.UsedRange.Rows.Count
    For c = 1 To ActiveSheet.UsedRange.Columns.Count
        s = s & ActiveSheet.Cells(r, c).Value & ";"
    Next c
    s = s & vbCrLf
Next r

答案 1 :(得分:0)

让我们先定义

要求:
1.要使用分号字符作为分隔符,直接在excel中打开文本文件。
2.对第2列中的所有值执行截断。
3.使用csv扩展名保存结果数据,同时保持原始布局(例如,用分号而不是逗号分隔的单元格数据,它们的值不能用双引号引起来,并且单元格中任何现有的双引号都不能重复),而不是excel生成的标准csv格式。

此方法将添加一个新工作簿,然后使用QueryTable连接导入CSV文件,在第二列中执行值的截断并使用xlTextPrinter格式保存文件,同时使用csv扩展名,然后关闭用于修改原始文件的工作簿。然后,在记事本中打开结果文件以验证输出布局。

编辑:这是Op所考虑的“最近解决方法”

Sub TEST()
Dim sFilenameSrc As String, sFilenameTrg As String
sFilenameSrc = "D:\@D_Trash\@Csv_Source.csv"    'change as required
sFilenameTrg = "D:\@D_Trash\@Csv_Target.csv"    'change as required

    Call Open_Csv_As_Semicolon_Delimited_Then_Save_As_Csv(sFilenameSrc, sFilenameTrg)

    Rem Open Target with Notepad
    Shell "notepad.exe " & sFilenameTrg, vbNormalFocus

    End Sub


Sub Open_Csv_As_Semicolon_Delimited_Then_Save_As_Csv(sFilenameSrc As String, sFilenameTrg As String)
Dim wb As Workbook
Dim rg As Range, aData As Variant
Dim aValue As Variant, lRow As Long

    Rem Add Workbook
    Set wb = Workbooks.Add(Template:="Workbook")

    Rem Import Csv File
    With wb.Worksheets(1)
        Rem Set qt = .QueryTables.Add(Connection:="TEXT;" & sFilenameSrc, Destination:=.Cells(1))
        With .QueryTables.Add(Connection:="TEXT;" & sFilenameSrc, Destination:=.Cells(1))
            .SaveData = True
            .TextFileParseType = xlDelimited
            .TextFileSemicolonDelimiter = True
            .TextFileTrailingMinusNumbers = True
            .Refresh BackgroundQuery:=False
    End With: End With

    Rem Set Data Range
    Set rg = wb.Worksheets(1).UsedRange

    Rem Truncate 2nd Column
    aData = rg.Columns(2).Value2
    For lRow = 1 To UBound(aData)
        aValue = aData(lRow, 1)
        aValue = Left(aValue, InStrRev(aValue, Chr(34)))
        aData(lRow, 1) = aValue
    Next
    rg.Columns(2).Value2 = aData

    Rem Prepare Data for Save as Csv
    aData = rg.Value2
    rg.ClearContents
    For lRow = 1 To UBound(aData)
        aValue = WorksheetFunction.Index(aData, lRow, 0)
        aValue = Join(aValue, Chr(59)) & Chr(59)
        rg.Cells(lRow, 1).Value2 = aValue
    Next

    rem Save File with csv extension     
    Application.DisplayAlerts = False
    With wb
        .SaveAs Filename:=sFilenameTrg, FileFormat:=xlTextPrinter
        .Close
    End With
    Application.DisplayAlerts = True

    End Sub

答案 2 :(得分:-2)

如果不需要基于VBA /宏的解决方案,以下内容与您的期望有何不同,

  1. 打开新工作簿
  2. 在“数据”选项卡中>在“获取外部数据”组中>单击“来自文本”按钮。

    GetExternalData-FromText

  3. 选择所需的输入文件。

  4. 在“文本导入向导”对话框中,

    第一步:选择“定界”,然后单击“下一步”

    第二步:仅选中“分号”

    semicolondelimit

    步骤3:无需更改,点击“完成”

    点击“确定”

您最好将结果文件保存为“ csv”格式。

干杯!