VBA中ActiveCell行上的简单循环迭代

VBA中ActiveCell行上的简单循环迭代,vba,excel,Vba,Excel,我正在用VBA编写一个非常基本的宏,这是我第一次用它编写任何东西,所以我一直在努力。我完全知道我需要做什么的逻辑,只是还不了解VBA的语法。如果行中的第一个单元格包含特定的子字符串,我希望迭代该行中的每个单元格。 在for循环中,如果该单元格不是空的,我想将该子字符串附加到该行中每个单元格的末尾。我没有通过我的for循环声明 Sub changeRow() Dim txt As String txt = Cells(ActiveCell.Row, 1) If InStr(1, txt, "

我正在用VBA编写一个非常基本的宏,这是我第一次用它编写任何东西,所以我一直在努力。我完全知道我需要做什么的逻辑,只是还不了解VBA的语法。如果行中的第一个单元格包含特定的子字符串,我希望迭代该行中的每个单元格。 在for循环中,如果该单元格不是空的,我想将该子字符串附加到该行中每个单元格的末尾。我没有通过我的for循环声明

Sub changeRow()
Dim txt As String
txt = Cells(ActiveCell.Row, 1)
   If InStr(1, txt, "123") > 0 Then
    For Each b In Range(Rows(ActiveCell.Row).Select)
        If Len(b.Value) > 0 Then
            b.Value = b.Value & " 123"
        End If
    Next b
End If    
End Sub

这就是您想要的,而无需引入任何新变量(尽管我确实将非信息性的“b”更改为
单元格

Sub changeRow()
Dim txt As String
Dim cell As Excel.Range

txt = ActiveCell.EntireRow.Cells(1)
If InStr(1, txt, "123") > 0 Then
    For Each cell In Intersect(ActiveCell.EntireRow, ActiveCell.Parent.UsedRange)
        If Len(cell.Value) > 0 Then
            cell.Value = cell.Value & " 123"
        End If
    Next cell
End If
End Sub
它也不会留下任何不合格的变量范围,这是一个好主意。通常,您可以通过引入像
ws
这样的变量来引用您正在处理的工作表来避免这种情况。但此代码很简单,并且基于
Activecell
,所以我只使用
Activecell.Parent

Sub changeRow()
  Const sTxt        As String = "123"
  Dim cell          As Range

  With Cells(ActiveCell.Row, "A")
    If VarType(.Value) = vbString Then
      If InStr(.Value, sTxt) Then
        For Each cell In .EntireRow.SpecialCells(xlCellTypeConstants, xlTextValues)
          cell.Value = cell.Value & " " & sTxt
        Next cell
      End If
    End If
  End With
End Sub
这也会将“123”添加到找到它的单元格中,但不会添加到包含数字或公式的单元格中

编辑:上面的代码中有一个明显的错误。它应该测试a列中的单元格是否不包含公式:

Sub changeRow()
  Const sTxt        As String = "123"
  Dim cell          As Range

  With Cells(ActiveCell.Row, "A")
    If VarType(.Value) = vbString And Not .HasFormula Then
      If InStr(.Value, sTxt) Then
        For Each cell In .EntireRow.SpecialCells(xlCellTypeConstants, xlTextValues)
          cell.Value = cell.Value & " " & sTxt
        Next cell
      End If
    End If
  End With
End Sub

否则,SpecialCells行可能会生成运行时错误。

我知道您已经找到了解决方案。我只是坚持“您对VBA是新手”这一事实。如果您有疑问,请随时发表评论。保留大部分原始逻辑

'-- this line is very important, it keeps "in order" to write code
'-- Forces explicit declaration of all variables in a file, or allows implicit declarations of variables.
'-- please explore on that
Option Explicit

'-- writing this with more comments since you said you are new to VBA
Sub changeRow()
Dim ws As Worksheet
Dim b As Range
Dim activeRange As Range
Dim fullRange As Range
Dim lastColumn As Long
Dim txt As String

    '-- set current sheet into a reference object variable called WS
    Set ws = ActiveWorkbook.Sheets("Sheet1")
    '-- similarly the range you plan to start the validation
    Set activeRange = ws.Range("B2")
    txt = activeRange.Value2

    '-- get last column in the row, 2 refers to rows 2 where you have data
    lastColumn = ws.Cells(2, ws.Columns.Count).End(xlToLeft).Column
    '-- get range until the last column in the row
    Set fullRange = Sheets("Sheet1").Range("B2").Resize(, lastColumn)

    '-- this allows you to view the Address of this range in the Immediate Window, just to make sure you get the desired range right
    Debug.Print fullRange.Address

    If InStr(1, txt, "123") > 0 Then
        '-- iterating through each range in full range that we specified above
        For Each b In fullRange
            '-- there's no need to check this because when InStr() fails,
            '-- the compiler will not come to this validation!
            If Len(b.Value) > 0 Then
                '-- b.Offset(3) refers to 3 rows down from cell B2 which is B5
                '-- output into 5th row for demonstration purpose
                '-- you may set it back to b.Value per your requirement.
                '-- Please explore offset property of Range object
                b.Offset(3).Value = b.Value & " 123"
            End If
        Next b
   End If

   '-- release the memory allocated to these reference object variables
   '-- the order is: first ranges, then worksheet
   Set activeRange = Nothing
   Set fullRange = Nothing
   Set ws = Nothing

End Sub

在您的声明中,
b
是什么?它应该是一个
范围
?是的,为糟糕的变量命名感到抱歉。我假设b应该是在每次迭代中选择的单元格。如果列中有标题,那么您也可以使用
.AutoFilter
对搜索字符串上的单元格进行筛选,然后在筛选的范围内循环。That将快得多!想象一下。您的Excel列有50k条记录。假设只有两个单元格有
123
。在当前场景中,您的循环将运行50k次,以检查单元格是否有
123
。如果您使用自动筛选,那么您的循环将只运行2次!!!我当然喜欢使用
特殊单元格e、 测试它不是空的总是好的。@Doug:如果测试的第一个单元格确实是文本字符串,则无需测试运行时错误。这就是编辑的重点。@Xonal:不客气。