First iteration jumping four rows instead of the expected one row

时间:2017-04-06 17:02:57

标签: excel vba

Why is my first iteration in Sub throughCols that is intended to move one row down each time jumping four rows?

Option Explicit

Dim txt As String
Dim i As Long
Dim strTest As String
Dim strArray() As String
Dim lCaseOn As Boolean
Dim firstRow As Long, startIt As Long
Dim thisCell As Range
Dim lastRow As Long
Dim resetAddress As Range


Sub throughCols()

' Dim thisCell As Range

' get start and end of column data
' NB sheet name is hard coded twice
Call dataRange
startIt = firstRow + 1

For i = 1 To 8 Step 1
    ' after testing use startIt To lastRow Step 1
    ' by using activeCell I dont have to pass range through to the sub
    Sheets("test").Range("B" & i).Select
    MsgBox "this is itteration " & i & " which will output to " & ActiveCell.Offset(0, 2).Address
    Call arrayManip

    Call cleanTxt(txt)
Next i

End Sub


Sub arrayManip()

' clear out all data
Erase strArray
txt = ""

'set default case
lCaseOn = False

' string into an array using a " " separator
strTest = WorksheetFunction.Proper(ActiveCell.Value)
strTest = Replace(strTest, "-", " - ")
strTest = Replace(strTest, "‘", " ‘ ")
strArray = Split(strTest, " ")

' itterate through array looking to make text formats

For i = LBound(strArray) To UBound(strArray)
    If strArray(i) = "-" Then
        lCaseOn = True
        GoTo NextIteration
    End If

    If strArray(i) = "‘" Then
        lCaseOn = True

        GoTo NextIteration
    End If
    If lCaseOn Then
        strArray(i) = LCase(strArray(i))
        lCaseOn = False
NextIteration:
    End If

    Next
End Sub

Function cleanTxt(txt)

' loop through the array to build up a text string
For i = LBound(strArray) To UBound(strArray)
    txt = txt & strArray(i) & " "
Next i

' remove the space
txt = Trim(Replace(txt, " - ", "-"))
txt = Trim(Replace(txt, " ‘ ", "‘"))

' MsgBox "active cell is " & activeCell.Address
ActiveCell.Offset(0, 2).Select: ActiveCell.Value = txt

' MsgBox "final output would be " & txt & " to " & activeCell.Address
' this is a thumb suck to attempt to reset the active cell to the itteration address that started it
ActiveCell.Offset(0, -2).Select
MsgBox "next itteration should start with active cell set as " & ActiveCell.Address

End Function
Sub dataRange()

With Sheets("test").Columns("B")

    If WorksheetFunction.CountA(.Cells) = 0 Then '<--| if no data whatever
        MsgBox "Sorry: no data"
    Else
    With .SpecialCells(xlCellTypeConstants) '<--| reference its cells with constant (i.e, not derived from formulas) values)
        firstRow = .Areas(1).Row
        lastRow = .Areas(.Areas.Count).Cells(.Areas(.Areas.Count).Rows.Count).Row
    End With
        ' MsgBox "the first row is " & firstRow
        ' MsgBox "last row is " & lastRow
    End If
End With

End Sub    

1 个答案:

答案 0 :(得分:2)

You are declaring your i variable at module scope, which makes it accessible everywhere within the module; it's modified when you call arrayManip and the value changes.

If you declare a local ind variable inside this routine it won't happen, because the variable will only be accessible to the scope it's declared in. Try the code below:

Sub throughCols()

' Dim thisCell As Range
Dim ind As Long  '<-- DECLARE local variable
' get start and end of column data
' NB sheet name is hard coded twice
Call dataRange
startIt = firstRow + 1

' ===== loop on ind and not i (changes when you call arrayManip) ====
For ind = 1 To 8 ' Step 1 <-- actually not needed, that's the default increment value
    ' after testing use startIt To lastRow Step 1
    ' by using activeCell I dont have to pass range through to the sub
    Sheets("test").Range("B" & ind).Select
    MsgBox "this is itteration " & ind & " which will output to " & ActiveCell.Offset(0, 2).Address
    Call arrayManip

    Call cleanTxt(txt)
Next ind

End Sub