| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Программирование, связанное с MS Office > Макрос для исправления слитых переносов |
| Автор: Guest45 15.6.2015, 23:52 |
| Собственно, задача: Имеется текст в коде ASCII, в котором перенесенные слова слиты, так что значок переноса оказывается посреди слова. А поскольку это .txt и форматирующей структуры нет, то такие переносы ничем не отличаются от минусов и тире. Ручная правка исключается - файл довольно велик, Ворд находит несколько тыс. сочетаний буква-дефис-буква. Непосредственно удалить их нельзя, так как пострадают нормальные слова, пишущиеся через дефис, их в русском языке довольно много. Необходимо написать макрос для Ворда (пригодный начиная от Офиса-2000). Идея состоит в следующем: Берем слово в строковую переменную, исключаем дефис и результат сличаем со словарем Ворда. Если орфоконтроль не находит ошибки, вносим исправленное слово в текст. Если слово без дефиса опознается как ошибочное, выбрасываем результат, оставляем в тексте как есть. В чем прошу помощь. Я неплохо знаю бейсики, в т.ч. VB6, но VBA включает некоторые специфические команды, по которым и прошу подсказки. Итак: 1) Как взять в строковую переменную очередное слово из текста? 2) Как проверить содержимое строковой переменной при помощи системы орфографии Ворда? (Достаточно получить булевское значение: верно слово, или нет.) 3) Как заменить слово в тексте на содержимое строковой переменной? Прошу примеры написания этих команд в теле макроса. Со строковыми переменными работать умею, в этом проблем не ожидается. Прочитать и записать файл могу тоже, но хотелось бы работать с текстом в окне Ворда, это нагляднее. |
| Автор: Akina 16.6.2015, 09:16 | ||
|
| Автор: Guest45 16.6.2015, 18:37 |
| Такая конструкция цикла мной еще не использовалась. Сделал проверочный .txt размером в два абзаца, открыл Вордом-2000. Сделал макрос, скопипастил в него ваш пример как есть. Запустил. Макрос быстро провернулся, никаких изменений в тексте не произвел. Тогда заремил строку с орфографической проверкой и последующий IF по Result, оставил в цикле только второй (вложенный) IF. Предположив, что теперь все слова проверочного текста должны быть заменены словом Replaced . Запустил. Никаких изменений текста. Заремил и второй IF, оставил в цикле только строчку oneWord.Text = "Replaced " Запустил. Макрос завис. Вот это непонятно почему - ведь область не изменялась; по достижении конца текста цикл должен был остановиться независимо - изменялись ли слова, или нет. Растолкуйте результаты, плиз. |
| Автор: Akina 16.6.2015, 18:48 |
Ну чё на кофейной гуще-то гадать? Пройдите в режиме трассировки и посмотрите, как изменяются значения переменных. Заодно не поленитесь в текст добавить пару заведомо несуществующих слов - для контраста... |
| Автор: Guest45 16.6.2015, 18:59 |
| Разумеется, в тексте преднамеренные ошибки есть. Чтобы на первых порах отстроиться от вопросов к грамматике. Отладка "поблочно". Надо же начинать с простейшего. Но и оно не получилось пока. А oneWord.Text это что? - указатель на слово в тексте? дополнено: Итак, проверку грамматики пока заремил, оставил только вложенный IF. Поставил точку останова на If Trim(oneWord.Text) <> "Replaced" Then Посмотрел, что oneWord.Text в ней имеет значение квадратик в кавычках. (Кодов меньше 20h в тексте нет, кроме 0Dh, 0Ah. Проверено в HEX-просмотре FAR-ом.) После продолжения макрос снова на эту точку не попадает, то есть цикл после одного прохода завершается. |
| Автор: Akina 16.6.2015, 22:55 |
| В тексте нет преднамеренных ошибок. Более того - поскольку я не юзаю эти функции ежедневно, я написАл кейс и проверил, что он работает правильно. Приведённый код - копипаст РАБОЧИЙ ПРОВЕРЕННЫЙ. Среда - Ворд 2007. И если у тебя он сбоит, я скорее поверю в избыточную кривизну твоих рук, уж извини... |
| Автор: Guest45 17.6.2015, 16:21 |
| преднамеренно ошибки были мной вставлены в проверочный текст, который скармливался макросу Пример, сорь, пока не работает почему-то. Про кривизну рук - допускаю конечно, но Ctrl-C, Ctrl-V, тут как бы кривить-то особено и не в чем... Ворд работает, не глючит, претензий не было. Система - XP SP2, rus, но вроде на язык высокого уровня влиять не должна? Помогайте кто может. |
| Автор: Akina 17.6.2015, 16:37 |
| Guest45, давай так. Выкладывай файл до запуска макроса и после. Я у себя обработаю тот же файл. Сравним. Укажи сразу, что не нравится - если воспроизведётся, постараюсь понять, где собака порылась. |
| Автор: Guest45 17.6.2015, 17:17 |
| Проверочный текст в смысле? - без проблем, прицепляю ниже. Но он один и тот же, ни одного изменения макросом не вносится. Я подозреваю, что макрос по нему вообще не пробегает - уже писал выше, что цикл почему-то заканчивается после первого же прохода. |
| Автор: Akina 18.6.2015, 08:50 |
| Воспроизводим по шагам. 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 |
| Автор: Guest45 18.6.2015, 14:55 | ||||
| Отчет о проделанной работе: 1. Открываю проверочный текст Вордом. (В окне Ворда - проверочный текст.) 2. Меню Сервис / Макрос / Макросы 3. Копипаст имени MyReplace 4. Создать. 5. Копипаст кода Результат:
6. Закрыл окно VBA. 7. Сервис / Макрос / Макросы 8. Выбор MyReplace 9. Выполнить. Меню закрывается, текст остается прежним, больше ничего не происходит. Ни одного изменения не появилось. Вариант 2 Сервис / Макрос / Редактор Visual Basic Insert / Module открывается чистое окно нового модуля Создаю в нем следующий код:
Запускаю из меню VBA: кнопка Run В тексте появились замененные слова Replaced. Итак, второй вариант работает, а первый почему-то нет. Поэксериментирую со вторым, о результатах отпишусь. Сенкс! Примечание. Вначале (т.е. вчера) и макрос запускал кнопкой Run не закрывая VBA, но макрос и таким запуском не работал. |
| Автор: Guest45 18.6.2015, 15:26 |
| Кажется я выяснил, в чем отличие. Модуль создается в разделе Project, а макрос - в разделе Normal (по умолчанию "из Активных шаблонов") Когда переключил на создание макроса из "Документ1", тогда он создался в разделе Project и заработал. Хотя, записанные нажатия клавиш и т.п., создаются тоже в разделе Normal, но при этом работают. Подозреваю, что не будет работать чтение - видимо тогда макрос вместо текста из окна пытается читать файл Normal.dot . Спасибо за помощь! Остальное, я надеюсь, самостоятельно докручу. |
| Автор: Guest45 18.6.2015, 18:26 | ||
| Не показывалось это, или я не знал, где посмотреть. Пришлось догадкой доходить))))) Версия "альфа" макроса для удаления слившихся переносов будет выглядеть вот так:
Полностью еще не обкатана, возможны какие-нибудь глюки, но пока у меня сработало нормально. Гран мерси за оказанную помощь! |
| Автор: Akina 19.6.2015, 08:42 |
Для скалярных переменных и скалярных свойств - достаточно навести курсор мыша на переменную и секунду подождать. В редакторе VBA в меню View есть Locals Window. Там ты можешь смотреть содержимое любых видимых в текущем контексте переменных. Удобно для объектных - можно просмотреть любые свойства (вернее, их значения) объекта. А ещё там есть Watch Window. Там можно смотреть значения не только для переменных и свойств, но и для любых выражений. НУ и тупой вывод значений (а также выполнение любых однострочных выражений - в т.ч. и для изменения значений) в Immediate Window тоже никто не отменяет. |
| Автор: Guest45 19.6.2015, 09:11 |
| Первые впечатления. У меня проверка орфографии не знает букву "ё". Так что перед проверкой в переменной надо бы их заменить на "е", но это сравнительно редкий случай, и в более новых Офисах наверное этой проблемы нет. Кажется, что "итератор" после каждой правки восстанавливает свою позицию, заново отсчитывая от самого начала текста. Так что, чем дальше в лес тем толще партизаны, тем больше замедляется работа. Поэтому большие тексты лучше обрабатывать, разделив их на фрагменты. Зависит конечно от компьютера; у меня разумный максимум составил приблизительно 50 вордовых страниц. Свой проблемный файл обработал. Некоторые огрехи остались, когда перенос попадал например в имена собственные и тогда не был удален, или слово уже содержало грамматическую ошибку. Но эти единичные случаи вполне поправимы уже в ручную. На этом тему считаю исчерпанной, всем спасибо! |
| Автор: Akina 19.6.2015, 11:15 | ||
Ну вообще по уму надо делать итерацию по словам не как по коллекции (при этом действительно возникают определённые побочные эффекты), а как по массиву. Не вижу особой сложности в переделке кода. Только не делай его циклом FOR - попадёшь на выход за пределы массива, организуй его как DO - LOOP или как WHILE - WEND с проверкой на достижение ТЕКУЩЕГО конца массива. Это на самом деле работа UNDO-буфера. |