Excel VBA将可变列范围转置为可变行

时间:2017-11-24 21:07:30

标签: excel vba excel-vba transpose

Hello StackOverFlow社区,

我不久前开始使用excel vba,并且可以在一些有些复杂的问题上使用一些帮助。

我有一个电子表格,其中包含一列“Prime”部件及其下方的“Alternative”部件。我需要创建一个宏,将可变备用部件转置到其关联的Prime部件的右侧。因此,对于下面的示例,在列A中,“P”是Prime部件,“A”是Altenates:

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 |

以下是我能够提出的代码,但所有备用部分合并到一个范围内并转置到列表的第一个Prime部分。我知道这可能不是我想要完成的最佳方法。我对所有建议持开放态度,并期待听到一些很棒的解决方案。

请注意,上面示例中的Bolded Prime部分实际上在我的电子表格中突出显示,这将解释代码中的“colorindex = 6”

<body>
    <h1> <span class ="magicNum" id ="magic"> ? </span></h1>
    <h2><span id ="output">Result</span></h2>
    <h2> Score: <span id = "score"> 0 </span></h2>
    <div class="wrapper" > 
    <input type="text" id="input1" placeholder="Enter your guess:"/>
    <button onclick="submit()"> Submit </button></div> <br>
    <div class="wrapper" > <button id ="playAgain" onclick="restart()"> Play Again? </button></div>
    <script type="text/javascript">
        var magicNumber;
        var points = 0;
        function submit(){
            var text=document.getElementById('input1').value;
            var question=document.getElementById('magic');
            var output=document.getElementById('output');
            var counter=document.getElementById('score');
            magicNumber=Math.floor((Math.random() * 10) + 1);
            question.innerHTML = magicNumber;
            if ((magicNumber == text) or ((text + 1) == magicNumber) or ((text - 1) == magicNumber)) {
                points++;
                counter.innerHTML = points;
                output.innerHTML = You Got Lucky!;
            } else {
                output.innerHTML = Bad luck. Try again;
            }
        }
        function restart() {
            var text=document.getElementById('input1').value;
            var question=document.getElementById('magic');
            var output=document.getElementById('output');
            text.innerHTML= result;
            question.innerHTML=?;
            output.innerHTML=;
        }
    </script>

</body>

3 个答案:

答案 0 :(得分:2)

试试这段代码:

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

答案 1 :(得分:0)

If Prime Is Nothing Then

以上代码似乎没有按照您的要求执行;它没有重置“素数”。自从&#39; prime&#39;细胞,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

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

答案 2 :(得分:0)

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