Excel 第一次迭代跳过四行而不是预期的一行

Excel 第一次迭代跳过四行而不是预期的一行,excel,vba,Excel,Vba,为什么我在Sub-throughCols中的第一次迭代每次向下移动一行会跳过四行 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 resetA

为什么我在
Sub-throughCols
中的第一次迭代每次向下移动一行会跳过四行

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    
选项显式
以字符串形式显示文本
我想我会坚持多久
将strTest设置为字符串
Dim strArray()作为字符串
作为布尔值的Dim lCaseOn
第一排一样长,第一排一样长
将此单元格设置为范围
最后一排一样长
将地址重置为范围
Sub-throughCols()
'将此单元格设置为范围
'获取列的开始和结束数据
“NB图纸名称硬编码两次
呼叫数据范围
startIt=第一行+1
对于i=1到8,步骤1
'测试后,使用startIt至最后一行步骤1
“通过使用activeCell,我不必将范围传递给sub
表格(“测试”)。范围(“B”和i)。选择
MsgBox“this is iteration”&i&“它将输出到”&ActiveCell.Offset(0,2).Address
呼叫arrayManip
调用cleanTxt(txt)
接下来我
端接头
副数组名称()
“清除所有数据
抹去条纹
txt=“”
'设置默认情况
lCaseOn=False
使用“”分隔符将“”字符串插入数组中
strTest=WorksheetFunction.property(ActiveCell.Value)
strTest=替换(strTest,“-”,“-”)
strTest=替换(strTest,“'”,“'”)
strArray=拆分(strTest,“”)
'通过数组查找以生成文本格式
对于i=LBound(strArray)到UBound(strArray)
如果strArray(i)=“-”,则
lCaseOn=True
后藤下滴度
如果结束
如果Straray(i)=“”,则
lCaseOn=True
后藤下滴度
如果结束
如果是这样的话
strArray(i)=LCase(strArray(i))
lCaseOn=False
下一次滴定:
如果结束
下一个
端接头
函数cleanTxt(txt)
'循环数组以生成文本字符串
对于i=LBound(strArray)到UBound(strArray)
txt=txt&strArray(一)和“
接下来我
“删除空间
txt=修剪(替换(txt,“-”,“-”)
txt=修剪(替换(txt,“,”))
“MsgBox”活动单元格为“&activeCell.Address”
偏移量(0,2)。选择:ActiveCell.Value=txt
“MsgBox”的最终输出将是“&txt&”到“&activeCell.Address”
'这是一个尝试将活动单元格重置为启动它的写入地址的错误
ActiveCell.Offset(0,-2)。选择
MsgBox“下一次写入应以设置为”的活动单元格开始(&ActiveCell.Address)
端函数
子数据范围()
附页(“测试”)。列(“B”)

如果WorksheetFunction.CountA(.Cells)=0,则“您在模块范围内声明了
i
变量,这使得它在模块内的任何地方都可以访问;当您调用
arrayManip
并且值发生更改时,会对其进行修改

如果在此例程中声明一个本地
ind
变量,则不会发生这种情况,因为该变量只能在声明的范围内访问。请尝试以下代码:

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
Sub-throughCols()
'将此单元格设置为范围

Dim ind,只要'Your
i
是一个全局变量,它的值由您在循环中调用的一些子变量更改。不要在没有充分理由的情况下使用全局变量,这里似乎不是这样。你是一个高度进化的天才-现在,当你做了评论而不是回答时,我如何向你致意?@JohnColeman
I
根本不是全局的,这是一个私人领域。但问题仍然存在:它的范围太广,有多个过程正在访问它。@Mat'smugh我在一般意义上使用了“global”作为“local”的对应词几乎在任何编程语言中,而不是作为VBA范围规则中的一个技术术语。@MatsMug-好奇-我从未听说过VBA中的术语private field-在MSDN中找不到它-它从何而来?
Dim
在模块级使用会生成一个
private
字段;“此模块内的全局”是令人困惑的措辞,特别是考虑到(已弃用)
Global
关键字的存在,这意味着
Public
范围。变量是一个私有字段(表示模块作用域变量的字段),根本不是“全局的”。@Mat'smugh我的解释没有你的Mat好,你知道我的意思。如果你能编辑我的解释,那就太好了(我不为RubberDuck项目工作)没问题!=)。。。re“我不为Rubberduck项目工作”-为什么不?;-)@Mat'sMug不知道,从来都不知道你是如何加入团队的?这也许可以解决眼前的问题,但如果这些潜艇之间没有不必要的交互导致其他隐藏的错误,我会感到惊讶。应该鼓励OP重构他们的代码,而不是简单地把创可贴放在上面。