0

色分けされたテーブルがあります。各行を循環し、その行のどの列が色付けされているかを表す文字列を返したいと思います。私のアプローチは、循環するセルの垂直範囲を定義し、その範囲内の各セルに対して、循環する水平範囲を定義することでした。表示されるエラーは、For 変数が既に使用されていることを示しています。これは私が使用しているコードです:

Public Sub Months()

Dim Tally As String
Dim R1 As Range
Dim R2 As Range
Dim Col As String

Range("A2").Select
Range(Selection, Selection.End(xlDown)).Select
Set R1 = Range(Selection.Address)

For Each cell In R1
    cell.Activate
    Range(Selection, Selection.End(xlRight)).Select
    Set R2 = Range(Selection.Address)
    For Each cell In R2
        If cell.Interior.ColorIndex > 0 Then
            Col = Split(ActiveCell(1).Address(1, 0), "$")(0)
            If Tally Is Nothing Then
                Set Tally = Col
            Else
                Set Tally = Tally + ";" + Col
            End If
            Range("DF" & (ActiveCell.Row)).Select
            ActiveCell.Value = Tally
        End If
    Next
Next

End Sub

何かご意見は?

どうもありがとう。

4

3 に答える 3

2

いつもOption Explicitのように、このエラーの原因を特定するのに役立ちます。

まず、複数の範囲は必要ありません。テーブル全体を定義する範囲は 1 つだけです。その方法を以下に示します。

当面の質問は

コンテキストでは、For each cell in ... R1wherecellは特別なキーワードではなく、使用されている暗黙の変数です。後で. For each cell in R2_cell

つまり、疑似キーワード以外のものを使用すると、問題がより明白になる可能性がありますcell

For i = 1 to 10
    For i = 3 to 44
        Msgbox i
    Next
Next

コンパイラがメッセージ ボックスの行に到達できるとしたら、どの値がi表示されると予想されますか? これがエラーの原因です。イテレータはすでに使用されているため、再利用できません。

すべての変数を宣言Option Explicitし、将来これらの間違いを避けるために使用してください:)

テーブルの範囲を定義するより良い方法

ただし、テーブル内のすべての行または列の行範囲を無計画に定義して再定義しようとするよりも、単に 1 つの範囲を定義する方がはるかに効率的です。このようなことを試してください。

Option Explicit
Public Sub Months()
Dim Tally As String
Dim tbl As Range
Dim r As Range
Dim c As Range
Dim cl As Range
Dim Col As String

Set tbl = Range(Range("A2").End(xlDown), Range("A2").End(xlToRight))

For Each r In tbl.Rows
    For Each c In tbl.Columns
        Set cl = tbl.Cells(r, c)
        If cl.Interior.ColorIndex > 0 Then
            Col = Split(cl.Address(1, 0), "$")(0)
'            If Tally Is Nothing Then
'                Set Tally = Col
'            Else
'                Set Tally = Tally + ";" + Col
'            End If
            Range("DF" & (cl.Row)).Select
            cl.Value = Tally
        End If
    Next
Next

End Sub

ノート:

Tallyいくつかのエラーがあるため、変数に関連するコードのブロックをコメントアウトしました。

  • Tally文字列変数です。Setキーワードを使用して文字列変数を割り当てないでください。
  • Tallyは文字列変数であるため、Is Nothing一致しません。Tally = vbNullStringorをチェックしてくださいLen(Tally) = 0
  • 演算子+は文字列の連結を許可する場合がありますが、VBA で優先される演算子は&.
于 2013-06-07T17:49:06.477 に答える
1

ネストされた For ループで同じ変数名を使用しています。

For Each cell In R1
...
    For Each cell In R2

2 番目のループの "cell" 変数を別のものに変更します。

また、この行:

If Tally Is Nothing Then

壊れます。Tally はオブジェクトではなく文字列として定義されるため、"If Tally <> "" Then" を使用する必要があります。

于 2013-06-07T17:49:42.323 に答える
1

可能な限り、選択を避ける必要があります。

未テスト:

Public Sub Months()

Dim Tally As String
Dim R1 As Range
Dim R2 As Range
Dim Col As String
Dim c As Range, c2 As Range

    With ActiveSheet
        Set R1 = .Range(.Range("A2"), .Range("A2").End(xlDown))
    End With

    For Each c In R1.Cells
        Tally = ""
        Set R2 = ActiveSheet.Range(c, c.End(xlToRight)) 'not xlRight...
        For Each c2 In R2.Cells
            If c2.Interior.ColorIndex > 0 Then
                Col = Split(c2.Address(), "$")(0)
                Tally = Tally & IIf(Len(Tally) > 0, ";", "") & Col 'Set not required...
            End If
        Next
        ActiveSheet.Range("DF" & c.Row).Value = Tally
    Next

End Sub
于 2013-06-07T18:00:00.483 に答える