EXCEL VBA 将多列转换为多行,列与列之间有间隙
EXCEL VBA Transpose multiple columns to multiple rows with gaps inbetween columns
我有一个大型数据集要转置,下面的代码在正确的输出中完全做到了这一点,但是列太多了。目前,代码将不断地从一列读取到另一列,直到它拥有所有内容。我想更改此设置,以便我可以 select 第一列数据,跳过 3 列然后继续脚本。
My Dataset:
UFI CAT1 CAT2 CAT3 CAT4 CAT5 CAT6
RN1 Skip1 Skip2 Skip3 Copy1 Copy2 Copy3
RN2 Skip1 Skip2 Skip3 Copy1 Copy2 Copy3
Desired Output:
UFI COLUMN VALUES
RN1 CAT5 Copy1
RN1 CAT6 Copy2
RN1 CAT7 Copy3
RN2 CAT5 Copy1
RN2 CAT6 Copy2
RN2 CAT7 Copy3
下面是 VBA 代码:
Option Explicit
Sub Tester()
Dim p
'get the unpivoted data as a 2-D array
p = UnPivotData(Sheets("Sheet1").Range("A1").CurrentRegion, _
3, True, False)
Dim r As Long, c As Long
For r = 1 To UBound(p, 1)
For c = 1 To UBound(p, 2)
Sheets("Sheet2").Cells(r, c).Value = p(r, c)
Next c
Next r
End Sub
Function UnPivotData(rngSrc As Range, fixedCols As Long, _
Optional AddCategoryColumn As Boolean = True, _
Optional IncludeBlanks As Boolean = True)
Dim nR As Long, nC As Long, data, dOut()
Dim r As Long, c As Long, rOut As Long, cOut As Long, cat As Long
Dim outRows As Long, outCols As Long
data = rngSrc.Value 'get the whole table as a 2-D
array
nR = UBound(data, 1) 'how many rows
nC = UBound(data, 2) 'how many cols
'calculate the size of the final unpivoted table
outRows = nR * (nC - fixedCols)
outCols = fixedCols + IIf(AddCategoryColumn, 2, 1)
'resize the output array
ReDim dOut(1 To outRows, 1 To outCols)
'populate the header row
For c = 1 To fixedCols
dOut(1, c) = data(1, c)
Next c
If AddCategoryColumn Then
dOut(1, fixedCols + 1) = "COLUMN"
dOut(1, fixedCols + 2) = "VALUES"
Else
dOut(1, fixedCols + 1) = "VALUES"
End If
'populate the data
rOut = 1
For r = 2 To nR
For cat = fixedCols + 1 To nC
If IncludeBlanks Or Len(data(r, cat)) > 0 Then
rOut = rOut + 1
'Fixed columns...
For c = 1 To fixedCols
dOut(rOut, c) = data(r, c)
Next c
'populate unpivoted values
If AddCategoryColumn Then
dOut(rOut, fixedCols + 1) = data(1, cat)
dOut(rOut, fixedCols + 2) = data(r, cat)
Else
dOut(rOut, fixedCols + 1) = data(r, cat)
End If
End If
Next cat
Next r
UnPivotData = dOut
End Function
感谢 Tims 的帮助,我得以解决问题。
为了做到这一点,我将添加一个新的隐藏 sheet,VBA 代码将以此为目标,隐藏 sheet 将包含我的数据集,其中包含所有跳过的内容删除列以允许 VBA 从隐藏的 sheet 正常读取,同时从我的工作 sheet.
操作所有这些
无需编辑 VBA 代码来为列设置例外,所需的输出将是相同的
只是为了它:
Sub Skip_and_Transpose()
Dim Ws1 As Worksheet: Set Ws1 = Sheets(1)
Dim Ws2 As Worksheet: Set Ws2 = Sheets(2)
Dim P1 As Range: Set P1 = Ws1.UsedRange
T1 = P1
Dim T2()
a = 1
ReDim Preserve T2(1 To 3, 1 To a)
T2(1, a) = "UFI"
T2(2, a) = "COLUMN"
T2(3, a) = "VALUES"
a = a + 1
For i = 2 To UBound(T1)
For j = 5 To UBound(T1, 2)
ReDim Preserve T2(1 To 3, 1 To a)
T2(1, a) = T1(i, 1)
T2(2, a) = T1(1, j)
T2(3, a) = T1(i, j)
a = a + 1
Next j
Next i
Ws2.Range("A1").Resize(UBound(T2, 2), UBound(T2)) = Application.Transpose(T2)
End Sub
我有一个大型数据集要转置,下面的代码在正确的输出中完全做到了这一点,但是列太多了。目前,代码将不断地从一列读取到另一列,直到它拥有所有内容。我想更改此设置,以便我可以 select 第一列数据,跳过 3 列然后继续脚本。
My Dataset:
UFI CAT1 CAT2 CAT3 CAT4 CAT5 CAT6
RN1 Skip1 Skip2 Skip3 Copy1 Copy2 Copy3
RN2 Skip1 Skip2 Skip3 Copy1 Copy2 Copy3
Desired Output:
UFI COLUMN VALUES
RN1 CAT5 Copy1
RN1 CAT6 Copy2
RN1 CAT7 Copy3
RN2 CAT5 Copy1
RN2 CAT6 Copy2
RN2 CAT7 Copy3
下面是 VBA 代码:
Option Explicit
Sub Tester()
Dim p
'get the unpivoted data as a 2-D array
p = UnPivotData(Sheets("Sheet1").Range("A1").CurrentRegion, _
3, True, False)
Dim r As Long, c As Long
For r = 1 To UBound(p, 1)
For c = 1 To UBound(p, 2)
Sheets("Sheet2").Cells(r, c).Value = p(r, c)
Next c
Next r
End Sub
Function UnPivotData(rngSrc As Range, fixedCols As Long, _
Optional AddCategoryColumn As Boolean = True, _
Optional IncludeBlanks As Boolean = True)
Dim nR As Long, nC As Long, data, dOut()
Dim r As Long, c As Long, rOut As Long, cOut As Long, cat As Long
Dim outRows As Long, outCols As Long
data = rngSrc.Value 'get the whole table as a 2-D
array
nR = UBound(data, 1) 'how many rows
nC = UBound(data, 2) 'how many cols
'calculate the size of the final unpivoted table
outRows = nR * (nC - fixedCols)
outCols = fixedCols + IIf(AddCategoryColumn, 2, 1)
'resize the output array
ReDim dOut(1 To outRows, 1 To outCols)
'populate the header row
For c = 1 To fixedCols
dOut(1, c) = data(1, c)
Next c
If AddCategoryColumn Then
dOut(1, fixedCols + 1) = "COLUMN"
dOut(1, fixedCols + 2) = "VALUES"
Else
dOut(1, fixedCols + 1) = "VALUES"
End If
'populate the data
rOut = 1
For r = 2 To nR
For cat = fixedCols + 1 To nC
If IncludeBlanks Or Len(data(r, cat)) > 0 Then
rOut = rOut + 1
'Fixed columns...
For c = 1 To fixedCols
dOut(rOut, c) = data(r, c)
Next c
'populate unpivoted values
If AddCategoryColumn Then
dOut(rOut, fixedCols + 1) = data(1, cat)
dOut(rOut, fixedCols + 2) = data(r, cat)
Else
dOut(rOut, fixedCols + 1) = data(r, cat)
End If
End If
Next cat
Next r
UnPivotData = dOut
End Function
感谢 Tims 的帮助,我得以解决问题。
为了做到这一点,我将添加一个新的隐藏 sheet,VBA 代码将以此为目标,隐藏 sheet 将包含我的数据集,其中包含所有跳过的内容删除列以允许 VBA 从隐藏的 sheet 正常读取,同时从我的工作 sheet.
操作所有这些无需编辑 VBA 代码来为列设置例外,所需的输出将是相同的
只是为了它:
Sub Skip_and_Transpose()
Dim Ws1 As Worksheet: Set Ws1 = Sheets(1)
Dim Ws2 As Worksheet: Set Ws2 = Sheets(2)
Dim P1 As Range: Set P1 = Ws1.UsedRange
T1 = P1
Dim T2()
a = 1
ReDim Preserve T2(1 To 3, 1 To a)
T2(1, a) = "UFI"
T2(2, a) = "COLUMN"
T2(3, a) = "VALUES"
a = a + 1
For i = 2 To UBound(T1)
For j = 5 To UBound(T1, 2)
ReDim Preserve T2(1 To 3, 1 To a)
T2(1, a) = T1(i, 1)
T2(2, a) = T1(1, j)
T2(3, a) = T1(i, j)
a = a + 1
Next j
Next i
Ws2.Range("A1").Resize(UBound(T2, 2), UBound(T2)) = Application.Transpose(T2)
End Sub