Используя регулярное выражение в Excel, могу ли я выполнить некоторую арифметику для сопоставленного шаблона перед заменой сопоставленной строки? - PullRequest
2 голосов
/ 07 октября 2011

Я использую `VBscript.RegExp``, чтобы найти и заменить с помощью регулярного выражения. Я пытаюсь сделать что-то вроде этого:

Dim regEx
Set regEx = CreateObject("VBScript.RegExp")
regEx.Pattern = "ID_(\d{3})"
regEx.IgnoreCase = False
regEx.Global = True
regEx.Replace(a_cell.Value, "=HYPERLINK(A" & CStr(CInt("$1") + 2) )

т.е. У меня есть ячейки с такими вещами, как ID_006, и я хочу заменить содержимое такой ячейки гиперссылкой на ячейку A8. Поэтому я сопоставляю три цифры, а затем хочу добавить 2 к этим цифрам, чтобы получить правильную строку с гиперссылкой.

Но часть CStr(CInt("$1") + 2) не работает. Любые предложения о том, как я могу заставить его работать?

Ответы [ 3 ]

1 голос
/ 08 октября 2011

Я опубликовал данные баллы

  • Вы должны проверить на соответствие, прежде чем пытаться заменить
  • из вашего текущего кода Глобал избыточен, так как вы можете добавить 1 гиперссылку (1 совпадение) в ячейку
  • Ваш текущий код примет частичное совпадение строк. Если вы хотите избежать ID_9999, тогда вы сопоставляете всю строку, используя ^ и $. Эта версия запускает меня, вы можете вернуться к своей текущей модели с .Pattern = "ID_(\d{3})"
  • Обычно при добавлении гиперссылки необходим видимый адрес. Код Белое делает это (с манипулированием строк в одном кадре)

Код, приведенный ниже, работает на A1: A10 (образец показывает дамп до B1: B10 для до и после коэффициента)

 Sub ParseIt()
    Dim rng1 As Range
    Dim rng2 As Range
    Dim regEx
    Set rng1 = Range([a1], [a10])
    Set regEx = CreateObject("VBScript.RegExp")
    With regEx
        'match entire string
        .Pattern = "^ID_(\d{3})$"
        'match anywhere
       ' .Pattern = "ID_(\d{3})"
        .IgnoreCase = False
        For Each rng2 In rng1
            If .test(rng2.Value) Then
            'use Anchor:=rng2.Offset(0, 1) to dump one column to the right)
                ActiveSheet.Hyperlinks.Add Anchor:=rng2, Address:="", SubAddress:= _
                                           Cells(.Replace(rng2.Value, "$1") + 2, rng2.Column).Address, TextToDisplay:=Cells(.Replace(rng2.Value, "$1") + 2, rng2.Column).Address
            End If
        Next
    End With
End Sub

enter image description here

1 голос
/ 07 октября 2011

Это потому, что: "=HYPERLINK(A" & CStr(CInt("$1") + 2) оценивается один раз, когда код выполняется, а не один раз для каждого совпадения.

Вам нужно захватить и обработать матч следующим образом;

a_cell_Value = "*ID_006*"
Set matches = regEx.Execute(a_cell_Value)
Debug.Print "=HYPERLINK(A" & CLng(matches(0).SubMatches(0)) + 2 & ")"

>> =HYPERLINK(A8)

Или, если они все в формате ?? _ NUM;

a_cell_Value = "ID_11"
?"=HYPERLINK(A" & (2 + val(mid$(a_cell_Value, instr(a_cell_Value,"_") +1))) & ")"
=HYPERLINK(A13)
0 голосов
/ 07 октября 2011

Строка -

regEx.Replace(a_cell.Value, "=HYPERLINK(A" & CStr(CInt("$1") + 2) )

не будет работать, поскольку VBA попытается выполнить CInt для буквенной строки "$ 1", а не для совпадения с вашим RegEx.

Это сработало бы, если бы вы сделали замену в 2 шага, что-то вроде этого -

Dim a_cell
a_cell = Sheets(1).Cells(1, 1)
Dim regEx
Set regEx = CreateObject("VBScript.RegExp")
regEx.Pattern = "ID_(\d{3})"
regEx.IgnoreCase = False
regEx.Global = True
a_cell = regEx.Replace(a_cell, "$1")
Sheets(1).Cells(1, 1) = "=HYPERLINK(A" & CStr(CInt(a_cell) + 2) & ")"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...