检查列中的值以更改多个行值

时间:2014-10-20 17:56:14

标签: excel vba excel-vba

我有一个包含大量数据的电子表格(超过100,000行,列a-h)。

我知道F列中的二十个或更多不同的值是错误的,我知道它们应该是什么。例如,每次出现的“pif”应为“pig”,“coe”应为“cow”等。

(请注意,每个都有多个不正确的值(即多个“pif”)。)

我正在构建一个宏来完成并单独修复它们,这部分可以工作:

Sub FixColumnF()

ActiveSheet.Columns("F").Replace What:= _
        "pif", _
        Replacement:="pig", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:= _
        False, SearchFormat:=False, ReplaceFormat:=False
ActiveSheet.Columns("F").Replace What:= _
        "coe", _
        Replacement:="cow", LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:= _
        False, SearchFormat:=False, ReplaceFormat:=False

...

End Sub

我的问题是A列用于跟踪错误,其中一个是F列中的错误值。如何删除A列中的值以指示每行中的错误不再存在F列中的值是固定的吗?

我对vba非常陌生,所以非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

我能想到两种方式。

方式1

使用.Find/.FindNext循环遍历所有单词“pif”的单元格。在该循环中,不仅要替换单词,还要编辑Col A中的值。例如(未经测试)

Sub Sample()
    Dim oRange As Range, aCell As Range, bCell As Range
    Dim ws As Worksheet
    Dim SearchString As String, FoundAt As String

    On Error GoTo Whoa

    Set ws = Worksheets("Sheet1")
    Set oRange = ws.Columns(5) '<~~ Column 5

    SearchString = "pif"
    NewString = "pig"

    Set aCell = oRange.Find(What:=SearchString, LookIn:=xlValues, _
                LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                MatchCase:=False, SearchFormat:=False)

    If Not aCell Is Nothing Then
        Set bCell = aCell

        '~~> Change value in Cell F
        aCell.Value = Replace(aCell.Value, SearchString, NewString)
        '~~> Change value in Cell A
        aCell.Offset(, -5).Value = "Rectified"

        Do
            Set aCell = oRange.FindNext(After:=aCell)

            If Not aCell Is Nothing Then
                If aCell.Address = bCell.Address Then Exit Do
                aCell.Value = Replace(aCell.Value, SearchString, NewString)
                aCell.Offset(, -5).Value = "Rectified"
            Else
                Exit Do
            End If
        Loop
    End If

    Exit Sub
Whoa:
    MsgBox Err.Description
End Sub

方式2

使用自动过滤器对单词“pif”上的Col F进行过滤。循环通过Col A中的所有单元格并添加相关消息。删除自动过滤,然后运行原始代码(在您的问题中提到)在Col F中进行替换。请参阅THIS链接,了解如何使用自动过滤器。

答案 1 :(得分:1)

Siddharth在我测试/打字时发布了他的建议。我的第一个建议是他的第一个建议的简单变化,并没有提供我能看到的优势。但是,我的第二个建议与他的任何一个建议都不同,可能是合适的。

你需要循环每次出现&#34; pif&#34;和&#34; coe&#34;如果你想做一些额外的事情,发现每个错误的价值。下面的代码显示了如何替换&#34; pif&#34; by&#34; pig&#34;然后用列&#34; A&#34;做一些事情。如果您喜欢这种技术,则需要复制此代码以用于&#34; coe&#34;和&#34;牛&#34;。

Option Explicit
Sub ReplaceFaultyA()

  Dim Rng As Range

  ' It is best to avoid "ActiveSheet" in case the use has called the
  ' macro with the wrong worksheet active. Probably this is not likely
  ' in this case but I like to follow good practice even if it not not
  ' necessary
  With Worksheets("Data")

    Do While True

      ' Are you sure all your Find parameters are correct? For example,
      ' "LookAt:=xlPart" means than "pif" in the middle of a word will
      ' be replaced by "pig". "LookAt:=xlWhole" may better match your
      ' requirement. I suggest you look up the specification of Find
      ' and consider the implications of each parameter.
      Set Rng = .Columns("F").Find(What:="pif")
      If Rng Is Nothing Then
        ' No [more] occurrences of "pif" in column F
        Exit Do
      Else
        ' Occurrences of "pif" found in column F
        .Cells(Rng.Row, "F") = "pig"
        ' Amend column ""A" of Rng.Row as necessary
      End If
   Loop

  End With

End Sub

复制我的循环并替换&#34; pif&#34;和&#34;猪&#34; by&#34; coe&#34;和&#34;牛&#34;如果只有两个替换,重复可能是最简单的解决方案。但是,如果有很多替代品,下面的技术可能是更好的选择。

在此代码中,我将错误值和匹配的良好值放在数组中。使用这种方法,一个替换代码块可以处理无限数量的替换,前提是A列的操作对于每个替换都是相同的。

Sub ReplaceFaultyB()

  Dim InxValue As Long
  Dim Rng As Range
  Dim ValueFaulty() As Variant
  Dim ValueGood() As Variant

  ' The code below assumes there same number of entries in both arrays.
  ' You can add extra entries to the two arrays as necessary.
  ' This assumes the action for column "A" is the same for each faulty value
  ValueFaulty = Array("pif", "coe", "appme")
  ValueGood = Array("pig", "cow", "apple")

  With Worksheets("Data")

    For InxValue = LBound(ValueFaulty) To UBound(ValueFaulty)

      Do While True
        Set Rng = .Columns("F").Find(What:=ValueFaulty(InxValue))
        If Rng Is Nothing Then
          ' No [more] occurrences of this faulty value in column F
          Exit Do
        Else
          ' Occurrences of faulty value found in column F
          .Cells(Rng.Row, "F") = ValueGood(InxValue)
          ' Amend column ""A" of Rng.Row as necessary
        End If
     Loop

   Next InxValue

  End With

End Sub