0

概要:私の会社には2つの異なるスプレッドシートがあり、それぞれに多くのポリシーがあります。彼らは私にポリシーIDでポリシーを照合し、古いスプレッドシートから新しいスプレッドシートにすべての古いメモを転送することを望んでいます。

理由:私の問題は、これを行う方法を理解していないことではなく、これを行うための最良の方法です。StackOverflowに参加して以来、私はすべきこととすべきでないことを言われてきました。For Each単純なループではなく、ループを使用する方がよいと何度も言われてきましたDo。また、私は.Select頻繁に使用するべきではないと言われました(しかし私はそうします)。

通常の方法:通常はループを使用しDoてデータを調べ、データを選択して.Find使用します。ActiveCell現在の行の他の列とやり取りする場合は、を使用しますActiveCell.Offset()。私はいつもそれを愛し.Selectて使用する傾向がありますが、このプロジェクトでは、箱から出して自分自身を押し出し、悪いコーディングの習慣を変えて、より良いものを使い始めようとしています。

質問:ループActiveCell.Offset()を使用しているときに、と同等のことを行うにはどうすればよいですか?For Each

これまでの私のコード: **質問/批評を歓迎します

Sub NoteTransfer()

    transferNotes

End Sub
Function transferNotes()

    Dim theColumn As Range
    Dim fromSheet As Worksheet
    Dim toSheet As Worksheet
    Dim cell As Range
    Dim lastRow As Integer

    Set fromSheet = Sheets("NotesFrom")
    Set toSheet = Sheets("NotesTo")

    With fromSheet                      'FINDING LAST ROW
        lastRow = .Range("B" & .Rows.Count).End(xlUp).Row
    End With

    Set theColumn = fromSheet.Range("B5:B" & lastRow)

    For Each cell In theColumn          'CODE FOR EACH CELL IN COLUMN

        If cell.Text = "" Then

            'do nothing

        Else

            With toSheet         'WANT TO FIND DATA ON THE toSheet

                Cells.find(What:=cell.Text, After:=ActiveCell, LookIn:=xlFormulas, _
                LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False).Activate



            End With


        End If

    Next cell

End Function

参考のためのサンプル画像

シートの下部

シートの下部。

4

2 に答える 2

2

まず、あなたの質問:

Question: How would I go about doing the equivalent of an ActiveCell.Offset() when I'm using a For Each loop?

あなたが投稿したコードを考えると、あまり意味がありません。これは非常に一般的な質問であり、理解を深めるにはある程度のコンテキストが必要です。それは本当にあなたのループに依存します。ActiveCellから連続した範囲のセルをループしている場合は、次のように言うことができます...

For each cel in Range
    myValue = ActiveCell.Offset(,i)
    i = i + 1
Next

ループ内の各セルの横にある列を取得します。しかし、一般的に、私はその素晴らしいプログラミングとは呼びません。私が言ったように、文脈は重要です。

コードに関する限り、これが理にかなっているかどうかを確認してください。私はあなたを少し助けるために編集してコメントしました。そうそう、使用していない良い仕事Select

Sub transferNotes() '-> first no need for a function, because you are not returning anything...
                       'and no need to use a sub to call a sub here as you don't pass variables,
                       'and you don't have a process you are trying to run

    Dim theColumn As Range, cell As Range '-> just a little cleaner, INMHO
    Dim fromSheet As Worksheet, toSheet As Worksheet '-> just a little cleaner, INMHO
    Dim lastRow As Integer

    Set fromSheet = Sheets("NotesFrom")
    Set toSheet = Sheets("NotesTo")

    With fromSheet ' -> put everything you do in the "fromSheet" in your With block

        lastRow = .Range("B" & .Rows.Count).End(xlUp).Row 'FINDING LAST ROW
        Set theColumn = .Range("B5:B" & lastRow)

        theColumn.AutoFilter 1, "<>"

        Set theColumn = theColumn.SpecialCells(xlCellTypeVisible) '-> now you are only looping through the cells are that are not blank, so it's more efficient

        For Each cell In theColumn

            '-> use of ActiveCell.Offset(), it's not ActiveCell.Offset(), but it uses Offset
            Dim myValue
            myValue = cell.Offset(, 1) '-> gets the cell value in the column to the right of the code


            'WANT TO FIND DATA ON THE toSheet
            toSheet.Cells.Find(What:=cell.Text, After:=ActiveCell, LookIn:=xlFormulas, _
                LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False).Activate

        Next cell

    End With

End Sub
于 2012-09-24T20:36:47.067 に答える
1

これはこれまでの私の提案です。

Function transferNotes()

    Dim SourceColumn As Range
    Dim fromSheet As Worksheet
    Dim toSheet As Worksheet
    Dim cell As Range
    Dim lastRow As Long '<--changed to Long

    Set fromSheet = Sheets("NotesFrom")
    Set toSheet = Sheets("NotesTo")

    With fromSheet                      'FINDING LAST ROW
        lastRow = .Range("B" & .Rows.Count).End(xlUp).Row
    End With

    Set SourceColumn = fromSheet.Range("B5:B" & lastRow)

    For Each cell In SourceColumn          'CODE FOR EACH CELL IN COLUMN
        If cell.Value = "" Then 'the .Text property can
                                'make for some confusing errors.
                                'Try to avoid it.
            'nothng to search for
        Else
            With toSheet         'WANT TO FIND DATA ON THE toSheet
                Dim destRng As Range

                Set destRng = .Range("A:A").Find(What:=cell.Value)
                If Not destRng Is Nothing Then
                    .Cells(destRng.Row, <your mapped column destination>)
                        = fromSheet.Cells(cell.Row,<your mapped column source>)
    ' you can either repeat the above line for all of your non-contiguous
    'sections of data you want to move from sheet to sheet
    '(i.e. if the two sheets are not arranged the same)
    'if the two sheets are aranged the same then change
    'the .cells call to call a range and include
    'the full width of columns
                Else
                    'nothing was found
                End If

            End With
        End If
    Next cell

End Function
于 2012-09-24T20:43:56.947 に答える