Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 10.09.2011, 21:26   #1
bdfy
Форумчанин
 
Регистрация: 12.11.2009
Сообщений: 258
По умолчанию Регулярные выражения. найти заменить по условию

есть вот такое вот к примеру выражение в виде строки.
Код:
(" & [5!$B$83] & "·(" & [5!$B$98] & "+" & [5!$B$99] & "+" & [5!$B$100] & "))/(" & [5!$B$97] & "+" & [5!$B$98] & "+" & [5!$B$99] & "+" & [5!$B$100] & ")+(" & [5!$B$89] & "·(" & [5!$B$99] & "+" & [5!$B$100] & ")+" & [5!$B$94] & "·" & [5!$B$100] & ")/(" & [5!$B$97] & "+" & [5!$B$98] & "+" & [5!$B$99] & "+" & [5!$B$100] & ")
[5!$B$98] и т.п. это ссылки на ячейки. необходимо сделать следующие:
посмотреть что в ячейке и если там записано комплексное число взять в скобки. наваял следующий код
Код:
objRegExp.Pattern = "\[[^\[\]]+\]" 'Шаблон поиска
                  Set objSubMatches = objRegExp.Execute(s)
                  
                  
            For j = objSubMatches.Count - 1 To 0 Step -1
                     Set s1 = objSubMatches(j)
                     s2 = Right(Left(s1, Len(s1) - 1), Len(s1) - 2)
                     'Debug.Print "!!!!s1 " & s1
                     s3 = ActiveWorkbook.ActiveSheet.Evaluate("=" & s2)
                     If InStr(s3, "j") > 0 Then
                       ' Debug.Print "!!!! s3 " & s3
                        objRegExp.Pattern = "[^ 0-9A-Z]"
                        s4 = objRegExp.Replace(s1, "\$&")
                      '  Debug.Print "!!!! s4 " & s4
                        objRegExp.Pattern = s4
                        s = objRegExp.Replace(s, Chr(34) & "("" & " & "$&" & " & "")" & Chr(34))
                     End If
                     
            Next
проблема вот в чем - в таком виде добавление скобок происходит каждый раз ко всем одинаковым выражениям. и в итоге если [5!$B$83] встречается 4 раза, то и скобки лишние будут четырежды
bdfy вне форума Ответить с цитированием
Старый 11.09.2011, 12:59   #2
Watcher_1
Форумчанин
 
Аватар для Watcher_1
 
Регистрация: 22.06.2011
Сообщений: 325
По умолчанию

Не сильно вникая в ваш макрос пришло на ум следующее
просто при каждом цикле заменяйте двойные скобки (( и )) на ( и )
Заказать макрос можно на сайте http://excel4you.ru/
Watcher_1 вне форума Ответить с цитированием
Старый 12.09.2011, 13:14   #3
bdfy
Форумчанин
 
Регистрация: 12.11.2009
Сообщений: 258
По умолчанию

ну просто двойные скобки менять нельзя - ибо они могут вполне по делу стоять например
((a+jb)-(v+jd))*b
bdfy вне форума Ответить с цитированием
Старый 12.09.2011, 13:40   #4
Watcher_1
Форумчанин
 
Аватар для Watcher_1
 
Регистрация: 22.06.2011
Сообщений: 325
По умолчанию

А если сделать поиск того выражения которое вы хотите вставить если оно уже есть в определенной позиции то не вставлять?
Заказать макрос можно на сайте http://excel4you.ru/
Watcher_1 вне форума Ответить с цитированием
Старый 12.09.2011, 14:14   #5
bdfy
Форумчанин
 
Регистрация: 12.11.2009
Сообщений: 258
По умолчанию

плохо представляю синтаксис для этого. там слишком много кавычек.
вот если бы regex отлавливал только первое уникальное имя... добавить массив уже просмотренных ссылок и с ним сверять ? как то неизящно. знатоки regex - может проще есть решение ?
bdfy вне форума Ответить с цитированием
Старый 12.09.2011, 14:20   #6
bdfy
Форумчанин
 
Регистрация: 12.11.2009
Сообщений: 258
По умолчанию

собственно сделал. за мозговой штурм спасибо
Код:
 Dim found As String
 
            For j = objSubMatches.Count - 1 To 0 Step -1
                     Set s1 = objSubMatches(j)
                     s2 = Right(Left(s1, Len(s1) - 1), Len(s1) - 2)
                     'Debug.Print "!!!!s1 " & s1
                     s3 = ActiveWorkbook.ActiveSheet.Evaluate("=" & s2)
                     If InStr(s3, "j") > 0 And InStr(found, s3) = 0 Then
                        found = found & s3
                        'Debug.Print "!!!! s3 " & s3
                        objRegExp.Pattern = "[^ 0-9A-Z]"
                        s4 = objRegExp.Replace(s1, "\$&")
                        'Debug.Print "!!!! s4 " & s4
                        objRegExp.Pattern = s4
                        s = objRegExp.Replace(s, Chr(34) & "("" & " & "$&" & " & "")" & Chr(34))
                        Debug.Print "ñêîáêè " & s
                     End If
                     
            Next
bdfy вне форума Ответить с цитированием
Старый 12.09.2011, 15:52   #7
Казанский
Старожил
 
Аватар для Казанский
 
Регистрация: 31.12.2010
Сообщений: 2,133
По умолчанию

Я не спец по Regexp, но ИМХО достаточно применить его один раз, а потом работать с коллекцией совпадений. Вот программа на этапе разработки:
Код:
Sub bb()
Dim s$, objMatches As Object, x As Object, s1$, i&
Dim objRegExp As New RegExp             'подключите "Microsoft VBScript Regual Expressions"
                                        'в Tools-References, чтобы работал IntelliSense на этапе разработки программы

s = "([5!$B$83]·([5!$B$98]+[5!$B$99]+[5!$B$100]))/([5!$B$97]+[5!$B$98]+[5!$B$99]+[5!$B$100]+([5!$B$89]·([5!$B$99]+[5!$B$100])+[5!$B$94]·[5!$B$100])/([5!$B$97]+[5!$B$98]+[5!$B$99]+[5!$B$100])"

objRegExp.Pattern = "\[([^\[\]]+)\]"    'Шаблон поиска, в скобках - "Submatch"
objRegExp.Global = True                 'найти все вхождения
i = 1                                   'номер текущей позиции в исходной строке
Debug.Print s

Set objMatches = objRegExp.Execute(s)
For Each x In objMatches
    s1 = s1 & Mid$(s, i, x.FirstIndex + 1 - i)  'перенести текст между предыдущим и текущим вхождением
'Debug.Print s1
    If InStr(Evaluate(x.SubMatches(0)), "j") > 0 Then
        s1 = s1 & "(" & x & ")"         'добавить Match со скобками
    Else
        s1 = s1 & x                     'добавить Match без скобок
    End If
'Debug.Print s1
    i = x.FirstIndex + x.Length + 1
Next
s1 = s1 & Mid$(s, i)                    'перенести остаток текста
Debug.Print s1
End Sub
Окончательный вид:
Код:
Sub bb1()
Dim s$, x, s1$, i&

s = "([5!$B$83]·([5!$B$98]+[5!$B$99]+[5!$B$100]))/([5!$B$97]+[5!$B$98]+[5!$B$99]+[5!$B$100]+([5!$B$89]·([5!$B$99]+[5!$B$100])+[5!$B$94]·[5!$B$100])/([5!$B$97]+[5!$B$98]+[5!$B$99]+[5!$B$100])"

With CreateObject("vbscript.regexp")
    .Pattern = "\[([^\[\]]+)\]"    'Шаблон поиска, в скобках - "Submatch"
    .Global = True                 'найти все вхождения
    For Each x In .Execute(s)
        s1 = s1 & Mid$(s, i + 1, x.FirstIndex - i)  'перенести текст между предыдущим и текущим вхождением
        If InStr(Evaluate(x.SubMatches(0)), "j") > 0 Then
            s1 = s1 & "(" & x & ")"         'добавить Match со скобками
        Else
            s1 = s1 & x                     'добавить Match без скобок
        End If
        i = x.FirstIndex + x.Length
    Next
    s1 = s1 & Mid$(s, i + 1)                  'перенести остаток текста
End With
Debug.Print s1
End Sub
exceleved@yandex.ru Яндекс.Деньги: 410011500007619

Последний раз редактировалось Казанский; 12.09.2011 в 16:03.
Казанский вне форума Ответить с цитированием
Старый 14.09.2011, 02:08   #8
bdfy
Форумчанин
 
Регистрация: 12.11.2009
Сообщений: 258
По умолчанию

спасибо. красивое решение.
bdfy вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
регулярные выражения Gen_r_questions PHP 15 25.04.2011 11:56
регулярные выражения vvsh PHP 3 22.04.2011 17:09
Регулярные выражения Syltan JavaScript, Ajax 3 24.04.2010 23:08
нужно в edit точку заменить запятой используя регулярные выражения Pasha1983 Общие вопросы Delphi 7 02.04.2010 13:12
Регулярные выражения adwaer Общие вопросы .NET 4 24.02.2010 17:38