Excel VBA 将可变列范围转置为可变行
Excel VBA Transpose Variable Column Range to Variable Rows
你好 Whosebug 社区,
我不久前开始使用 excel vba 并且确实需要一些帮助来解决一个有点复杂的问题。
我有一个电子表格,其中有一列 "Prime" 部分及其下方的 "Alternative" 部分。我需要创建一个宏,将 Variable Alternative 部分转置到其关联的 Prime 部分的右侧。因此对于下面的示例,A 列中的 "P" 是主要部分,"A" 是备用部分:
A |
1P |
1A |
1A |
1A |
2P |
2A |
2A |
3P |
3A |
我正在尝试创建一个会给我以下结果的宏:
A || B || C || D |
1P | 1A | 1A | 1A
1A |
1A |
1A |
2P | 2A | 2A
2A |
2A |
3P | 3A
3A |
下面是我能够想出的代码,但是所有替代部分都合并到一个范围内并转置到列表的第一个主要部分。我知道这可能不是我要实现的目标的最佳方法。我乐于接受所有建议,并期待听到一些很棒的解决方案。
请注意,上面示例中的粗体主要部分实际上在我的电子表格中突出显示,这将解释代码中的 "colorindex = 6"
Sub NewHope()
Dim cell As Range
Dim LastRow As Long
Dim Prime As Range
Dim alt As Range
LastRow = Range("A" & Rows.Count).End(xlUp).Row
For Each cell In Range("A2:A" & LastRow)
If cell.Interior.ColorIndex = 6 Then
If Prime Is Nothing Then
Set Prime = cell
End If
Else
If alt Is Nothing Then
Set alt = cell
Else
Set alt = Union(alt, cell)
End If
End If
Next
alt.Copy
Prime.Offset(0, 4).PasteSpecial Transpose:=True
End sub
试试这个代码:
Sub test()
Dim cell As Range
Dim LastRow As Long
Dim PrimeRow As Long
Dim PrimeColumn As Long
LastRow = Range("A" & Rows.Count).End(xlUp).Row
For Each cell In Range("A2:A" & LastRow)
If cell.Interior.ColorIndex = 6 Then
PrimeRow = cell.Row
PrimeColumn = cell.Column + 1
Else
Cells(PrimeRow, PrimeColumn).Value = cell.Value
PrimeColumn = PrimeColumn + 1
End If
Next
End Sub
If Prime Is Nothing Then
以上代码似乎没有达到您的要求;它不会重置 'prime' 单元格,因为在 'prime' 单元格的第一个位置之后,Prime 将不再是空的。
dim r as long, pr as long
For r=2 to Range("A" & Rows.Count).End(xlUp).Row
If cells(r, "A").Interior.ColorIndex = 6 Then
pr = r
Else
cells(pr, columns.count).end(xltoleft).offset(0,1) = cells(r, "A").value
End If
Next
如果有正确引用的父工作表引用,此代码会更好。
此解决方案使用AutoFilter
、Range.Areas
和Arrays
以避免循环遍历每个单元格,提高处理速度...
Sub TEST_Transpose_Alternates_To_Prime()
Dim wsTrg As Worksheet, rgTrg As Range
Dim rgPrime As Range, rgAlter As Range
Dim rgArea As Range, aAlternates As Variant
Dim L As Long
Set wsTrg = ThisWorkbook.Worksheets("DATA") 'Change as required
With wsTrg
Application.Goto .Cells(1), 1
If Not (.AutoFilter Is Nothing) Then .Cells(1).AutoFilter
Set rgTrg = .Cells(6, 2).CurrentRegion.Columns(1) 'Change as required
End With
Rem Set Off Application Properties to improve speed
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With rgTrg
Rem Set Primes Range
.AutoFilter Field:=1, Criteria1:="=*P"
Set rgPrime = .Offset(1).Resize(-1 + .Rows.Count).SpecialCells(xlCellTypeVisible)
Rem Set Alternates Range
.AutoFilter Field:=1, Criteria1:="=*A"
Set rgAlter = .Offset(1).Resize(-1 + .Rows.Count).SpecialCells(xlCellTypeVisible)
Rem Clear Filters
.AutoFilter
End With
Rem Validate Prime & Alternate Ranges
If rgPrime.Areas.Count <> rgAlter.Areas.Count Then Exit Sub
Rem Post Alternates besides each Prime
rgTrg.Cells(1).Offset(0, 1).Value = "Alternates..."
For Each rgArea In rgAlter.Areas
With rgPrime
L = 1 + L
aAlternates = rgArea.Value2
If rgArea.Cells.Count > 1 Then
aAlternates = WorksheetFunction.Transpose(aAlternates)
.Areas(L).Cells(1).Offset(0, 1).Resize(1, UBound(aAlternates)).Value = aAlternates
Else
.Areas(L).Cells(1).Offset(0, 1).Value = aAlternates
End If: End With: Next
Rem Refresh Application Properties
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
你好 Whosebug 社区,
我不久前开始使用 excel vba 并且确实需要一些帮助来解决一个有点复杂的问题。
我有一个电子表格,其中有一列 "Prime" 部分及其下方的 "Alternative" 部分。我需要创建一个宏,将 Variable Alternative 部分转置到其关联的 Prime 部分的右侧。因此对于下面的示例,A 列中的 "P" 是主要部分,"A" 是备用部分:
A |
1P |
1A |
1A |
1A |
2P |
2A |
2A |
3P |
3A |
我正在尝试创建一个会给我以下结果的宏:
A || B || C || D |
1P | 1A | 1A | 1A
1A |
1A |
1A |
2P | 2A | 2A
2A |
2A |
3P | 3A
3A |
下面是我能够想出的代码,但是所有替代部分都合并到一个范围内并转置到列表的第一个主要部分。我知道这可能不是我要实现的目标的最佳方法。我乐于接受所有建议,并期待听到一些很棒的解决方案。
请注意,上面示例中的粗体主要部分实际上在我的电子表格中突出显示,这将解释代码中的 "colorindex = 6"
Sub NewHope()
Dim cell As Range
Dim LastRow As Long
Dim Prime As Range
Dim alt As Range
LastRow = Range("A" & Rows.Count).End(xlUp).Row
For Each cell In Range("A2:A" & LastRow)
If cell.Interior.ColorIndex = 6 Then
If Prime Is Nothing Then
Set Prime = cell
End If
Else
If alt Is Nothing Then
Set alt = cell
Else
Set alt = Union(alt, cell)
End If
End If
Next
alt.Copy
Prime.Offset(0, 4).PasteSpecial Transpose:=True
End sub
试试这个代码:
Sub test()
Dim cell As Range
Dim LastRow As Long
Dim PrimeRow As Long
Dim PrimeColumn As Long
LastRow = Range("A" & Rows.Count).End(xlUp).Row
For Each cell In Range("A2:A" & LastRow)
If cell.Interior.ColorIndex = 6 Then
PrimeRow = cell.Row
PrimeColumn = cell.Column + 1
Else
Cells(PrimeRow, PrimeColumn).Value = cell.Value
PrimeColumn = PrimeColumn + 1
End If
Next
End Sub
If Prime Is Nothing Then
以上代码似乎没有达到您的要求;它不会重置 'prime' 单元格,因为在 'prime' 单元格的第一个位置之后,Prime 将不再是空的。
dim r as long, pr as long
For r=2 to Range("A" & Rows.Count).End(xlUp).Row
If cells(r, "A").Interior.ColorIndex = 6 Then
pr = r
Else
cells(pr, columns.count).end(xltoleft).offset(0,1) = cells(r, "A").value
End If
Next
如果有正确引用的父工作表引用,此代码会更好。
此解决方案使用AutoFilter
、Range.Areas
和Arrays
以避免循环遍历每个单元格,提高处理速度...
Sub TEST_Transpose_Alternates_To_Prime()
Dim wsTrg As Worksheet, rgTrg As Range
Dim rgPrime As Range, rgAlter As Range
Dim rgArea As Range, aAlternates As Variant
Dim L As Long
Set wsTrg = ThisWorkbook.Worksheets("DATA") 'Change as required
With wsTrg
Application.Goto .Cells(1), 1
If Not (.AutoFilter Is Nothing) Then .Cells(1).AutoFilter
Set rgTrg = .Cells(6, 2).CurrentRegion.Columns(1) 'Change as required
End With
Rem Set Off Application Properties to improve speed
Application.EnableEvents = False
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With rgTrg
Rem Set Primes Range
.AutoFilter Field:=1, Criteria1:="=*P"
Set rgPrime = .Offset(1).Resize(-1 + .Rows.Count).SpecialCells(xlCellTypeVisible)
Rem Set Alternates Range
.AutoFilter Field:=1, Criteria1:="=*A"
Set rgAlter = .Offset(1).Resize(-1 + .Rows.Count).SpecialCells(xlCellTypeVisible)
Rem Clear Filters
.AutoFilter
End With
Rem Validate Prime & Alternate Ranges
If rgPrime.Areas.Count <> rgAlter.Areas.Count Then Exit Sub
Rem Post Alternates besides each Prime
rgTrg.Cells(1).Offset(0, 1).Value = "Alternates..."
For Each rgArea In rgAlter.Areas
With rgPrime
L = 1 + L
aAlternates = rgArea.Value2
If rgArea.Cells.Count > 1 Then
aAlternates = WorksheetFunction.Transpose(aAlternates)
.Areas(L).Cells(1).Offset(0, 1).Resize(1, UBound(aAlternates)).Value = aAlternates
Else
.Areas(L).Cells(1).Offset(0, 1).Value = aAlternates
End If: End With: Next
Rem Refresh Application Properties
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub