3

我试图导入的制表符分隔的文本文件看起来像这样(4 个字段,字段 3 是多行)......以及大约 100,000 行数据:

下面只是一个示例......但请给出一个通用解决方案,其中多行文本可能位于多个字段中......比如总共 10 个字段中的 fld3、fld6 和 fld7。

Field 1 <tab> Field 2 <tab> Field 3.1
Field 3.2
Field 3.3<tab>Field 4
Field 1 <tab> Field 2 <tab> Field 3.1
Field 3.2
Field 3.3<tab>Field 4
Field 1 <tab> Field 2 <tab> Field 3.1
Field 3.2
Field 3.3<tab>Field 4

但是,实际上当它从数据库导出到上述文本文件时......它有 3 行实际......看起来像这样...... 4 个字段。字段 3 是多行的。

Field 1 <tab> Field 2 <tab> Field 3.1(CR)Field 3.2(CR)Field 3.3<tab>Field 4
Field 1 <tab> Field 2 <tab> Field 3.1(CR)Field 3.2(CR)Field 3.3<tab>Field 4
Field 1 <tab> Field 2 <tab> Field 3.1(CR)Field 3.2(CR)Field 3.3<tab>Field 4

其中是 Tab,(CR) 是回车。将制表符分隔的文本文件导入 Excel 时,我希望字段 3(字段 3.1、字段 3.2 和字段 3.3)中的所有 3 行都在一个单元格中,但多行。所以基本上我希望excel忽略字段3中的回车。我该怎么做???

供您参考...文本字段不在双引号中...请告诉我将纯文本制表符分隔的文本文件转换为 Excel 4 列的最佳方法是这样的:

Excel文件

有谁知道解决方案。这将不胜感激。

附加评论

请注意,我所拥有的只是生成的文本文件...如此消息的最顶部所示...。第 2 行中的文本为“字段 3.2”,第 3 行中的文本为“字段 3.3”和“字段 4”将它们分开。

另外...不一定字段 3 将始终是多行的...它可能是具有 2、3 或更多行的多行...甚至没有或单行。字段 3 本身永远不会有 with。

带有样本文件的附加评论供某人测试 - 更新 25Jun2013 09:05 UTC

请注意复制粘贴不起作用..因为标签丢失..您必须自己添加。

多行字段周围带有引号的文件:

f1hdr   f2hdr   f3hdr
f11 "f12
part of f12"    f13
f21 "f22part of f22
part f22
part f22
part f22"   f23
f31 "f32aaa"    f33
f41 "f42bbb"    f43

多行字段周围没有引号的文件:

f1hdr   f2hdr   f3hdr
f11 f12
part of f12 f13
f21 f22part of f22
part f22
part f22
part f22    f23
f31 f32aaa  f33
f41 f42bbb  f43

在 Excel 中打开带引号的文件...打开文件对话框...按住 Shift...并单击打开...用多行很好地显示文件。

用引号捕获 2

但是打开不带引号的文件..不起作用..它会中断。

我不知道为什么轮班工作。我从这里知道这一点:Import multiline csv files into Excel international

现在..还有待回答...

1) 在导入 Excel 之前,如何以更简单的方式在文本文件周围添加引号... 为什么 Shift Open 有效?如果我想使用文本导入向导控制每个分隔列怎么办?

2)如何在SQL Server 2015中默认在字段周围添加引号。这是对上面Q1的补充。我们仍然需要一个无法再次导出文件的解决方案。但是,对于任何新的出口......有人可以使用第二季度的答案。

3)还有其他更简单的方法吗?

4

3 回答 3

3

这就是我想出的。如果您可以保证最后一列永远不会有回车,那么这应该可以。

这样做是读取 VBA 中的文本文件并将其带入工作簿。您必须指定期望的字段数(在测试场景中为 4)。这样它就可以跟踪何时准备好开始新行。

由于回车,这有点令人困惑,但是单步执行代码,我认为您将能够弄清楚。如果您有任何问题,请告诉我。

Option Explicit

Const fieldCount = 4

Sub import()
    Application.ScreenUpdating = False

    Dim fileNumber As Integer
    Dim data As String
    Dim curCol As Long, curRow As Long
    Dim dataCols As Long
    Dim i As Long
    Dim sh As Excel.Worksheet
    Dim arr() As String
    Dim hasCarriageReturn As Boolean

    fileNumber = FreeFile()
    Open "C:\test.txt" For Input As #fileNumber
    curCol = 1
    curRow = 1
    Set sh = ThisWorkbook.Worksheets("Sheet1")

    While Not EOF(fileNumber)
        ' if we reached the "correct" last column, then move to next row
        If (curCol > fieldCount) Then
            curCol = 1
            curRow = curRow + 1
            hasCarriageReturn = False
        End If

        Line Input #fileNumber, data
        arr = Split(data, vbTab)
        dataCols = UBound(arr)



        If (dataCols = fieldCount - 1) Then
            ' full row has no carriage returns
            hasCarriageReturn = False

            For i = 0 To dataCols
                sh.Cells(curRow, curCol).Value = arr(i)
                curCol = curCol + 1
            Next

        ElseIf (dataCols = 0 And hasCarriageReturn = True) Then
            ' if there is only 1 value in the row, append it to the current column
            sh.Cells(curRow, curCol - 1).Formula = sh.Cells(curRow, curCol - 1).Formula & Chr(10) & arr(0)

        ElseIf (dataCols = 0 And hasCarriageReturn = False) Then
            ' carriage return begins in the first field
            sh.Cells(curRow, curCol).Formula = sh.Cells(curRow, curCol).Formula & Chr(10) & arr(0)
            curCol = curCol + 1
            hasCarriageReturn = True

        ElseIf (hasCarriageReturn) Then
            ' append first item to field 3, then rest goes in other columns
            sh.Cells(curRow, curCol - 1).Formula = sh.Cells(curRow, curCol - 1).Formula & Chr(10) & arr(0)
            For i = 1 To dataCols
                sh.Cells(curRow, curCol).Value = arr(i)
                curCol = curCol + 1
            Next

            hasCarriageReturn = False

        Else
            ' process row and note that it has carriage returns
            For i = 0 To dataCols
                sh.Cells(curRow, curCol).Value = arr(i)
                curCol = curCol + 1
            Next

            hasCarriageReturn = True
        End If

    Wend

    Application.ScreenUpdating = True
End Sub
于 2013-06-24T13:59:37.027 回答
2

暂时我所做的是..使用gvim(与'vi'相同)并替换了所有

\twith "\t" (这是用引号括起来的字段..然后..例如:%s/\t/"\t"/g

\r\nwith "\r (这是真正的行尾有一个引号......然后例如:%s/\r\n/"\r/g

行开头^20^"20 这是引号中第一个字段的开头...该行以 2013 开头...所以替换为“2013...”)例如:%s/^2013/"2013/g

保存文件.. 为 file.txt

打开 Excel

选择文件...并按住 shift 并单击“打开”(由:Import multiline csv files into Excel international提供)

所有字段都很好地导入(以通用格式),并且多行被正确处理并放入正确的字段中。

这真是太棒了......但是有一个警告。

有些字段是文本,但带有前导 0.. 例如'000327511''032'.. 我希望前导零完好无损.. 无需 excel 转换为数字。我无法使用“shift + open”方法保留前导 0。

如果我使用普通的文本导入向导......那么多行将无法工作......捕捉 22 的情况。遗憾!!!

但是..这是一个很好的临时解决方案,直到有人可以找到永久修复所有一个。完全不涉及代码...只需键入几下即可替换为 vi 并单击...单击..

希望有人可以稍微改进这种方法。

于 2013-06-25T15:11:05.257 回答
0

导入 Libre Office Calc。Libre Office Calc 不会将两个选项卡之间的换行符解释为下一行命令。换行后的内容将出现在同一单元格内的下一行。将电子表格保存为 ms excel xls/xlsx 格式。忽略在保存之前弹出的警告,风险自负和/或在导入后校对相同的电子表格。在校对期间,请确保您使用的是 Excel。

于 2015-03-15T14:48:08.520 回答