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

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

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

Восстановить пароль
Повторная активизация e-mail

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

Ответ
 
Опции темы Поиск в этой теме
Старый 04.12.2012, 13:11   #1
cw_o
Пользователь
 
Регистрация: 25.10.2009
Сообщений: 92
По умолчанию Заменить один стиль другим

Нужно заменить стиль "А" на стиль "B". Оба эти стиля есть в документе, но только стиль "B" - в шаблоне.
Как делаю: выделяю все вхождения стиля "А", применяю стиль "B", удаляю стиль "А".
Нужно это автоматизировать, т.к. таких пар стилей много. Не могу найти способ для выделения всех вхождений стиля в текст документа.
cw_o вне форума Ответить с цитированием
Старый 05.12.2012, 11:20   #2
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

Выделять вхождения стиля макросом не получится, уже обсуждалось. Нужно делать поиск по одному стилю и заменять на другой. Пары замены занести в массивы, чтобы перебирать в цикле, как-то так:
Код:
    Dim s1, s2, i As Integer
    s1 = Array("style1", "style2")
    s2 = Array("style11", "style22")
    For i = LBound(s1) To UBound(s1)
        With ActiveDocument.Range.Find
            .ClearFormatting
            .Text = ""
            .Style = s1(i)
            .Replacement.Style = s2(i)
            .Execute Replace:=wdReplaceAll
        End With
    Next i
Лучше день потерять — потом за пять минут долететь!©

Последний раз редактировалось viter.alex; 05.12.2012 в 11:22.
viter.alex вне форума Ответить с цитированием
Старый 05.12.2012, 14:34   #3
cw_o
Пользователь
 
Регистрация: 25.10.2009
Сообщений: 92
По умолчанию

Отлично работает, спасибо)
Только встроенные стили вроде не хочет заменять.

Последний раз редактировалось cw_o; 05.12.2012 в 14:50.
cw_o вне форума Ответить с цитированием
Старый 31.12.2012, 18:07   #4
Скрипт
Форумчанин
 
Регистрация: 24.12.2012
Сообщений: 776
По умолчанию

viter.alex, сообщение #2, нужно ли делать .ClearFormatting?
Скрипт вне форума Ответить с цитированием
Старый 31.12.2012, 23:23   #5
viter.alex
Балуюсь кодами
Участник клуба
 
Аватар для viter.alex
 
Регистрация: 09.01.2009
Сообщений: 1,837
По умолчанию

При работе с Range, в принципе, не нужно, но поскольку производим замену в цикле, то нужно делать очистку условий форматирования искомого текста, чтобы один цикл поиска не влиял на другой.
С Новым годом!
Лучше день потерять — потом за пять минут долететь!©
viter.alex вне форума Ответить с цитированием
Старый 01.01.2013, 04:10   #6
Скрипт
Форумчанин
 
Регистрация: 24.12.2012
Сообщений: 776
По умолчанию

viter.alex, в каждом витке цикла с переменной "i" создаётся новый объект "Find". Поэтому никакого влияния не может быть одного поиска на другой поиск.
Код:
    For i = LBound(s1) To UBound(s1)
        'В строке с "With" в оперативной памяти компьютера
        'создаётся объект "Find".
        With ActiveDocument.Range.Find
            .ClearFormatting
            .Text = ""
            .Style = s1(i)
            .Replacement.Style = s2(i)
            .Execute Replace:=wdReplaceAll
        End With
        'После строки с "End With" объект "Find"
        'удаляется из оперативной памяти компьютера.
    Next i

Последний раз редактировалось Скрипт; 01.01.2013 в 14:19.
Скрипт вне форума Ответить с цитированием
Старый 01.01.2013, 04:48   #7
Скрипт
Форумчанин
 
Регистрация: 24.12.2012
Сообщений: 776
По умолчанию

Предложу вот такую схему для поиска чего-либо:
Код:
Sub Procedure_1()

    Dim oFind As Word.Find
    
    'Создаём объект "Find" и даём ему имя "oFind".
    Set oFind = ActiveDocument.Range.Find
    
    'Указываем, какой текст ищем.
    oFind.Text = "text1"
    
    'С помощью цикла ищем все вхождения искомого слова.
    Do
        
        'Осуществляем поиск.
        'Если найдено.
        If oFind.Execute = True Then
            
            'Делаем какое-нибудь действие с найденным словом.
            'Я вывожу в Immediate Window.
            Debug.Print oFind.Parent.Text
            
            'Если слово было найдено, то "Range" изменился.
            '"Range" сначала был целый документ, а затем "Range"
            'стал фрагментом документа, содержащим искомое слово.
            'Поэтому нужно указать диапазон поиска.
            '"Parent" представляет собой диапазон, где ведётся поиск.
            oFind.Parent.SetRange Start:=oFind.Parent.End, End:=ActiveDocument.Range.End
            
        Else
        
            'Выходим из цикла, когда больше не находится текст.
            Exit Do
        
        End If
    
    Loop
    
End Sub
Преимущества этой схемы:
  1. нет связи с диалоговым окном "Найти и заменить";
  2. каждый раз не создаётся в оперативной памяти компьютера объект "Find". Не знаю, какая от этого польза, но вроде логично это не делать несколько раз, т.к. при создании объекта происходит несколько действий, что по идее должно замедлять работу кода;
  3. после каждого поиска поиск не ведётся снова во всём документе, а начинается с найденнго слова и до конца документа.

Последний раз редактировалось Скрипт; 01.01.2013 в 08:41.
Скрипт вне форума Ответить с цитированием
Старый 01.01.2013, 14:16   #8
Скрипт
Форумчанин
 
Регистрация: 24.12.2012
Сообщений: 776
По умолчанию

То же самое, что и в сообщении #7, только раздельное использование диапазона, где осуществляется поиск, и объекта "Find". Может так будет проще писать код.
Код:
Sub Procedure_1()

    Dim myFindRange As Word.Range
    Dim myFind As Word.Find
    
    'Создаём диапазон, в котором будем искать.
    'Диапазон нужно создавать, т.к. команда "Find"
    'изменяет диапазон, если было найдено искомое.
    'И дальше поиск не возможен.
    'Будем вести поиск в основной части документа
    '(есть ещё колонтитулы, сноски и другое).
    Set myFindRange = ActiveDocument.Range
    
    'Создаём объект "Find" и даём ему имя "myFind".
    Set myFind = myFindRange.Find
    
    'Указываем, какой текст ищем.
    myFind.Text = "text1"
    
    'С помощью цикла ищем все вхождения искомого слова.
    Do
        
        'Если найдено.
        If myFind.Execute = True Then
            
            'Делаем какое-нибудь действие с найденным словом.
            'Я вывожу в Immediate Window.
            Debug.Print myFind.Parent.Text
            
            'Если слово было найдено, то диапазон "myFindRange" изменился.
            '"myFindRange" сначала был целый документ, а затем "myFindRange"
            'стал фрагментом документа, содержащим искомое слово.
            'Поэтому нужно указать диапазон поиска.
            myFindRange.SetRange Start:=myFindRange.End, End:=ActiveDocument.Range.End
            
        Else
        
            'Выходим из цикла, когда больше не находится текст.
            Exit Do
        
        End If
    
    Loop
    
End Sub
Скрипт вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Заменить в строке один символ на другой (assembler) fuzo Помощь студентам 1 06.05.2013 12:11
как заменить одно значение в ячейке другим Arassir SQL, базы данных 2 06.03.2012 13:35
Заменить один символ на другой Jim Hart Общие вопросы C/C++ 2 14.01.2012 19:28
Заменить один символ на другой EvilCry Помощь студентам 1 16.11.2011 17:08
Можно ли строить графики один под другим в TeeChart 8? Зойберг Компоненты Delphi 5 11.05.2010 13:59