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