【问题标题】:Excel VBA Import TXT File with variable Column widthExcel VBA 导入具有可变列宽的文本文件
【发布时间】:2012-08-03 17:01:29
【问题描述】:

我在通过 VBA 将固定文件 (TXT) 导入 Excel 时遇到了挑战。问题并不是真正将数据导入 Excel(代码如下),而是根据 TXT 文件的列内容更改列宽。

非常感谢任何帮助!

例子:

txt文件的内容是:

  FirstC        SecondC           ThirdC
A             111122223333      444455556666
B             111122223333      444455556666
A             111122223333      444455556666
A             111122223333      444455556666
B             111122223333      444455556666

根据第一列 (FirstC) 的内容,Excel 中的导入列宽应更改,即对于 A,第二列 (SecondC) 的列宽应为 8 位,如果是 B,则应为 10数字

导入代码(不是专业的,如果代码有点乱,请见谅):

    Sub Button1_Click()

Dim vPath As Variant

vPath = Application.GetOpenFilename("TextFiles (*.txt), *.txt", , "TEST TEXT IMPORTER:")
If vPath = False Then Exit Sub
Filename = vPath
Debug.Print vPath

Worksheets("IMPORT").UsedRange.ClearContents


With Sheets("IMPORT").QueryTables.Add(Connection:="TEXT;" & CStr(vPath), Destination:=Sheets("IMPORT").Range("A2"))
       .FieldNames = True
       .RowNumbers = False
       .FillAdjacentFormulas = False
       .PreserveFormatting = True
       .RefreshOnFileOpen = False
       .RefreshStyle = xlInsertDeleteCells
       .SavePassword = False
       .SaveData = True
       .AdjustColumnWidth = True
       .RefreshPeriod = 0
       .TextFilePromptOnRefresh = False
       .TextFilePlatform = xlWindows
       .TextFileStartRow = 1
       .TextFileParseType = xlFixedWidth
       .TextFileTextQualifier = xlTextQualifierDoubleQuote
       .TextFileConsecutiveDelimiter = False
       .TextFileTabDelimiter = False
       .TextFileSemicolonDelimiter = False
       .TextFileCommaDelimiter = False
       .TextFileSpaceDelimiter = False
       .TextFileColumnDataTypes = Array(2, 2, 2)
       .TextFileFixedColumnWidths = Array(14, 18, 12)  
       .TextFileFixedColumnWidths = Array(14, 18, 12)    '<-- That’s where  I need to be flexible
       .TextFileTrailingMinusNumbers = True
       .Refresh BackgroundQuery:=False

   End With


End Sub

在我的代码下面进行了一些修改,除了第四列没有显示之外它可以工作。 实际上将添加更多列,因此很高兴看到我必须在哪里调整代码以便灵活使用列。任何想法?提前致谢

文本文件(只有2行,以后会更多)看起来像这样:

0000000002666980001F2002
0000000002666980002G1020709500430120101L05200000000000000000000

编码:

Sub Button1_Click()


    Const fPath As String = "H:\MyDocs\xxxxx\TestFiles6.txt"
    Const fsoForReading = 1
    Const F1_LEN As Integer = 15    'Reference Number
    Const F2_LEN As Integer = 4     'Cosectuive Number
    Const F3_LEN As Integer = 1     'Record Type
    Const F4_Len As Integer = 4     'Company Number

    Dim objFSO As Object
    Dim objTextStream As Object
    Dim start As Integer
    Dim fLen As Integer
    Dim rw As Long

    Set objFSO = CreateObject("scripting.filesystemobject")
    Set objTextStream = objFSO.OpenTextFile(fPath, fsoForReading)
    rw = 2

    Do Until objTextStream.AtEndOfStream
        txt = objTextStream.Readline


        f1 = Trim(Left(txt, F1_LEN))
   '------------------------------------------------------------------------------------------------------------
        start = F1_LEN + 1
        f2 = Trim(Mid(txt, start, F2_LEN))
   '------------------------------------------------------------------------------------------------------------
        start = F1_LEN + F2_LEN + 1
        f3 = Trim(Mid(txt, start, F3_LEN))

        If f3 = "F" Then
            fLen = 4
        ElseIf f3 = "G" Then
            fLen = 50
        Else

        End If

        Debug.Print start
    '------------------------------------------------------------------------------------------------------------
        start = start + 1
        f4 = Trim(Mid(txt, start, fLen))
        Debug.Print f4
    '------------------------------------------------------------------------------------------------------------
        ThisWorkbook.Sheets("data").Cells(rw, 1).Resize(1, 3).Value = Array(f1, f2, f3, f4)
        rw = rw + 1
    Loop

    objTextStream.Close

结束子

【问题讨论】:

  • 要在单次导入中处理此问题,您需要“手动”逐行读取文件并检查第一列以了解如何处理接下来的列。或者您可以运行您拥有的代码两次 - 第一次使用 setting1(然后删除任何“B”行),然后再次使用 setting2(删除任何“A”行)。
  • 您是否尝试过使用空格/制表符分隔符(将连续的分隔符视为一个分隔符)?您可能会发现您的列标题被推到右侧一列,但您可以使用 VBA 轻松地将它们剪切+粘贴到一个单元格上。
  • 所有,非常感谢您的反馈。 Zairja:源文件是一个固定的witdh文件,所以我不能改变它(它来自我们的ERP系统)。 @Tim Williams:我认为逐行阅读会是一个解决方案,但不幸的是我仍在学习,所以任何代码示例都会非常有帮助:)

标签: excel import fixed fixed-width vba


【解决方案1】:

未经测试:

Sub Tester()

    Const fPath As String = "C:\SomeFile.txt"
    Const fsoForReading = 1
    Const F1_LEN As Integer = 14
    Const F2_LEN_A As Integer = 8
    Const F2_LEN_B As Integer = 10
    Const F3_LEN As Integer = 14

    Dim objFSO As Object, objTextStream As Object, txt, f1, f2, f3
    Dim start As Integer, fLen As Integer
    Dim rw As Long

    Set objFSO = CreateObject("scripting.filesystemobject")
    Set objTextStream = objFSO.OpenTextFile(fPath, fsoForReading)
    rw = 2

    Do Until objTextStream.AtEndOfStream
        txt = objTextStream.Readline


        f1 = Trim(Left(txt, F1_LEN))
        start = F1_LEN + 1

        If f1 = "A" Then
            fLen = 8
        ElseIf f1 = "B" Then
            fLen = 10
        Else
            'what if?
        End If

        f2 = Trim(Mid(txt, start, fLen))
        start = start + fLen + 1
        f3 = Trim(Mid(txt, start, F3_LEN))

        With ThisWorkbook.Sheets("data").Cells(rw, 1).Resize(1, 3)
            .NumberFormat = "@" 'format cells as text 
            .Value = Array(f1, f2, f3)
            'alternatively.....
            '.cells(1).Value = f1
            '.cells(3).Value = f3
        End With
        rw = rw + 1
    Loop

    objTextStream.Close
End Sub

【讨论】:

  • 谢谢,这在第一次开始时确实有效。在接下来的 2 天内,我将对其进行更详细的测试,如果一切顺利,我会报告。到目前为止,非常感谢和竖起大拇指!
  • 添加了我修改后的代码,但仍然需要一些帮助。非常感谢提前
  • 最后一个问题:据我所知,数组填充了所有值,并且还描述了粘贴值的 Excel 单元格。如何仅将值粘贴到某些单元格中并保留单元格中已经存在的原始内容?示例: .Value = Array(f1, , f3) 其中缺少的 f2 表示 Excel 工作表中的一个单元格,该单元格已被填充,应该保持原样
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-17
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
相关资源
最近更新 更多