Модераторы: mihanik

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Макрос для исправления слитых переносов, помогите в написании. Word, VBA. 
:(
    Опции темы
Guest45
Дата 15.6.2015, 23:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



Собственно, задача:

Имеется текст в коде ASCII, в котором перенесенные слова слиты, так что значок переноса оказывается посреди слова.
А поскольку это .txt и форматирующей структуры нет, то такие переносы ничем не отличаются от минусов и тире.
Ручная правка исключается - файл довольно велик, Ворд находит несколько тыс. сочетаний буква-дефис-буква.
Непосредственно удалить их нельзя, так как пострадают нормальные слова, пишущиеся через дефис, их в русском языке довольно много.
Необходимо написать макрос для Ворда (пригодный начиная от Офиса-2000).

Идея состоит в следующем:
Берем слово в строковую переменную, исключаем дефис и результат сличаем со словарем Ворда.
Если орфоконтроль не находит ошибки, вносим исправленное слово в текст.
Если слово без дефиса опознается как ошибочное, выбрасываем результат, оставляем в тексте как есть.

В чем прошу помощь.
Я неплохо знаю бейсики, в т.ч. VB6, но VBA включает некоторые специфические команды, по которым и прошу подсказки.
Итак:

1) Как взять в строковую переменную очередное слово из текста?

2) Как проверить содержимое строковой переменной при помощи системы орфографии Ворда?
(Достаточно получить булевское значение: верно слово, или нет.)

3) Как заменить слово в тексте на содержимое строковой переменной?

Прошу примеры написания этих команд в теле макроса.  user posted image

Со строковыми переменными работать умею, в этом проблем не ожидается. Прочитать и записать файл могу тоже, но хотелось бы работать с текстом в окне Ворда, это нагляднее.
 
PM MAIL   Вверх
Akina
Дата 16.6.2015, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Код

Dim oneWord As Range, Result As Boolean

For Each oneWord In ThisDocument.Words
  Result = Application.CheckSpelling(oneWord)
  If Not Result Then
    If Trim(oneWord.Text) <> "Replaced" Then
      oneWord.Text = "Replaced "
    End If
  End If
Next






--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Guest45
Дата 16.6.2015, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



Такая конструкция цикла мной еще не использовалась.

Сделал проверочный .txt размером в два абзаца, открыл Вордом-2000.
Сделал макрос, скопипастил в него ваш пример как есть.
Запустил.
Макрос быстро провернулся, никаких изменений в тексте не произвел.

Тогда заремил строку с орфографической проверкой и последующий IF по Result,
оставил в цикле только второй (вложенный) IF.
Предположив, что теперь все слова проверочного текста должны быть заменены словом Replaced .
Запустил.
Никаких изменений текста.

Заремил и второй IF, оставил в цикле только строчку
oneWord.Text = "Replaced "

Запустил.
Макрос завис.
Вот это непонятно почему - ведь область не изменялась;
по достижении конца текста цикл должен был остановиться независимо - изменялись ли слова, или нет.

Растолкуйте результаты, плиз.



PM MAIL   Вверх
Akina
Дата 16.6.2015, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Guest45 @  16.6.2015,  19:37 Найти цитируемый пост)
заремил 

 smile Нахуа? smile 
Ну чё на кофейной гуще-то гадать? Пройдите в режиме трассировки и посмотрите, как изменяются значения переменных. Заодно не поленитесь в текст добавить пару заведомо несуществующих слов - для контраста...



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Guest45
Дата 16.6.2015, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



Разумеется, в тексте преднамеренные ошибки есть.

Цитата(Akina @ 16.6.2015,  18:48)
Цитата(Guest45 @  16.6.2015,  19:37 Найти цитируемый пост)
заремил 

 smile Нахуа? smile 
 Чтобы на первых порах отстроиться от вопросов к грамматике.
Отладка "поблочно". Надо же начинать с простейшего. Но и оно не получилось пока.

А oneWord.Text это что? - указатель на слово в тексте?


дополнено:
Итак, проверку грамматики пока заремил, оставил только вложенный IF.

Поставил точку останова на     If Trim(oneWord.Text) <> "Replaced" Then
Посмотрел, что oneWord.Text в ней имеет значение квадратик в кавычках. (Кодов меньше 20h в тексте нет, кроме 0Dh, 0Ah. Проверено в HEX-просмотре FAR-ом.)

После продолжения макрос снова на эту точку не попадает, то есть цикл после одного прохода завершается.




Это сообщение отредактировал(а) Guest45 - 16.6.2015, 19:54
PM MAIL   Вверх
Akina
Дата 16.6.2015, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



В тексте нет преднамеренных ошибок. Более того - поскольку я не юзаю эти функции ежедневно, я написАл кейс и проверил, что он работает правильно. Приведённый код - копипаст РАБОЧИЙ ПРОВЕРЕННЫЙ. Среда - Ворд 2007.  И если у тебя он сбоит, я скорее поверю в избыточную кривизну твоих рук, уж извини...


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Guest45
  Дата 17.6.2015, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



преднамеренно ошибки были мной вставлены в проверочный текст, который скармливался макросу smile

Пример, сорь, пока не работает почему-то.  Про кривизну рук - допускаю конечно, но Ctrl-C, Ctrl-V,  тут как бы кривить-то особено и не в чем...
Ворд работает, не глючит, претензий не было. Система - XP SP2, rus, но вроде на язык высокого уровня влиять не должна?
Помогайте кто может.

PM MAIL   Вверх
Akina
Дата 17.6.2015, 16:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Guest45, давай так. Выкладывай файл до запуска макроса и после. Я у себя обработаю тот же файл. Сравним. Укажи сразу, что не нравится - если воспроизведётся, постараюсь понять, где собака порылась.


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Guest45
Дата 17.6.2015, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



Проверочный текст в смысле? - без проблем, прицепляю ниже. Но он один и тот же, ни одного изменения макросом не вносится.
Я подозреваю, что макрос по нему вообще не пробегает - уже писал выше, что цикл почему-то заканчивается после первого же прохода.


Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  test.txt 0,42 Kb
PM MAIL   Вверх
Akina
Дата 18.6.2015, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Воспроизводим по шагам.
1) Запустить Word.
2) Открыть - text.txt
3) Разработчик - Макросы
4) Имя = MyReplace
5) Создать
6) Вставляем приведённый выше код
7) Закрываем окно VBA
8) Разработчик - Макросы
9) MyReplace - Выполнить 
После выполнения этих операций я вижу в тексте слово "Replaced" в количестве 6 штук.

Добавлено через 2 минуты и 42 секунды
Как вариант, вместо шагов 3-5:
3) Открыть редактор VBA
4) Вставить - модуль
5) Вставить вышеприведённый код, обрамив его в Private Sub MyReplace() ... End Sub


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Guest45
  Дата 18.6.2015, 14:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



Отчет о проделанной работе:

1. Открываю проверочный текст Вордом.
(В окне Ворда - проверочный текст.)

2. Меню Сервис / Макрос / Макросы

3. Копипаст имени MyReplace

4. Создать.

5. Копипаст кода

Результат:
Код

Sub MyReplace()
'
' MyReplace Макрос
' Макрос создан18.06.2015
'

Dim oneWord As Range, Result As Boolean

For Each oneWord In ThisDocument.Words
  Result = Application.CheckSpelling(oneWord)
  If Not Result Then
    If Trim(oneWord.Text) <> "Replaced" Then
      oneWord.Text = "Replaced "
    End If
  End If
Next

End Sub


6. Закрыл окно VBA.

7.  Сервис / Макрос / Макросы

8. Выбор MyReplace

9. Выполнить.

Меню закрывается, текст остается прежним, больше ничего не происходит.
Ни одного изменения не появилось.

Вариант 2
Сервис / Макрос / Редактор Visual Basic

Insert / Module
открывается чистое окно нового модуля

Создаю в нем следующий код:
Код

Private Sub MyReplace() 
Dim oneWord As Range, Result As Boolean

For Each oneWord In ThisDocument.Words
  Result = Application.CheckSpelling(oneWord)
  If Not Result Then
    If Trim(oneWord.Text) <> "Replaced" Then
      oneWord.Text = "Replaced "
    End If
  End If
Next
End Sub


Запускаю из меню VBA: кнопка Run
В тексте появились замененные слова Replaced.

Итак, второй вариант работает, а первый почему-то нет. 

Поэксериментирую со вторым, о результатах отпишусь.
Сенкс!



Примечание.
Вначале (т.е. вчера) и макрос запускал кнопкой Run не закрывая VBA, но макрос и таким запуском не работал.

PM MAIL   Вверх
Guest45
Дата 18.6.2015, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



Кажется я выяснил, в чем отличие.
Модуль создается в разделе Project,
а макрос - в разделе Normal (по умолчанию "из Активных шаблонов")
Когда переключил на создание макроса из "Документ1", тогда он создался в разделе Project и заработал.

Хотя, записанные нажатия клавиш и т.п., создаются тоже в разделе Normal, но при этом работают.
Подозреваю, что не будет работать чтение - видимо тогда макрос вместо текста из окна пытается читать файл Normal.dot .

Спасибо за помощь!
Остальное, я надеюсь, самостоятельно докручу.

PM MAIL   Вверх
Akina
Дата 18.6.2015, 17:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Guest45 @  18.6.2015,  16:26 Найти цитируемый пост)
Когда переключил на создание макроса из "Документ1", тогда он создался в разделе Project и заработал.

Теперь понятен источник твоих проблем. При создании кода в normal.dot итератор ThisDocument.Words перебирал, как это не странно, почему-то слова именно из Normal.dot.
И кто мешал это увидеть сразу, при трассировке?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Guest45
  Дата 18.6.2015, 18:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



Не показывалось это, или я не знал, где посмотреть. Пришлось догадкой доходить)))))


Версия "альфа" макроса для удаления слившихся переносов будет выглядеть вот так:
Код

Sub UnDivision()
'
' UnDivision Макрос
' Удаление слитых переносов
'
Dim oneWord As Range, i As Long

If MsgBox("Этот макрос удалит слитые переносы из текста" + vbCrLf + "   Лицензия: бесплатно." + vbCrLf + "Авторские права: forum.vingrad.ru", 1) = 2 Then Exit Sub

i = 0: Word1$ = "": Word2$ = ""
For Each oneWord In ThisDocument.Words
  Word3$ = oneWord.Text
  If Word2$ = "-" And Trim(Word1$) <> "" And Right$(Word1$, 1) <> " " Then
    Word3$ = Trim(Word1$) + Trim(Word3$)
    For j = 1 To Len(Word3$)
      If Asc(Mid$(Word3$, j, 1)) < 192 Then
        Word3$ = "неправитьцифры"
        Exit For
      End If
    Next j
    If Application.CheckSpelling(Word3$, , 0) = True Then
      ThisDocument.Words(i) = ""
      i = i - 2
    End If
  End If
  i = i + 1
  Word1$ = Word2$
  Word2$ = Word3$
Next

End Sub


Полностью еще не обкатана, возможны какие-нибудь глюки, но пока у меня сработало нормально.

Гран мерси за оказанную помощь!




Это сообщение отредактировал(а) Guest45 - 18.6.2015, 22:45
PM MAIL   Вверх
Akina
Дата 19.6.2015, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Guest45 @  18.6.2015,  19:26 Найти цитируемый пост)
я не знал, где посмотреть

Для скалярных переменных и скалярных свойств - достаточно навести курсор мыша на переменную и секунду подождать.
В редакторе VBA в меню View есть Locals Window. Там ты можешь смотреть содержимое любых видимых в текущем контексте переменных. Удобно для объектных - можно просмотреть любые свойства (вернее, их значения) объекта.
А ещё там есть Watch Window. Там можно смотреть значения не только для переменных и свойств, но и для любых выражений.
НУ и тупой вывод значений (а также выполнение любых однострочных выражений - в т.ч. и для изменения значений) в Immediate Window тоже никто не отменяет. 


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Guest45
Дата 19.6.2015, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 199
Регистрация: 24.5.2009

Репутация: нет
Всего: нет



Первые впечатления.

У меня проверка орфографии не знает букву "ё". Так что перед проверкой в переменной надо бы их заменить на "е", но это сравнительно редкий случай, и в более новых Офисах наверное этой проблемы нет.

Кажется, что "итератор" после каждой правки восстанавливает свою позицию, заново отсчитывая от самого начала текста.
Так что, чем дальше в лес тем толще партизаны, тем больше замедляется работа.
Поэтому большие тексты лучше обрабатывать, разделив их на фрагменты.
Зависит конечно от компьютера; у меня разумный максимум составил приблизительно 50 вордовых страниц.

Свой проблемный файл обработал. Некоторые огрехи остались, когда перенос попадал например в имена собственные и тогда не был удален, или слово уже содержало грамматическую ошибку.
Но эти единичные случаи вполне поправимы уже в ручную.

На этом тему считаю исчерпанной, всем спасибо!

PM MAIL   Вверх
Akina
Дата 19.6.2015, 11:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 26
Всего: 454



Цитата(Guest45 @  19.6.2015,  10:11 Найти цитируемый пост)
Кажется, что "итератор" после каждой правки восстанавливает свою позицию, заново отсчитывая от самого начала текста.

Ну вообще по уму надо делать итерацию по словам не как по коллекции (при этом действительно возникают определённые побочные эффекты), а как по массиву. Не вижу особой сложности в переделке кода. Только не делай его циклом FOR - попадёшь на выход за пределы массива, организуй его как DO - LOOP или как WHILE - WEND с проверкой на достижение ТЕКУЩЕГО конца массива.
Цитата(Guest45 @  19.6.2015,  10:11 Найти цитируемый пост)
чем дальше в лес, тем больше замедляется работа.
Это на самом деле работа UNDO-буфера.



--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Программирование, связанное с MS Office"
mihanik staruha

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами



  • Несанкционированная реклама на форуме запрещена
  • Пожалуйста, давайте своим темам осмысленный, информативный заголовок. Вопль "Помогите!" таковым не является.
  • Чем полнее и яснее Вы изложите проблему, тем быстрее мы её решим.
  • Оставляйте свои записи в "Книге отзывов о работе администрации"
  • А вот тут лежит FAQ нашего подраздела


Если Вам понравилась атмосфера форума, заходите к нам чаще!
С уважением mihanik и staruha.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Программирование, связанное с MS Office | Следующая тема »


 




[ Время генерации скрипта: 0.0884 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.