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

如果有正确引用的父工作表引用,此代码会更好。

此解决方案使用AutoFilterRange.AreasArrays以避免循环遍历每个单元格,提高处理速度...

    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