Excel 如何使用VBA将多列转换为单列?

Excel 如何使用VBA将多列转换为单列?,excel,vba,Excel,Vba,大家好,我如何通过VBA(在单独的表格上)将初始Excel表格转换为最终表格 使用VBA取消PIVOT 我不久前创造了这个怪物(一个正在进行的工作)。这是一种意大利面代码,但它应该适用于您的情况 TESTgetPivot是您运行的。只需将Sheet1和Sheet2更改为工作表名称,并调整第一个单元格A1和A2。但是你不会得到标题 这也可以通过PowerQuery轻松完成(只需点击几下) 代码 Option Explicit Enum RCV RowsColumnsValues =

大家好,我如何通过VBA(在单独的表格上)将初始Excel表格转换为最终表格

使用VBA取消PIVOT
  • 我不久前创造了这个怪物(一个正在进行的工作)。这是一种意大利面代码,但它应该适用于您的情况
  • TESTgetPivot
    是您运行的。只需将
    Sheet1
    Sheet2
    更改为工作表名称,并调整第一个单元格
    A1
    A2
    。但是你不会得到标题
  • 这也可以通过
    PowerQuery
    轻松完成(只需点击几下)
代码

Option Explicit

Enum RCV
    RowsColumnsValues = 1
    RowsValuesColumns
    ColumnsRowsValues
    ColumnsValuesRows
    ValuesRowsColumns
    ValuesColumnsRows
End Enum

Sub TESTgetPivot()
    Dim srcfirst As Range
    Set srcfirst = ThisWorkbook.Worksheets("Sheet1").Range("A1")
    Dim Data As Variant
    Data = getPivot(srcfirst, 2, 1, True, RowsColumnsValues)
    If Not IsEmpty(Data) Then
        With ThisWorkbook.Worksheets("Sheet2").Range("A2")
            '.Worksheet.Cells.ClearContents
            .Resize(UBound(Data, 1), UBound(Data, 2)) = Data
        End With
    Else
        Debug.Print "No Data."
    End If
End Sub

Function getPivot(FirstCell As Range, _
                  Optional ByVal RowLabels As Long = 1, _
                  Optional ByVal ColumnLabels As Long = 1, _
                  Optional ByVal ByColumnLabels As Boolean = False, _
                  Optional ByVal Order As RCV = RCV.RowsColumnsValues) _
         As Variant
    
    ' Initialize error handling.
    
    Const ProcName As String = "getPivot"
    On Error GoTo clearError
    
    ' Validate parameters
    
    If FirstCell Is Nothing Then
        GoTo NoCell
    End If
    If RowLabels < 0 Then
        GoTo RowLabelsNegative
    End If
    If ColumnLabels < 0 Then
        GoTo ColumnLabelsNegative
    End If
    Dim ColRowVal As Variant
    ColRowVal = Array("RCV", "RVC", "CRV", "CVR", "VRC", "VCR")
    Dim CRV As Variant
    CRV = Application.Match(Order, ColRowVal, 0)
    If IsError(CRV) Then
        ColRowVal = Array(1, 2, 3, 4, 5, 6)
        CRV = Application.Match(Order, ColRowVal, 0)
        If IsError(CRV) Then
            GoTo CRVWrongParameter
        End If
    End If
    
    ' Define Source Range.
    
    ' Define Current Region ('rng').
    Dim rng As Range
    Set rng = FirstCell.CurrentRegion
    ' Define End Range ('rng').
    Set rng = FirstCell _
      .Resize(rng.Rows.Count + rng.Row - FirstCell.Row, _
              rng.Columns.Count + rng.Column - FirstCell.Column)
    
    ' Validate parameters.
    
    ' Retrieve Source Rows Count ('srCount').
    Dim srCount As Long
    srCount = rng.Rows.Count
    ' Retrieve Source Columns Count ('scCount').
    Dim scCount As Long
    scCount = rng.Columns.Count
    ' Declare Target Array ('Target').
    Dim Target As Variant
    ' Validate Row Labels and Column Labels.
    If srCount = 1 And scCount = 1 Then
        If RowLabels + ColumnLabels = 0 Then
            ReDim Target(1 To 1, 1 To 1)
            Target(1, 1) = rng.Value
            GoTo writeResult
        Else
            GoTo OneCellOnly
        End If
    End If
    If scCount < RowLabels + 1 Then
        GoTo ColumnsDeficit
    End If
    If srCount < ColumnLabels + 1 Then
        GoTo RowsDeficit
    End If
    
    ' Write values from Source Range to Source Array ('Source').
    
    Dim Source As Variant
    Source = rng.Value
    
    ' Prepare to write values from Source Array to Target Array.
    
    ' Calculate Target Rows Count ('trCount').
    Dim trCount As Long
    trCount = (srCount - ColumnLabels) * (scCount - RowLabels)
    ' Calculate Target Columns Count ('tcCount').
    Dim tcCount As Long
    tcCount = RowLabels + ColumnLabels + 1
    
    ' Define Target Array ('Target').
    'Dim Target As Variant
    ReDim Target(1 To trCount, 1 To tcCount)
    
    ' Declare Counters.
    Dim i As Long ' Source Rows Counter
    Dim j As Long ' Source Columns Counter
    Dim k As Long ' Target Rows Counter
    Dim l As Long ' Target Columns Counter
     
    ' Write values from Source Array to Target Array.
    
    Select Case Order
        Case 1 ' "RCV"
            If Not ByColumnLabels Then
                For i = 1 + ColumnLabels To srCount
                    For j = 1 + RowLabels To scCount
                        k = k + 1
                        For l = 1 To RowLabels
                            Target(k, l) = Source(i, l) ' R
                        Next l
                        For l = l To l + ColumnLabels - 1
                            Target(k, l) = Source(l - RowLabels, j) ' C
                        Next l
                        For l = l To l
                            Target(k, l) = Source(i, j) ' V
                        Next l
                    Next j
                Next i
            Else
                For j = 1 + RowLabels To scCount
                    For i = 1 + ColumnLabels To srCount
                        k = k + 1
                        For l = 1 To RowLabels
                            Target(k, l) = Source(i, l) ' R
                        Next l
                        For l = l To l + ColumnLabels - 1
                            Target(k, l) = Source(l - RowLabels, j) ' C
                        Next l
                        For l = l To l
                            Target(k, l) = Source(i, j) ' V
                        Next l
                    Next i
                Next j
            End If
        Case 2 ' "RVC"
            If Not ByColumnLabels Then
                For i = 1 + ColumnLabels To srCount
                    For j = 1 + RowLabels To scCount
                        k = k + 1
                        For l = 1 To RowLabels
                            Target(k, l) = Source(i, l) ' R
                        Next l
                        For l = l To l
                            Target(k, l) = Source(i, j) ' V
                        Next l
                        For l = l To l + ColumnLabels - 1
                            Target(k, l) = Source(l - RowLabels - 1, j) ' C
                        Next l
                    Next j
                Next i
            Else
                For j = 1 + RowLabels To scCount
                    For i = 1 + ColumnLabels To srCount
                        k = k + 1
                        For l = 1 To RowLabels
                            Target(k, l) = Source(i, l) ' R
                        Next l
                        For l = l To l
                            Target(k, l) = Source(i, j) ' V
                        Next l
                        For l = l To l + ColumnLabels - 1
                            Target(k, l) = Source(l - RowLabels - 1, j) ' C
                        Next l
                    Next i
                Next j
            End If
        Case 3 ' "CRV"
            If Not ByColumnLabels Then
                For i = 1 + ColumnLabels To srCount
                    For j = 1 + RowLabels To scCount
                        k = k + 1
                        For l = 1 To ColumnLabels
                            Target(k, l) = Source(l, j) ' C
                        Next l
                        For l = l To l + RowLabels - 1
                            Target(k, l) = Source(i, l - ColumnLabels) ' R
                        Next l
                        For l = l To l
                            Target(k, l) = Source(i, j) ' V
                        Next l
                    Next j
                Next i
            Else
                For j = 1 + RowLabels To scCount
                    For i = 1 + ColumnLabels To srCount
                        k = k + 1
                        For l = 1 To ColumnLabels
                            Target(k, l) = Source(l, j) ' C
                        Next l
                        For l = l To l + RowLabels - 1
                            Target(k, l) = Source(i, l - ColumnLabels) ' R
                        Next l
                        For l = l To l
                            Target(k, l) = Source(i, j) ' V
                        Next l
                    Next i
                Next j
            End If
        Case 4 ' "CVR"
            If Not ByColumnLabels Then
                For i = 1 + ColumnLabels To srCount
                    For j = 1 + RowLabels To scCount
                        k = k + 1
                        For l = 1 To ColumnLabels
                            Target(k, l) = Source(l, j) ' C
                        Next l
                        For l = l To l
                            Target(k, l) = Source(i, j) ' V
                        Next l
                        For l = l To l + RowLabels - 1
                            Target(k, l) = Source(i, l - ColumnLabels - 1) ' R
                        Next l
                    Next j
                Next i
            Else
                For j = 1 + RowLabels To scCount
                    For i = 1 + ColumnLabels To srCount
                        k = k + 1
                        For l = 1 To ColumnLabels
                            Target(k, l) = Source(l, j) ' C
                        Next l
                        For l = l To l
                            Target(k, l) = Source(i, j) ' V
                        Next l
                        For l = l To l + RowLabels - 1
                            Target(k, l) = Source(i, l - ColumnLabels - 1) ' R
                        Next l
                    Next i
                Next j
            End If
        Case 5 ' "VRC"
            If Not ByColumnLabels Then
                For i = 1 + ColumnLabels To srCount
                    For j = 1 + RowLabels To scCount
                        k = k + 1
                        For l = 1 To 1
                            Target(k, l) = Source(i, j) ' V
                        Next l
                        For l = l To l + RowLabels - 1
                            Target(k, l) = Source(i, l - 1) ' R
                        Next l
                        For l = l To l + ColumnLabels - 1
                            Target(k, l) = Source(l - RowLabels - 1, j) ' C
                        Next l
                    Next j
                Next i
            Else
                For j = 1 + RowLabels To scCount
                    For i = 1 + ColumnLabels To srCount
                        k = k + 1
                        For l = 1 To 1
                            Target(k, l) = Source(i, j) ' V
                        Next l
                        For l = l To l + RowLabels - 1
                            Target(k, l) = Source(i, l - 1) ' R
                        Next l
                        For l = l To l + ColumnLabels - 1
                            Target(k, l) = Source(l - RowLabels - 1, j) ' C
                        Next l
                    Next i
                Next j
            End If
        Case 6 ' "VCR"
            If Not ByColumnLabels Then
                For i = 1 + ColumnLabels To srCount
                    For j = 1 + RowLabels To scCount
                        k = k + 1
                        For l = 1 To 1
                            Target(k, l) = Source(i, j) ' V
                        Next l
                        For l = l To l + ColumnLabels - 1
                            Target(k, l) = Source(l - 1, j) ' C
                        Next l
                        For l = l To l + RowLabels - 1
                            Target(k, l) = Source(i, l - ColumnLabels - 1) ' R
                        Next l
                    Next j
                Next i
            Else
                For j = 1 + RowLabels To scCount
                    For i = 1 + ColumnLabels To srCount
                        k = k + 1
                        For l = 1 To 1
                            Target(k, l) = Source(i, j) ' V
                        Next l
                        For l = l To l + ColumnLabels - 1
                            Target(k, l) = Source(l - 1, j) ' C
                        Next l
                        For l = l To l + RowLabels - 1
                            Target(k, l) = Source(i, l - ColumnLabels - 1) ' R
                        Next l
                    Next i
                Next j
            End If
        ' Not possible
    End Select
        
    ' Write result and exit.
writeResult:
    
    getPivot = Target
    GoTo ProcExit

' Labels

NoCell:
    Debug.Print "'" & ProcName & "': No First Cell Range ('Nothing')."
    GoTo ProcExit

RowLabelsNegative:
    Debug.Print "'" & ProcName & "': Headers Columns can only be 0 or positive."
    GoTo ProcExit

ColumnLabelsNegative:
    Debug.Print "'" & ProcName & "': Headers Rows can only be 0 or positive."
    GoTo ProcExit

CRVWrongParameter:
    Debug.Print "'" & ProcName & "': Order can contain either a combination " _
              & "of the letters ""R"", ""C"" and ""V"" or a number from 1 to 6."
    GoTo ProcExit

OneCellOnly:
    Debug.Print "'" & ProcName & "': There is one cell only."
    GoTo ProcExit

ColumnsDeficit:
    Debug.Print "'" & ProcName & "': Not enough columns."
    GoTo ProcExit

RowsDeficit:
    Debug.Print "'" & ProcName & "': Not enough rows."
    GoTo ProcExit

clearError:
    Debug.Print "'" & ProcName & "': " & vbLf _
              & "    " & "Run-time error '" & Err.Number & "':" & vbLf _
              & "        " & Err.Description
    On Error GoTo 0
    GoTo ProcExit

ProcExit:
    
End Function
选项显式
枚举RCV
RowsColumnsValues=1
行值列
ColumnsRowsValue
列值箭头
ValuesRowsColumns
值列箭头
结束枚举
子TESTgetPivot()
第一个作为范围
Set srcfirst=thishworkbook.Worksheets(“Sheet1”).Range(“A1”)
作为变量的Dim数据
Data=getPivot(srcfirst、2、1、True、RowsColumnsValues)
如果不是空的(数据),那么
使用此工作簿。工作表(“表2”)。范围(“A2”)
'.Worksheet.Cells.ClearContents
.Resize(UBound(数据,1),UBound(数据,2))=数据
以
其他的
调试。打印“无数据”
如果结束
端接头
函数getPivot(第一个单元格作为范围_
可选的ByVal行标签,长度为1_
可选的ByVal列标签,长度为1_
可选的ByVal ByColumnLabels为Boolean=False_
可选的ByVal顺序为RCV=RCV.RowsColumnsValues)_
作为变体
'初始化错误处理。
Const ProcName As String=“getPivot”
关于错误转到clearError
'验证参数
如果FirstCell什么都不是
转到诺塞尔
如果结束
如果行标签<0,则
转到Rowlabels阴性
如果结束
如果ColumnLabels<0,则
GoTo柱状标签阴性
如果结束
Dim ColRowVal作为变体
ColRowVal=数组(“RCV”、“RVC”、“CRV”、“CVR”、“VRC”、“VCR”)
作为变体的Dim-CRV
CRV=Application.Match(订单,ColRowVal,0)
如果是IsError(CRV),则
ColRowVal=数组(1,2,3,4,5,6)
CRV=Application.Match(订单,ColRowVal,0)
如果是IsError(CRV),则
转到CRVWRONG参数
如果结束
如果结束
'定义源范围。
'定义当前区域('rng')。
变暗rng As范围
设置rng=FirstCell.CurrentRegion
'定义结束范围('rng')。
设置rng=FirstCell_
.调整大小(rng.Rows.Count+rng.Row-FirstCell.Row_
rng.Columns.Count+rng.Column-FirstCell.Column)
'验证参数。
'检索源行计数('srCount')。
长度等于
srCount=rng.Rows.Count
'检索源列计数('scCount')。
我认为时间很长
scCount=rng.Columns.Count
'声明目标数组('Target')。
变暗目标
'验证行标签和列标签。
如果srCount=1和scCount=1,则
如果RowLabels+ColumnLabels=0,则
重拨目标(1对1,1对1)
目标(1,1)=平均值
转到writeResult
其他的
只去一家酒店
如果结束
如果结束
如果scCount<行标签+1,则
后藤专栏
如果结束
如果srCount