vba 以相同格式将excel文件导出到txt

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19273014/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-11 23:43:52  来源:igfitidea点击:

Export an excel file to txt with same formatting

excelexcel-vbatextformattingvba

提问by David_D

I have an excel file written in this way:

我有一个这样写的excel文件:

187712  201    37     0.18   
2525    580    149    0.25   
136829  137    43     0.31

I need to export this file with same spaces, same formatting in a txt file. How can i do it? I've tryied Save As | Formatted Text (Space Delimited) (*.prn)but not working because i have an issue on the last column. Is there a macro? Thanks.

我需要在txt文件中使用相同的空格和相同的格式导出此文件。我该怎么做?我已经尝试过Save As | Formatted Text (Space Delimited) (*.prn)但没有工作,因为我在最后一栏有问题。有宏吗 谢谢。

EDIT: i tryied a macro:

编辑:我尝试了一个宏:

Sub TEST()
    Dim c As Range, r As Range
    Dim output As String
    For Each r In Range("A1:L504").Rows
        For Each c In r.Cells
            output = output & " " & c.Value
        Next c
        output = output & vbNewLine
    Next r
    Open "D:\MyPath\text.txt" For Output As #1
    Print #1, output
    Close
End Sub

but the result is

但结果是

187712  201    37     0.18   
2525 580  149    0.25   
136829  137    43     0.31

These values are only an example because there are about 504 columns!! Anyway the problem is that if in the first column there is a value shorter then the others it lost the formatting like the second row as you can see.

这些值只是一个例子,因为大约有 504 列!!无论如何,问题是,如果在第一列中有一个较短的值,那么其他列就会丢失格式,如您所见,第二行。

回答by JayRO-GreyBeard

I struggled with that also numerous times, the only way I found was with a VBA function I created (the tricky part is determining the "widest" column for plain-text layout). Fair warning: I didn't build a lot "smarts" into this, the output can be a little quirky.

我也为此挣扎了很多次,我发现的唯一方法是使用我创建的 VBA 函数(棘手的部分是确定纯文本布局的“最宽”列)。公平警告:我没有在其中构建很多“智能”,输出可能有点古怪。

Usage: Select the cells you want formatted to plain-text, then run the macro (I have the macro assigned to a button, I use it all the time!). If the top row is center-aligned, then let's /assume/ it's a header. And watch for right-aligned columns, and output those right-aligned.

用法:选择要格式化为纯文本格式的单元格,然后运行宏(我将宏分配给了一个按钮,我一直在使用它!)。如果顶行居中对齐,那么让我们/假设/它是一个标题。并注意右对齐的列,并输出那些右对齐的列。

The marco will copy the desired output to the clip-board, then paste the result in Notepad (or similar) to do with as desired.

marco 会将所需的输出复制到剪贴板,然后将结果粘贴到记事本(或类似工具)中以根据需要进行处理。

Example output (I threw in some headers)

示例输出(我加入了一些标题)

CustId  Views  Selected  Cost
187712    201        37  0.18
  2525    580       149  0.25
136829    137        43  0.31

The code:

编码:

Sub FormatSelectionToPlainText()
  ' ---------------------------------------------------------------------------
  ' Author: Jay R. Ohman
  ' Ohman Automation Corp., http://www.OhmanCorp.com
  ' ** disclaimer and release: I am NOT an expert  **
  ' ** programmer, use my coding at your own risk! **
  ' ---------------------------------------------------------------------------
  Dim rFound As Range, RngCol1 As Integer, RngRow1 As Integer, ActCol As Integer, ActRow As Integer, x As Integer
  Dim MaxCellLen() As Variant, CellAlignRight() As Variant, HdrLen() As Variant, xDbg As Boolean, xVal As Variant
  Dim SepSpace As Integer, RetStr As String, RetLen As Integer, MsgStr As String, HasHdr As Boolean
  Dim GeneralIsRightAlignedFactor As Single, TotalRows As Integer
  Dim oClip As DataObject

  xDbg = True                                                        ' output stuff to the immediate window?
  GeneralIsRightAlignedFactor = 0.75                                 ' threshhold for deeming a column as right-aligned
  Set oClip = New DataObject
  MsgStr = "(looking for top row to be center aligned as header)"
  If MsgBox("Are the cells to be copied selected?" & vbCrLf & MsgStr, vbYesNo + vbQuestion, "Auto-Fill Time Slots") = vbYes Then
    If (Selection Is Nothing) Then
      MsgBox "Nothing Selected."
    Else
      SepSpace = 2                                                   ' number of spaces between columns
      RetLen = 0
      HasHdr = True
      Set rFound = Selection
      RngCol1 = rFound.Column
      RngRow1 = rFound.Row
      Debug.Print Selection.Columns.Count
      ReDim Preserve MaxCellLen(Selection.Columns.Count)             ' max cell length
      ReDim Preserve CellAlignRight(Selection.Columns.Count)         ' track the cell alignment
      ReDim Preserve HdrLen(Selection.Columns.Count)                 ' header row max cell length
      For ActCol = RngCol1 To RngCol1 + Selection.Columns.Count - 1
        x = (ActCol - RngCol1 + 1)
        ' If xDbg Then Debug.Print Cells(RngRow1, ActCol).HorizontalAlignment
        If (Cells(RngRow1, ActCol).HorizontalAlignment <> xlCenter) And (Cells(RngRow1, ActCol).Value <> "") Then HasHdr = False
        HdrLen(x) = IIf(HasHdr, Len(Cells(RngRow1, ActCol).Value), 0)
        MaxCellLen(x) = 0
        CellAlignRight(x) = 0
      Next
      If xDbg Then Debug.Print "HasHdr: " & HasHdr
      TotalRows = (RngRow1 + Selection.Rows.Count) - (RngRow1 + IIf(HasHdr, 1, 0))
      For ActCol = RngCol1 To RngCol1 + Selection.Columns.Count - 1  ' go find the longest text in each column
        x = (ActCol - RngCol1 + 1)
        xVal = IIf(HasHdr, 1, 0)
        For ActRow = RngRow1 + xVal To RngRow1 + Selection.Rows.Count - 1
          ' If xDbg Then Debug.Print Cells(ActRow, ActCol).HorizontalAlignment
          xVal = Cells(ActRow, ActCol).Value
          If (MaxCellLen(x) < Len(Cells(ActRow, ActCol).Value)) Then MaxCellLen(x) = Len(xVal)
          If (Cells(ActRow, ActCol).HorizontalAlignment = xlRight) Or _
              ((Cells(ActRow, ActCol).HorizontalAlignment = xlGeneral) And (IsDate(xVal) Or IsNumeric(xVal))) Then _
                  CellAlignRight(x) = CellAlignRight(x) + 1
        Next
        If xDbg Then Debug.Print "Max Length for Column " & ActCol & ": " & MaxCellLen(x) & _
            ", CellAlignRight.Count: " & CellAlignRight(x) & "/" & TotalRows
        RetLen = RetLen + MaxCellLen(x) + SepSpace
      Next
      RetLen = RetLen - SepSpace                                     ' subtract that last separator space
      If HasHdr Then
        For ActCol = RngCol1 To RngCol1 + Selection.Columns.Count - 1
          x = (ActCol - RngCol1 + 1)
          If (HdrLen(x) > MaxCellLen(x)) Then MaxCellLen(x) = HdrLen(x)
        Next
      End If
      RetStr = ""                                                    ' build the output text
      For ActRow = RngRow1 To RngRow1 + Selection.Rows.Count - 1
        For ActCol = RngCol1 To RngCol1 + Selection.Columns.Count - 1
          x = (ActCol - RngCol1 + 1)
          MsgStr = Cells(ActRow, ActCol).Value                       ' re-use string variable
                                                                     ' format for right-aligned
          If (CellAlignRight(x) / TotalRows >= GeneralIsRightAlignedFactor) And (Not (HasHdr And (ActRow = 1))) Or (Cells(ActRow, ActCol).HorizontalAlignment = xlRight) Then    ' aligned right
            RetStr = RetStr & Space(MaxCellLen(x) - Len(MsgStr)) & MsgStr
          ElseIf (Cells(ActRow, ActCol).HorizontalAlignment = xlCenter) Then
            xVal = Fix((MaxCellLen(x) - Len(MsgStr)) / 2)
            RetStr = RetStr & Space(xVal) & MsgStr & Space(MaxCellLen(x) - Len(MsgStr) - xVal)
          Else
            RetStr = RetStr & MsgStr & Space(MaxCellLen(x) - Len(MsgStr))
          End If
          If ((ActCol - RngCol1) + 1 < UBound(MaxCellLen)) Then RetStr = RetStr & Space(SepSpace)
        Next
        RetStr = RetStr & vbCrLf
      Next
      oClip.SetText RetStr
      oClip.PutInClipboard
      MsgBox ("The selection has been copied to clipboard." & vbCrLf & "Max line length: " & RetLen)
    End If
  Else
    MsgBox ("Have a nice day. :)")
  End If
End Sub

回答by Gary's Student

Your posted data shows fixed fields with field-widths of 8,7,7,4 (each field is a combination of characters and trailing blanks). These can be adjusted as necessary in the macro below. Also adjust the folder name to suit your needs:

您发布的数据显示了字段宽度为 8、7、7、4 的固定字段(每个字段都是字符和尾随空格的组合)。这些可以根据需要在下面的宏中进行调整。还要调整文件夹名称以满足您的需要:

Sub FixedField()

    Dim fld(1 To 4) As Long
    Dim V(1 To 4) As String
    Dim N As Long, L As Long
    Dim K As Long

    fld(1) = 8
    fld(2) = 7
    fld(3) = 7
    fld(4) = 4
    N = Cells(Rows.Count, "A").End(xlUp).Row
    Close #1
    Open "c:\TestFolder\test.txt" For Output As #1

    For L = 1 To N
        outpt = ""
        For K = 1 To 4
            V(K) = Cells(L, K).Text
            While Len(V(K)) <> fld(K)
                V(K) = V(K) & " "
            Wend
            outpt = outpt & V(K)
        Next K
        MsgBox outpt
        Print #1, outpt
    Next L
    Close #1
End Sub

It is also assumed that the data starts in column A.

还假设数据从 A 列开始。