Replace cleverly values in a cell with macros using regex?

时间:2015-06-30 13:42:06

标签: regex excel vba excel-vba

I've got the following macro :

Sub MacroClear()

Dim wbD As Workbook, _
    wbC As Workbook, _
    wsD As Worksheet, _
    wsC As Worksheet, _
    DicC() As Variant, _
    Dic() As String, _
    ValToReplace As String, _
    IsInDic As Boolean

Set wbD = Workbooks.Open("D:\Users\me\Documents\macro\Dictionnary", ReadOnly:=True)

Set wbC = Workbooks("FileToTreat.xlsm")

Set wsD = wbD.Worksheets("Feuil1")

Set wsC = wbC.Worksheets("draft")

ReDim DicC(1, 0)

For i = 1 To wsD.Range("C" & wsD.Rows.Count).End(xlUp).Row
    Dic = Split(wsD.Cells(i, 3), ";")
    ValToReplace = Trim(wsD.Cells(i, 2))
    For k = LBound(Dic) To UBound(Dic)
        IsInDic = False
        For l = LBound(DicC, 2) To UBound(DicC, 2)
            If LCase(DicC(1, l)) <> Trim(LCase(Dic(k))) Then
                'No match
            Else
                'Match
                IsInDic = True
                Exit For
            End If
        Next l
        If IsInDic Then
            'Don't add to DicC
        Else
            DicC(0, UBound(DicC, 2)) = Trim(Dic(k))
            DicC(1, UBound(DicC, 2)) = ValToReplace
            ReDim Preserve DicC(UBound(DicC, 1), UBound(DicC, 2) + 1)
        End If
    Next k
Next i

ReDim Preserve DicC(UBound(DicC, 1), UBound(DicC, 2) - 1)
wbD.Close
Erase Dic

    For l = LBound(DicC, 2) To UBound(DicC, 2)
        Cells.Replace What:="*" & Trim(DicC(0, l)) & "*", _
             Replacement:=Trim(DicC(1, l)), _
             LookAt:=xlPart, _
             SearchOrder:=xlByRows, _
             MatchCase:=False, _
             SearchFormat:=False, _
             ReplaceFormat:=False
    Next l


Erase DicC
Set wbD = Nothing
Set wbC = Nothing
Set wsD = Nothing
Set wsC = Nothing

End Sub

I'll try to explain : It takes from the dictionnary my "words to replace" (column C), all separated by a ";", and my "primary words" (column B).

image http://img11.hostingpics.net/pics/403257dictionnary.png

Then it searches in all the cells of my "file to treat" (via Cells.Replace), if it finds something in column C of my dictionnary, it replaces it with what's in column B.

But now that I've got "SCE" in my column C (For Sony Computer Entertainment, to be replaced by Sony in column B), even when SCE is in a word (for example : ascend), it replaces the word with Sony. I don't want to replace it if it's inside a word...

In Java, I'd have done it easily with p = Pattern.compile("[^a-zA-Z]"+keyword+"[^a-zA-Z]", Pattern.CASE_INSENSITIVE); but I have no idea how to solve this problem in VBA. I tried some things but it didn't work, had errors etc. so I came back to the start.

1 个答案:

答案 0 :(得分:0)

所以我在replace方法中更改了一些参数并为你的所有单元格提出了一个循环,你只需设置正确的列(在第二个命题中:这里B = 2)。

参数:

LookAt:=xlWhole 'To search for whole expression
SearchOrder:=xlByColumns 'Search in column
MatchCase:=True 'Will look for the expression with the same casing (not sure about this word...)

尝试以下方法之一:

For l = LBound(DicC, 2) To UBound(DicC, 2)
    Cells.Replace What:="*" & Trim(DicC(0, l)) & "*", _
         Replacement:=Trim(DicC(1, l)), _
         LookAt:=xlWhole, _
         SearchOrder:=xlByColumns, _
         MatchCase:=True, _
         SearchFormat:=False, _
         ReplaceFormat:=False
Next l

或者在每个单元格上使用循环:

For l = LBound(DicC, 2) To UBound(DicC, 2)
    For k = 1 To wsC.Rows(wsC.Rows.Count).End(xlUp).Row
        wsC.Cells(i, 2).Replace What:="*" & Trim(DicC(0, l)) & "*", _
             Replacement:=Trim(DicC(1, l)), _
             LookAt:=xlWhole, _
             SearchOrder:=xlByColumns, _
             MatchCase:=True, _
             SearchFormat:=False, _
             ReplaceFormat:=False
    Next k
Next l