【问题标题】:Excel Split Single Column Into Multiple Columns Based on Header RowsExcel根据标题行将单列拆分为多列
【发布时间】:2017-09-16 01:35:06
【问题描述】:

我有一个 Excel 文件,其中包含从 LTSpice 模拟导出的数据。有 280 次不同的运行,但是数据导出为两列(时间和电压),在新运行开始时有一个运行单元格。每次运行中的数据点数量各不相同。看起来像这样:

Run 1/280
Time1        Voltage1
Time2        Voltage2
Run 2/280
Time1        Voltage1
Time2        Voltage2
Time3        Voltage3
Run 3/280

我希望将运行单元格作为行,并将时间和电压列放在它们下方。

Run 1/280                Run 2/280                Run 3/280
Time1        Voltage1    Time1        Voltage1
Time2        Voltage2    Time2        Voltage2
                         Time3        Voltage3

我还没有找到一个简单的方法来做到这一点,所以任何帮助将不胜感激。

谢谢

【问题讨论】:

    标签: excel split multiple-columns


    【解决方案1】:

    没有 VBA...

    对于输入列表的每一行,您需要确定其类型(Run x/xxx 标头或 terminal, voltage 对)以及该输入行所属的输出中的行和列对。

    在下图中,AB 列执行此任务。列 A 标识输出列对,B 标识输出行,其中第 0 行表示输出的标题行。

    输出的标题行利用了这样一个事实,即如果 array 按升序排序并且具有重复值,则 MATCH(x,array,0) 会找到 arrayfirst 元素的索引等于到 x。由于以下原因,需要在其他行的公式中重复繁琐的 SUMPRODUCT 术语。如果在AB 列中没有与当前输出行和列对号匹配的对,则SUMPRODUCT 提供0,不幸的是,INDEX(array,SUMPRODUCT()) 术语计算为INDEX(array,0),它提供第一个元素array (*) - 这不是我们想要的。

    您显然需要在输出区域的工作表的row 1column E 中有足够的辅助值——BA 列的最大值分别确定了要求。输出过大(如图所示)不是问题,因为任何冗余位置的公式都只会计算为""

    (*) 实际上,对于单个列 array,公式 =INDEX(array,0) 的计算结果为 array 本身。当用作单元格公式(而不是用作跨单元格区域的数组公式)时,公式只是从array 中选择第一个值。

    【讨论】:

      【解决方案2】:

      请试试这个代码。

      Sub SplitToColumns()
          ' 16 Sep 2017
      
          Dim WsS As Worksheet                    ' S = "Source"
          Dim WsD As Worksheet                    ' D = "Destination"
          Dim WsDName As String
          Dim RunId As String                     ' first word in "Run 1/280"
          Dim RowId As Variant                    ' value in WsS.Column(A)
          Dim Rl As Long                          ' last row (WsS)
          Dim Rs As Long, Rd As Long              ' row numbers
          Dim Cd As Long                          ' column (WsD)
      
          WsDName = "RemoteMan"                   ' change to a valid tab name
          Application.ScreenUpdating = False
          On Error Resume Next
          Set WsD = Worksheets(WsDName)
          If Err Then
              ' create WsD if it doesn't exist:
              Set WsD = Worksheets.Add(After:=Worksheets(Worksheets.Count))
              WsD.Name = WsDName
              Cd = -1
          Else
              ' continue adding new data to the right of existing,
              With WsD.UsedRange
                  Cd = .Columns.Count - 1
                  If Cd = 1 And .Rows.Count = 1 Then Cd = -1
              End With
          End If
      
          Set WsS = Worksheets("Remote")          ' change to a valid tab name
          With WsS
              ' presume "Run" & Time in column A, Voltage in Column B
              ' presume: no blank rows
              Rl = .Cells(Rows.Count, "A").End(xlUp).Row
              RunId = .Cells(2, 1).Value          ' row 2 must have the RunId
              RunId = Left(RunId, InStr(RunId, " ") - 1)
              For Rs = 2 To Rl                    ' assume data start in row 2 (A1 may not be blank!)
                  RowId = .Cells(Rs, "A").Value
                  If InStr(1, RowId, RunId, vbTextCompare) = 1 Then
                      Rd = 1                      ' first row to use in WsD
                      Cd = Cd + 2                 ' determine next columns
                  End If
                  WsD.Cells(Rd, Cd).Value = RowId
                  WsD.Cells(Rd, Cd + 1).Value = .Cells(Rs, "B").Value
                  Rd = Rd + 1                     ' next row to use
              Next Rs
          End With
          Application.ScreenUpdating = True
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多