简体   繁体   中英

find and replace for specific range in VBA

I am using the following code for finding the curr_symbol and replacing it with new_symbol. Even though I have specified in the code that it should do so within the specific row numbers, it applies the find and replace to all the rows in the selected sheet, which is not what I want.

Sub find_replace()
Dim curr_symbol, new_symbol As String
Dim row_num, last_row As Integer
row_num = ActiveSheet.Cells(1, "A").Value 'row_num=9
last_row = ActiveSheet.Cells(2, "A").Value 'last_row=11

Do While row_num < last_row
      curr_symbol = ".ABC130301"
    new_symbol = ActiveSheet.Cells(row_num, "E").Value 'new_symbol=".BAC130306"
    With ActiveSheet.UsedRange
        .Replace curr_symbol, new_symbol, xlPart
    End With
row_num = row_num + 1
Loop
End Sub

I even tried replacing the With ActiveSheet.UsedRange....End With with the following statement, but that also replaces the curr_symbol in all the rows.

ActiveSheet.Cells.Replace What:=curr_symbol, Replacement:=new_symbol, LookAt:=xlPart, _
                              SearchOrder:=xlByRows, MatchCase:=False, _
                              SearchFormat:=False, ReplaceFormat:=False

How can I fix this so it only replaces the string in the specified rows.

I'm assuming the range you're interested in replacing is column A, from row_num to last_row . Try replacing this:

With ActiveSheet.UsedRange
    .Replace curr_symbol, new_symbol, xlPart
End With

With this:

Cells(row_num, 1).Replace curr_symbol, new_symbol, xlPart

No matter where you place ActiveSheet.UsedRange it always refers to the entire used area of the active sheet. It is a collection containing all used cells and other cells in the same rows and columns as the used cells. It's not contextual in the way you've used it (ie it doesn't refer to the range relevant to your loop). The Replace method will be applied to every individual cell in the UsedRange .

Similarly with ActiveSheet.Cells ; this always refers to the collection of every cell in the active sheet. My suggestion is the same as ActiveSheet.Cells(row_num, 1) , specifying an individual cell to apply the Replace method to.

No longer answering your question:

As an aside, the following line:

Dim curr_symbol, new_symbol As String

declares curr_symbol as a Variant, and new_symbol as a String. The same applies for your next line of declarations (the Integers). No, I don't like this declaration behaviour either. You have to specify a type for every variable. Here's how I tend to declare:

Dim curr_symbol As String, _
    new_symbol As String

Additionally, Excel internally stores all Integer types as Long types internally. Declaring as an Integer only restricts their values, not the amount of memory they consume. Unless you specifically want to limit the value of your integers, I recommend changing all Integer declarations to Long:

Dim last_row As Integer

Is just as memory consuming as:

Dim row_num as Long

But probably a little slower, if there's any speed difference at all.

The "UsedRange" range that you are using is the entire spreadsheet that you have used. Your replace is being applied to your entire spreadsheet.

I would create a range that you want to do the replace in like:

Dim MyRange as Range
Set MyRange = Range("B7:C9")

Then I would do the replace on this range.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM