【问题标题】:Excel VBA Transpose Variable Column Range to Variable RowsExcel VBA 将变量列范围转置为变量行
【发布时间】:2017-11-25 08:47:11
【问题描述】:

你好 StackOverFlow 社区,

不久前我开始使用 excel vba,并且确实可以使用一些帮助来解决一些复杂的问题。

我有一个电子表格,其中有一列“主要”部分及其下方的“替代”部分。我需要创建一个宏,它将可变替代部分转置到其关联的主要部分的右侧。因此,对于下面的示例,在 A 列中,“P”是主要零件,“A”是替代品:

一个 |

1P |

1A |

1A |

1A |

2P |

2A |

2A |

3P |

3A |

我试图创建一个宏,它会给我以下结果:

一个 || 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

【问题讨论】:

  • 我试图弄清楚是否需要了解替代素数的工作原理以帮助解决方案......我对此表示怀疑。只要存在模式,总会有许多不同的方法将数据重新排列成不同的模式。如果您的代码已经识别(用颜色)哪些数字需要作为“标题”,那么它应该非常简单。移动它而不是着色单元格?
  • @ashleedawg 没有模式。每个主要部分可以有任意数量的替代部分。希望澄清
  • 你试过使用数组吗?你怎么知道一个零件是否是 Prime 的替代品?
  • 代码是否比您发布的更多?由于某些原因,这对我来说没有意义(与 Primes 无关),但它有点难以理解。你知道如何单步执行你的代码,一次一行,观察变量和输出吗?听起来您确切地知道它需要做什么,一步一步,所以单步执行代码可能会使特定问题变得明显。 Check out this article 出色的 Chip Pearson,Excel 之王。
  • @DavidG。我没有尝试过使用数组,因为我对该函数不太熟悉。替代部分是它们正上方的 Prime 单元格下方的单元格。

标签: vba excel transpose


【解决方案1】:

试试这个代码:

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

【讨论】:

  • @David.G 您提供的代码完全符合我的要求!不过,我还有一个问题希望您能解决。
  • 代码转置了“--A”单元格,但我实际上试图转置这些单元格旁边的列中的单元格。我希望你很清楚。
  • 您好,托德,这段代码对您有帮助。由于这解决了您最初的问题,请将我的回答标记为已解决您的问题。您可以在Else 语句下方添加一些行,以验证下一列中的单元格是否有数据并将值复制到 Prime 行中的下一列。
  • 再次感谢您。我标记为已回答。有什么方法可以为这个建议提供更多指导吗?我仍在尝试完全理解您提供的代码。
  • 我想通了!再次感谢您的帮助!
【解决方案2】:
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

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

【讨论】:

    【解决方案3】:

    此方案使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-29
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      • 1970-01-01
      相关资源
      最近更新 更多