Методичка | Скачать |   English   Почта | Telegram | В контакте | Facebook | Twitter | Контакт
ГЛАВНАЯ СКРИНШОТЫ МАКРОСЫ ИСТОРИЯ ТВОРЧЕСТВО ИНСТРУКЦИИ

ПАМЯТКА

КОНТАКТ НОВОСТИ
Поиск | Единицы | Константы | Символы | Язык | Команды | Стили | Поля | idMSO | API | Макросы | Советы

Методичка  - пакет макросов Word

вниз
Макрос ПоЗа Пакет макросов для форматирования документов Microsoft Word.
Примеры, советы, информация по макросам, VBA и Microsoft Office.
Автор: © Александр, 2007-2023, alex@mtdmacro.ru
Макрос Дрейф
 

Поисковые шаблоны Word

ПОИСК С ПОДСТАНОВОЧНЫМИ ЗНАКАМИ

  • буква: [A-Za-zА-ЯЁа-яё]
  • прописная буква: [A-ZА-ЯЁ]
  • строчная буква: [a-zа-яё]
  • буква или цифра: [A-Za-zА-ЯЁа-яё0-9]
  • буква кириллицы: [А-ЯЁа-яё]
  • прописная буква кириллицы: [А-ЯЁ]
  • строчная буква кириллицы: [а-яё]
  • буква латиницы: [A-Za-z]
  • прописная буква латиницы: [A-Z]
  • строчная буква латиницы: [a-z]
  • слово: <[! ^s^t^13]{1;}>
  • слово прописными: <[A-ZА-ЯЁ]@['A-ZА-ЯЁ]@>
  • слово кириллицы: <[А-ЯЁа-яё]@['А-ЯЁа-яё]@>
  • слово кириллицы строчными: <[а-яё]@['а-яё]@>
  • слово кириллицы с заглавной: <[А-ЯЁ]['а-яё]@>
  • слово кириллицы с заглавной или прописными: <[А-ЯЁ]['А-ЯЁа-яё]@>
  • слово латиницы: <[A-Za-z]@['A-Za-z]@>
  • слово латиницы с заглавной: <[A-Z]['a-z]{1;}>
  • слово латиницы с заглавной или прописными: <[A-Z]['A-Za-z]{1;}>
  • инициал русский: <[А-ЯЁ].
  • инициал английский: <[A-Z].
  • прописная буква или цифра: [A-ZА-ЯЁ0-9]
  • цифра (арабская): [0-9]
  • цифры: [0-9]{1;}
  • число: <[0-9]{1;}>
  • цифры в начале слова: <[0-9]{1;}
  • цифры в конце слова: [0-9]{1;}>
  • четырехзначный год: <[12][0-9]{3}>
  • римская цифра прописными: [IVXLCDM]
  • римская цифра строчными: [ivxlcdm]
  • римское число прописными: <[IVXLCDM]{1;}>
  • небольшое римское число прописными: <[IVX]{1;}>
  • арабская или римская цифра: [0-9IVXLCDM]
  • цепочка обычных пробелов: [ ]{1;}
  • цепочка пробелов: [ ^s]{1;}
  • цепочка знаков табуляции: [^t]{1;}
  • пробел, неразрывный пробел, табуляция: [ ^s^t]
  • пустое место: [ ^s^t]{1;}
  • любое тире или дефис: [\-^=^+^~]
  • символы Интернета (адрес сайта, почты): [A-Za-z0-9_.\-]
  • видимый знак (использовать осторожно): [! ^t^s^m^n^-^l^13]
  • невидимый знак: [ ^t^s^m^n^-^l^13]
  • символы с кодом от 33 до 255: [\!-я]
Примечание. В приведенных выше шаблонах, в тексте вида "{1;}", символ точка с запятой (;) является настраиваемым. Данный символ задается в региональных настройках операционной системы, параметром "Разделитель элементов списка". Точка с запятой используется по умолчанию в русской версии Windows, в английской же принят символ запятая. См. раздел "Язык".

наверх

Единицы измерения

Centimeters (cм) - Сантиметры (см)

  • 1 cm = 10 mm = 28.35 pt = 0.49 in = 2.36 line = 2.36 pica
  • Visual Basic: Points = CentimetersToPoints(Centimeters)

Millimeters (mm) - Миллиметры (мм)

  • 1 mm = 0.1 cm = 2.84 pt = 0.04 in = 0.24 line = 0.24 pica
  • Visual Basic: Points = MillimetersToPoints(Millimeters)

Points (pt) - Пункты (пт)

  • 1 pt = 0.035 cm = 0.35 mm = 0.014 in = 0.083 line = 0.083 pica
  • Visual Basic:
    Centimeters = PointsToCentimeters(Points)
    Millimeters= PointsToMillimeters(Points)
    Inches = PointsToInches(Points)
    Lines = PointsToLines(Points)
    Picas = PointsToPicas(Points)

Inches (in) - Дюймы (д)

  • 1 in = 2.54 cm = 25.4 mm = 72 pt = 6 line = 6 pica
  • Visual Basic: Point = InchesToPoint(Inches)

Lines (line) - Строки

  • 1 line = 0.42 cm = 4.23 mm = 12 pt = 0.17 in = 1 pica
  • Visual Basic: Points = LinesToPoints(Lines)

Picas (pica) - Пика

  • 1 pica = 0.42 cm = 4.23 mm = 12 pt = 0.17 in = 1 line
  • Visual Basic: Points = PicasToPoints(Picas)

наверх

Константы Word 2019, 2016, 2013, 2010, 2007, 2003

ШРИФТ (Font)

  • размер шрифта (Size)
    • минимальный и максимальный размер: от 1 до 1638 пт
    • шаг (минимальный) размера: 0.5 пт
  • интервал шрифта (Spacing)
    • минимальный и максимальный интервал: от -1584 до 1584 пт
    • шаг (минимальный) интервала: 0.05 пт
    • стандартный интервал: 0 пт
  • смещение шрифта (Position)
    • минимальное и максимальное смещение: от -1584 до 1584 пт
    • шаг (минимальный) смещения: 0.05 пт
    • стандартное смещение: 0 пт
  • масштаб шрифта (Scaling)
    • минимальный и максимальный масштаб: от 1 до 600 %
    • шаг (минимальный) масштаба: 1 %
    • стандартный масштаб: 100 %

ПАРАГРАФ (ParagraphFormat)

  • отступ (LeftIndent, RightIndent, FirstLineIndent):
    • от -55.87 до 55.87 см
    • шаг отступа (минимальный): 0.05
  • межстрочный интервал (LineSpacing):
    • от 0.35 до 1584 пт, минимальный шаг 0.05
    • диалог Абзац:
      • минимум, пт: от 0 до 1584, минимальный шаг 0.05
      • точно, пт: от 0.7 до 1584, минимальный шаг 0.05
      • множитель, ин: от 0.06 до 132, минимальный шаг 0.01

СПИСОК (ListFormat)

  • номер нумерованного списка (StartAt): максимум - 32767
  • уровней списка (ListLevels): максимум - 9
  • префикс номера уровня списка (NumberFormat): %

ТАБЛИЦА (Table)

  • столбцов в таблице (Columns): максимум - 63
  • строк в таблице (Rows): максимум - 32767
  • ширина таблицы в процентах (PreferredWidth)
    • максимальная: 600 %
    • шаг (минимальный): 0.5 %
  • ширина таблицы в сантиметрах (PreferredWidth)
    • максимальная: 55.87 см
    • шаг (минимальный): 0.01 см
  • высота ячейки или строки: от 1 до 1584 пт
  • ширина ячейки или строки: минимум - 11 пт

РАЗНОЕ

  • максимум подчиненных стилей в цепочке (параметр "Основан на стиле"): 9 стилей
  • максимальная длина полей найти (Find.Text) и заменить (Find.Replacment.Text): 255 знаков
  • имя закладки (Bookmark.Name):
    • начинается с буквы или подчеркивания (скрытая)
    • может содержать: буквы, цифры, подчеркивание
    • регистр букв не учитывается
    • максимальная длина - 40 знаков
  • масштаб объекта (ScaleWidth, ScaleHeight): максимальный - 10675 %
  • масштаб окна (View.Zoom.Percentage): от 10 до 500 %
  • длина списка последних открытых документов (RecentFiles.Maximum):
    • 50 в Word 2007 и новее
    • 9 в Word 2003
  • максимальное количество отображаемых ошибок:
    • орфографических (SpellingErrors): 2000
    • грамматических (GrammaticalErrors): 2000
  • римское число: максимальное - 32766
  • дата (as Date):
    • от 1 января 100 года до 31 декабря 9999 года
    • от -657434 до 2958465

наверх

Коды символов

СПЕЦСИМВОЛЫ WORD

  • Visual Basic:
    • код_ASCII = Asc(символ)
    • символ = Chr(код_ASCII)
    • Код ASCII = от 0 до 255
  • Коды специальных символов, используемых в документах:
  • Dec Hex VBA Описание
    1 &h1   Объект
    2 &h2   Сноска
    9 &h9 vbTab Табуляция
    11 &hB vbVerticalTab Разрыв строки
    12 &hC   Разрыв страницы или раздела
    13 &hD vbCr Знак абзаца
    13 &hD   Разделитель стилей. Действует как знак абзаца, но следующий абзац не переносится на новую строку. Используется при оформлении оглавлений и т.п.
    13 + 7 &hD + &h7   Последний символ (Character) ячейки или строки таблицы
    14 &hE   Разрыв колонки
    19, 21 &h13, &h15   Начало и конец поля (Field)
    30 &h1E   Неразрывный дефис
    31 &h1F   Мягкий перенос
    160 &hA0   Неразрывный пробел
  • Символы (Character) означающие конец параграфа (Paragraph)
    • Chr(13) - конец параграфа
    • Chr(13) + Chr(7) - конец последнего параграфа ячейки таблицы
    • Chr(12) - разрыв раздела (код как и у разрыва страницы)
  • Символы (Character) не нарушающие целостности параграфа (Paragraph)
    • Chr(11) - разрыв строки
    • Chr(12) - разрыв страницы (код как и у разрыва раздела)
    • Chr(14) - разрыв колонки

СИМВОЛЫ ЮНИКОД (UNICODE)

В Word символы Unicode наиболее полно поддерживаются шрифтом "Arial Unicode MS". Данный шрифт поставляется с Microsoft Office, содержит приблизительно 40 000 алфавитных знаков. По причине своего большого размера, "Arial Unicode MS" следует использовать только в том случае, когда нельзя использовать шрифты, специально предназначенные для различных систем письма. Если шрифт "Arial Unicode MS" не установлен, его необходимо установить.

Полностью ознакомиться со стандартом Unicode можно на сайте www.unicode.org

  • Visual Basic
    • код_Unicode = AscW(символ)
    • символ = ChrW(код_Unicode)
    • Код Unicode = от -32768 до 65535
  • Основная латиница - Basic Latin (0000-007А)
    • &H9 (9) - табуляция
    • &HB (11) - разрыв строки
    • &HC (12) - разрыв страницы или раздела
    • &HD (13) - конец параграфа
    • &HE (14) - разрыв колонки
    • &H1E (30) - неразрывный дефис
    • &H1F (31) - мягкий перенос
    • &H20 (32) - пробел
    • &H21 (33) - восклицательный знак
    • &H22 (34) - прямая парная кавычка
    • &H24 (36) - доллар
    • &H25 (37) - проценты
    • &H27 (39) - апостроф
    • &H28 (40) - левая скобка
    • &H29 (41) - правая скобка
    • &H2A (42) - звездочка
    • &H2B (43) - плюс
    • &H2C (44) - запятая
    • &H2D (45) - тире
    • &H2E (46) - точка
    • &H2F (47) - косая черта
    • &H30 (48) - цифра 0
    • &H31 (49) - цифра 1
    • &H39 (57) - цифра 9
    • &H3A (58) - двоеточие
    • &H3B (59) - точка с запятой
    • &H3C (60) - меньше
    • &H3D (61) - равно
    • &H3E (62) - больше
    • &H3F (63) - знак вопроса
    • &H5B (91) - левая квадратная скобка
    • &H5C (92) - обратная косая черта
    • &H5D (93) - правая квадратная скобка
    • &H5D (94) - крышка
    • &H5F (95) - подчеркивание
    • &H60 (96) - тупое ударение
    • &H7B (123) - левая фигурная скобка
    • &H7C (124) - вертикальная линия
    • &H7D (125) - правая фигурная скобка
    • &H41 (65) - латинское A
    • &H5A (90) - латинское Z
    • &H61 (97) - латинское a
    • &H7A (122) - латинское z
  • Латиница-1 - Latin-1 (0080-00FF)
    • &HA0 (160) - неразрывный пробел
    • &HA7 (167) - знак параграфа
    • &HA9 (169) - "(C)"
    • &HAB (171) - левая парная угловая кавычка
    • &HAC (172) - знак переноса
    • &HAD (173) - тире
    • &HAE (174) - "(R)"
    • &HB0 (176) - градус
    • &HB1 (177) - плюс-минус
    • &HB4 (180) - острое ударение
    • &HB7 (183) - точка по центру
    • &HBB (187) - правая парная угловая кавычка
    • &HBC (188) - 1/4
    • &HBD (189) - 1/2
    • &HBE (190) - 3/4
    • &HD7 (215) - знак умножения (крестик)
    • &HF7 (247) - знак деления (тире между точек)
    • &HC0 (192) - буквы латиницы 1: начало
    • &HF6 (246) - буквы латиницы 1: конец
    • &HF8 (248) - буквы латиницы 2: начало
    • &HFF (255) - буквы латиницы 2: конец
  • Объединенные диакритические знаки - Combining Diacritical Marks (0300-036F)
    • &H300 (768) - модификатор: тупое ударение
    • &H301 (769) - модификатор: острое ударение
    • &H303 (771) - модификатор: тильда
  • Греческий основной - Greek and Coptic (0370-03FF)
    • &H391 (913) - АЛЬФА
    • &H3A9 (937) - ОМЕГА
    • &H3B1 (945) - альфа
    • &H3C9 (969) - омега
  • Кириллица - Cyrillic (0400-04FF)
    • &H401 (1025) - кириллическое Ё
    • &H410 (1040) - кириллическое А
    • &H42F (1071) - кириллическое Я
    • &H430 (1072) - кириллическое а
    • &H44F (1103) - кириллическое я
    • &H451 (1105) - кириллическое ё
  • Знаки пунктуации - General Punctuation (2000-206F)
    • &H200C (8204) - мягкая неразрывная связка
    • &H200D (8205) - неразрывная связка
    • &H2012 (8210) - тире
    • &H2013 (8211) - короткое тире
    • &H2014 (8212) - очень длинное тире
    • &H2015 (8213) - горизонталь
    • &H2018 (8216) - левая кавычка
    • &H2019 (8217) - правая кавычка
    • &H201A (8218) - нижняя кавычка 9
    • &H201B (8229) - верхняя кавычка 9
    • &H201C (8220) - левая парная кавычка
    • &H201D (8221) - правая парная кавычка
    • &H201E (8222) - нижняя парная кавычка
    • &H2022 (8226) - жирный кружок
    • &H2026 (8230) - многоточие
    • &H2027 (8231) - точка по центру
    • &H2030 (8240) - на тысячу (промилле) "o/oo"
    • &H2031 (8241) - на десять тысяч "o/ooo"
    • &H2032 (8242) - штрих
    • &H2033 (8243) - двойной штрих
    • &H2039 (8249) - одиночная левая угловая кавычка
    • &H203A (8250) - одиночная правая угловая кавычка
  • Буквоподобные символы - Letterlike Symbols (2100-214F)
    • &H2116 (8470) - №
    • &H2122 (8482) - "(ТМ)"
  • Числовые формы - Number Forms (2150–218F)
    • &H2153 (8531) - 1/3
    • &H2154 (8532) - 2/3
  • Стрелки - Arrows (2190–21FF)
    • &H2190 (8592) - <-
    • &H2192 (8594) - >
    • &H2194 (8596) - <->
    • &H21D2 (8658) - =>
    • &H21D4 (8660) - <=>
  • Математические операторы - Mathematical Operators (2200-22FF)
    • &H2219 (8729) - умножить
    • &H22C5 (8901) - точка по центру
    • &H2212 (8722) - минус
    • &H221E (8734) - знак бесконечности
    • &H2248 (8776) - приблизительно
    • &H2260 (8800) - не равно
    • &H2261 (8801) - равносильно
    • &H2264 (8804) - меньше или равно
    • &H2265 (8805) - больше или равно
  • Рамки - Box Drawing (2500-257F)
    • &H2500 (9472) - тонкая горизонталь
    • &H2501 (9473) - жирная горизонталь
  • Геометрические фигуры - Geometric Shapes (25A0-25FF)
    • &H25A0 (9632) - черный квадрат
    • &H25BA (9658) - треугольник вправо
    • &H25C4 (9668) - треугольник влево
    • &H25CB (9668) - пустой круг
    • &H25CF (9679) - черный кружок
  • Разные символы - Miscellaneous Symbols (2600-26FF)
    • &H2666 (9830) - черный ромб

наверх

Язык и региональные параметры Word

МЕХАНИЗМ ОПРЕДЕЛЕНИЯ ЯЗЫКА

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

  • Доступные для редактирования языки.
  • Язык, используемый по умолчанию в данном документе (определяется соответствующим параметром форматирования обычного стиля в активном шаблоне).
  • Активный язык клавиатуры (если установлены несколько языков клавиатуры и раскладок клавиатуры).

Определение языка производится одновременно с работой над текстом и не мешает пользователю. В новых документах проверка осуществляется с самого начала по мере ввода каждого предложения, а также при копировании или вставке в файл фрагментов текста. Если открывается документ, который ни разу не проверялся, проверке подвергается каждое предложение. Кроме того, заново проверяется любое предложение, если в него вносятся изменения. Для перезапуска распознания языка в пакет "Методичка" включен макрос M081_Правописание_Распознать_язык.

При открытии документа не проверяется текст, который уже был однажды проверен. Если языковое форматирование применяется к целым предложениям с помощью диалогового окна "Язык", это форматирование также запоминается и сохраняется до тех пор, пока в данное предложение не будут внесены изменения. Для повторной проверки текста, уже помеченного как "проверенный", в пакет "Методичка" включен макрос M082_Правописание_Перепроверить.

Даже при использовании автоматического определения языка, может потребоваться применение языкового форматирования непосредственно к тексту. Word, иногда, не различает близкие по написанию языки. В таких случаях, может быть автоматически применен неправильный языковый формат или в качестве языка, используемого по умолчанию, принят совершенно другой язык, например английский. Для решения последней проблемы в пакет "Методичка" включен макрос M080_Язык_текста.

ВЛИЯНИЕ ОПЕРАЦИОННОЙ СИСТЕМЫ

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

  • Windows: Разделитель элементов списка
    • Word: Поиск с подстановочными знаками
      • Подстановочные знаки {n;} и {n;m}, предназначенные для поиска повторений предыдущего знака или выражения. В данном случае, используется точка с запятой (;). Если же, в региональных параметрах задана запятая (,), нужно использовать ее.
      • Вышесказанное относится как к поиску через диалог, так и к поиску макросами VBA.
    • Word: Поля
      • Некоторые ключи полей требуют указания списка элементов через запятую (,) или точку с запятой (;), в зависимости от того, какие региональные параметры выбраны в Windows.
      • Например, такие поля как: = (формула); TOC (оглавление), INDEX (указатель), EQ (вставка формулы) и др.
  • Windows: Разделители целой и дробной части, групп разрядов, компонентов даты и времени, символы валют и др.
    • Word: Функции VBA, использующие формат или преобразующие из одного формата в другой
      • Например, такие функции как: Format(), CStr(), CDate(), CCur(), CDbl(), CSng() и др.
    • Word: Поля, содержащие формат числа, даты, времени и др.

Примечание. В макросах Word, для получения информации о текущих региональных настройках, используйте функцию International.

ЯЗЫК ПО УМОЛЧАНИЮ ШАБЛОНА NORMAL

Языковые параметры шаблона Normal определяют способ создания и выполнения макросов на языке Visual Basic for Applications (VBA). При старте Word и загрузке шаблона язык установки также изменяет некоторые параметры по умолчанию, зависимые от языковых параметров. Если измененный шаблон Normal с определенным языком скопировать на компьютер, настроенный на работу с другим языком, их совместимость может оказаться проблематичной. В этом случае, лучше позволить установочному процессу создать новый Normal, а затем, с помощью инструмента управления шаблонами, перенести в него настройки стилей, макросов, автотекста и панелей инструментов из шаблона, созданного ранее. При необходимости, можно переименовать подготовленный шаблон Normal и загрузить его в качестве глобального шаблона.

наверх

Встроенные команды Word

СПИСКИ КОМАНД С ОПИСАНИЕМ НА РУССКОМ ЯЗЫКЕ

ПОЛУЧЕНИЕ СПИСКА КОМАНД

  • Новый документ со списком команд Word и комбинациями быстрых клавиш, соответствующих этим командам, можно получить любым из представленных ниже способов.
    • Интерфейс:
      • Откройте диалоговое окно "Макросы" (Alt + F8).
      • В списке "Макросы из" выберите вариант "Команд Word".
      • В списке "Имя" выберите вариант "ListCommands".
      • Нажмите кнопку "Выполнить".
      • В диалоговом окне "Список команд" установите переключатель в положение "все команды Word".
      • Нажмите кнопку "OK".
    • Visual Basic: Application.ListCommands ListAllCommands:=True
  • Примечание. Список команд, отображаемый в диалоге "Макросы" или полученный с помощью ListCommands, является не полным.

ВЫПОЛНЕНИЕ КОМАНДЫ

  • Выполнить команду можно любым из представленных ниже способов.
    • Интерфейс:
      • Откройте диалоговое окно "Макросы" (Alt + F8).
      • В поле "Имя" введите имя команды.
      • Нажмите кнопку "Выполнить".
    • Visual Basic: Application.Run "Имя команды"
  • Примечание. Если новому макросу задать имя встроенной команды Word, то встроенный макрос будет заменен новым. Например, если записать новый макрос и задать для него имя FileClose, этот макрос будет связан с командой "Закрыть". После этого, при выборе команды "Закрыть", Word будет выполнять действия заданные в новом макросе.

наверх

Встроенные стили Word

  • Таблица со списком встроенных стилей Word: word_builtin_style.xlsx
    • Описаны стили Word версий: 2019, 2016, 2013, 2010, 2007, 2002/XP, 2000.
    • Информация о стилях: Русское имя, Английское имя, Primary Style Name (XML), Код / Индекс, wdBuiltinStyle.
    • Полезно знать: более 370 встроенных стилей содержит Word 2019.

наверх

Встроенные поля Word (Field)

  • Таблица со списком встроенных полей Word: word_field.xlsx
    • Описаны поля всех версий Word для Windows.
    • Информация о полях: имя, код, ключи, краткое описание, wdFieldType, Type.

наверх

idMSO

СПИСКИ CONTROL IDs И IMAGEMSO ДЛЯ MS OFFICE

наверх

Windows API

КОНСТАНТЫ, ТИПЫ, ФУНКЦИИ WINDOWS API ДЛЯ VBA

32 И 64

  • Обобщение. При разработке макроса, под разные платформы, надо учитывать что:
    • Есть старый VBA, который всегда x32.
    • Есть новый VBA 7, который может быть x64 или x32.
  • Office 2010 x64 - это первая 64-разрадная версия Office вообще.
  • Начиная с Office 2010, используется Microsoft Visual Basic For Applications 7.0 (VBA 7).
  • В VBA 7 введено две константы условной компиляции: VBA7 и Win64.
    • VBA7 проверяет, используется ли VBA 7 или более старая версия VBA.
      • VBA7 = True если используется Office 2010 или новее, False - в старых версиях.
      • Чтобы не допустить использование 64-разрядного кода в более ранних версиях Microsoft Office, используется константа VBA7.
    • Win64 проверяет, выполняется ли код как 32-разрядный или как 64-разрядный.
      • Win64 = True если используется Office 64-бит, False - 32-бит.
      • Если код для 32-разрядной версии отличается от такого же кода для 64-разрядной версии (например, в случае x64 используется LongLong, а в случае x32 версии - Long), нужно использовать константу Win64.
    • Пример:
      #If VBA7 Then
          ' Новый VBA 7
          ' Добавить PtrSafe в объявления.
          ' LongPtr вместо Long для указателей.
          #If Win64 Then
              ' Office 64
              ' LongLong вместо Long для значений, если это нужно.
          #Else
              ' Office 32
          #End If
      #Else
           ' Старый VBA, Office 32
      #End If
  • Для понимания, когда что использовать:
    • PtrSafe - обозначает, что оператор Declare совместим с 64-разрядными системами. Этот атрибут обязателен для 64-разрядных систем.
    • LongPtr - тип данных переменной, состоящей из 4 байт в 32-разрядных версиях и из 8 байт в 64-разрядных версиях Office. Это рекомендуемый способ объявления указателя или дескриптора в новом коде, а также в старом коде, если он будет выполняться в 64-разрядной версии Office. Эта возможность поддерживается только в среде выполнения VBA 7 в 32- и 64-разрядных системах. Обратите внимание, что этой переменной можно назначать числовые значения, но не числовые типы.
    • LongLong - 8-байтовый тип данных, доступный только в 64-разрядных версиях Office. Этому типу можно назначать числовые значения, но не числовые типы (чтобы избежать усечения).
    • CLngPtr - преобразует простое выражение в тип данных LongPtr.
    • CLngLng - преобразует простое выражение в тип данных LongLong.
    • VarPtr - преобразователь вариантов. Возвращает тип LongPtr для 64-разрядных версий и тип Long для 32-разрядных версий (4 байта).
    • ObjPtr - преобразователь объектов. Возвращает тип LongPtr для 64-разрядных версий и тип Long для 32-разрядных версий (4 байта).
    • StrPtr - преобразователь строк. Возвращает тип LongPtr для 64-разрядных версий и тип Long для 32-разрядных версий (4 байта).

наверх

Что такое макросы Word

О МАКРОСАХ

  • Если какая-либо задача часто выполняется в Word, ее выполнение можно автоматизировать с помощью макроса. Макрос - это набор команд и инструкций, выполняемых как одна команда.
  • Макросы часто используются для следующих целей:
    • для ускорения часто выполняемых операций редактирования или форматирования;
    • для объединения нескольких команд, например, для вставки таблицы с указанными размерами и границами и определенным числом строк и столбцов;
    • для упрощения доступа к параметрам в диалоговых окнах;
    • для автоматизации обработки сложных последовательных действий в задачах.

СОЗДАНИЕ МАКРОСОВ

  • Для создания макроса в Word существует два метода: использование средства для записи макросов и прямое программирование в редакторе Visual Basic.
  • Запись макроса.
    • В Word средство записи макросов работает как магнитофон. С его помощью записываются нажатия клавиш и кнопок мыши, которые переводятся макросом в код Microsoft Visual Basic для приложений.
    • При записи нового макроса допускается применение мыши только для выбора команд и параметров. Для записи такого действия, как выделение текста, необходимо использовать клавиатуру.
  • Создание макроса с помощью редактора Visual Basic.
    • Редактор Visual Basic позволяет писать очень мощные и сложные макросы, которые не могут быть записаны первым способом.
    • Кроме того, в редакторе Visual Basic можно получить вспомогательные сведения, помогающие при создании макроса, - в частности, справочную информацию об объектах и их свойствах.

ХРАНЕНИЕ МАКРОСОВ

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

ПОДДЕРЖКА МАКРОСОВ

  • Политика Microsoft по отношению к макросам такова: это не для серьезной работы, а только небольшое дополнение, чтобы с помощью макрорекордера слепить простенький макрос.
  • Потому, с поддержкой плохо, очень плохо. Найти серьезную справку или документацию крайне проблематично. Ошибки и глюки не правятся десятилетиями. Обновления носят вынужденный характер, а не прогрессивный. Что говорить, если VBA-редактор, с момента своего выхода, претерпел лишь косметические изменения. Редактор не поддерживает Юникод. Вообще нет информации, какую же кодировку он использует :)
  • Запасайтесь терпением, если собрались сами писать макросы.

ОБУЧЕНИЕ МАКРОСАМ

Что надо изучить, и в каком порядке, чтобы писать макросы:

  1. Научится работать в приложении Office, для которого собираетесь писать макросы. Тут связь прямая: лучше знаешь приложение - лучше пишешь макросы. Начинающие только и занимаются тем, что переводят в макросы, что сами умеют делать руками. Как встроенный макрорекордер.
  2. Освоить язык VBA (Visual Basic for Applications) - это такой упрощенный бейсик для приложений Office. Без него никуда. На нем вы будите писать. Это основа.
  3. Выучить объектную модель приложения Word, Excel, Access... Того, где вы хотите использовать VBA. Со временем, вы начнете писать макросы не просто повторяющие ручные операции, а макросы делающие те же операции оптимальным образом. Будите писать макросы делающие такое, что руками не сделать. Для создания таких макросов и нужно хорошее знание объектной модели.
  4. Изучить нестандартные приемы, методы, подходы. Это можно освоить изучая чужой опыт, код. Без знаний предыдущих пунктов, вы тут банально ничего не поймете. Крайне не советую начинать обучение с этого пункта, то есть с конца. Проще говоря: если учитесь через ж, то и макросы ваши будут оттуда же.
  5. Очень помогает знание фундаментальных наук, таких как математика, информатика. Возможно это прикладное, а возможно должно стоять первым пунктом :)

Все пункты тесно связаны между собой. Слабость в одном, будет тянуть за собой все другие. Пункты 1-3 обязательно надо освоить на начальном уровне. Далее, можно пробовать изучение на практике.

наверх

Советы по написанию макросов Word

ОПТИМИЗАЦИЯ КОДА

  • Для определения количества символов в части документа используйте свойство StoryLength или функцию Len(), но не команду Characters.Count, которая выполняется довольно долго, если символов много.
  • В проверках (If, Select и др.) сравнивайте с проверяемым значением - с тем, что должно быть.
    • Пример. При проверке на True правильно писать:
      If N <> True Then
      Часто ошибочно пишут:
      If N = False Then
      Если N имеет тип отличный от boolean, код может не сработать.
  • Оптимизация перебора массива (Array):
    • Быстро:
      For i = LBound(Array) to UBound(Array)    
      Next i
    • Медленно:
      For Each V in Array
      Next V
  • Оптимизация перебора коллекции (Collection):
    • Быстро:
      For Each V in Col
      Next V
    • Медленно:
      For i = 1 to Col.Count
          V = Col(i)
      Next i
  • При массовой проверке строк, Len(S) = 0 медленее чем S = "".
  • Быстродействие перехода по условию:
    • Оператор On ... GoSub ... на порядок быстрее чем Select Case.
    • Select Case вообще медленная проверка, If работает быстрее.
  • Оптимизация перебора символов (Character) и т.п.:
    • Медленный способ:
      Dim R As Range
      For Each R In ActiveDocument.Characters
      Next R
    • Средний способ:
      Set R = ActiveDocument.Characters.First
      Do
          Set R = R.Next
      Loop While Not (R Is Nothing)
    • Быстрый способ:
      Set R = ActiveDocument.Range(0, 0)
      Do
      Loop While R.Move = 1
  • Оптимизация перебора параграфов (Paragraph) и т.п.:
    • Медленный способ:
      Dim P As Paragraph
      For Each P In ActiveDocument.Paragraphs
      Next P
    • Средний способ:
      Set P = ActiveDocument.Paragraphs.First
      Do
          Set P = P.Next
      Loop While Not (P Is Nothing)
    • Быстрый способ:
      Dim R As Range
      Set R = ActiveDocument.Range(0, 0)
      Do While R.Move(Unit:=wdParagraph) = 1
          Set P = R.Paragraphs.First
      Loop
  • Безопасное применение цикла For Each
    • Если, в ходе обработки группы элементов документа, сама коллекция изменяется (удаляются или добавляются элементы), то циклом For Each могут быть пропущены некоторые элементы (из тех, что были при запуске цикла) .
    • Пример, где может случится пропуск, и удалены будут не все рисунки:
      Dim SH as Shape
      For Each SH in Selection.Range.ShapeRange
          SH.Delete
      Next
    • Что бы пример работал без сбоев, надо создать временную коллекцию и запомнить в ней все элементы:
      Dim COL as New Collection, SH as Shape
      For Each SH in Selection.Range.ShapeRange
          COL.Add Item:=SH
      Next
      For Each SH in COL
          SH.Delete
      Next
  • Выход из цикла For Each
    • При переборе элементов массива, с помощью цикла For Each, и досрочном выходе из цикла (например, с помощью GoTo), может случится ошибка "Run time error '10': This array is fixed or temporary locked", если дальше по коду попытаться изменить этот массив. Пример:
      For Each V in A
          GoTo 1
      Next
      1:
      A = Empty ' Здесь будет ошибка
    • Чтобы избежать ошибки, надо отказаться от Each и использовать обычный цикл. Пример:
      For i = LBound(A) to UBound(A)
          GoTo 1
      Next
      1:
      A = Empty ' Не будет ошибки
  • При обращении к объекту, впереди его имени желательно и полезно указывать его родителя. Достаточно одного - Parent.Object, но можно и всю цепочку - Parent1.Parent2.Parent3.Object.
    • Пример. В документе в редакторе VBA мы создали форму (UserForm) с именем "МояФорма", а затем, для ее запуска, в текст документа вставили кнопку (элемент управления CommandButton), которую также назвали "МояФорма", что естественно и удобно. Теперь, если в макрос нажатия кнопки вставить код МояФорма.Show, то при компиляции ошибки не будет, а вот при запуске мы ошибку получим. Правильно было написать Project.МояФорма.Show, а так мы обратились не к форме, а к кнопке. Если же хотим обратиться к кнопке, то надо писать ThisDocument.МояФорма.
  • Для назначения типов, удобно использовать специальные символы: String - $, Integer - %, Long - &, Single - !
    • Пример: Dim Строка$, Целое%, Длинное&, Вещественное!
  • Для повышения совместимости, имена констант Word лучше заменять их значениями. Это касается языков, списков, полей и др. То есть, в коде пишем 1049, а не wdRussian.
  • В математических формулах, что пишем в коде, надо использовать круглые скобки, чтобы в первую очередь выполнялись операции, уменьшающие промежуточный результат. То есть, сначала - деление и вычитание, потом - умножение и сложение. Иначе, если на каком-то этапе расчета число окажется слишком большим, получим ошибку № 6 "Overflow" - переполнение. Так же, непосредственно в формуле, можно привести тип чисел к Long, например, ибо по умолчанию имеем Integer.
    • Пример. Так будет ошибка:
      Dim V as Variant
      V = 999 * 999 / 999
      V = (999 * 999) / 999
    • А так нет, хотя математически результат один:
      V = 999 * (999 / 999)
      V = 999& * 999 / 999
      V = CLng(999) * 999 / 999
  • Избегайте избыточного изменения документа. Не надо слову назначать жирный шрифт, если оно уже жирное. Проверяйте необходимость изменений. Word реагирует на любые операции с документом, что сказывается на быстродействии. При большом количестве избыточных правок, разница по времени просто гигантская, если добавить простую проверку.
  • Учитывайте параметры автозамены Word, которых становится все больше, от версии к версии.
    • Во-первых, при каждом изменении документа, в том числе макросом, Word выполняет свои автоматические операции. Чем больше изменений и чем больше автозамен, тем медленнее работает макрос.
    • Во-вторых, может случится такое, что макрос правит какой-то текст, а Word тут же подправляет его по-своему, согласно настроек автозамены. Это может быть полезным, при замене кавычек, например, но не всегда.
  • При длительной обработке документа макросом, отключайте автоматические функции Word. Иначе, и обработка замедлится, и Word может зависнуть.
    • Пример. Вы берете большой документ, выполняете его обработку макросом, но Word при этом зависает. Даже не разбираясь в макросах, можно попробовать сделать следующее:
      • Откройте обрабатываемый документ.
      • Перейдите в параметры Word, где отключите:
        • Сохранение > Автосохранение документа (обязательно).
        • Правописание > Автоматическая проверка орфографии и грамматики (желательно).
        • Правка > Учитывать пробелы (желательно).
        • Параметры автозамены (по желанию, уж слишком их много).
      • Запустите макрос. Дождитесь его завершения.
      • Верните параметры Word в исходное состояние.
  • Крайне медленно работает обращение к элементу документа по его индексу. Речь о символах, словах, предложениях, абзацах и др. Чем больше элементов в документе, тем "тормоза" более заметны.
    • Пример. Вместо прямого обращения к знаку:
      Document.Characters(N)
      лучше используйте поиск нужных знаков:
      Document.Range.Find
      в крайнем случае, перебор знаков в цикле:
      For Each C In Document.Characters

КОНТРОЛЬ ОШИБОК (On Error)

  • Код, вносящий изменения в документ, защищайте On Error.
  • Вместо команды Err.Clear, можно использовать On Error Resume Next, которая также очищает последнюю ошибку. В плане надежности это даже полезно.
  • В приведенной ниже структуре, выполняемую часть помещать после Else. Так как, при ошибке в проверке, выполняется блок Then:
    • On Error Resume Next
      If ... Then ... Else ...
  • Если контроль ошибок отключен и происходит присвоение переменной, то при ошибке переменная сохранит старое значение. Поэтому, предварительно, надо сбросить значение переменной.
    • Пример с ошибкой:
      N = 1
      On Error Resume Next
      N = CLng("") ' Run-time error 13
      if N = 0 Then Exit Sub
    • Рабочий пример:
      On Error Resume Next
      N = 0: N = CLng("")
      if N = 0 Then Exit Sub
    • Правильно:
      On Error Resume Next
      N = CLng("")
      if Err.Number <> 0 Then Exit Sub

РЕЖИМ ПРОСМОТРА ДОКУМЕНТА (View.Type)

  • В случае когда, в интерфейсе Word, выбран элемент вне окна активного документа, отдельные свойства и методы активного документа могут быть недоступны.
    • Пример. Если в Word 2003 кликнуть правой кнопкой мыши пункт на панели "Схема документа", то документ останется активным, но при обращении к стилю абзаца произойдет ошибка:
      • MsgBox ActiveDocument.Paragraphs.First.Style.NameLocal ' Run-time error 4605
    • Одним из вариантов лечения может быть код:
      • ActiveDocument.Windows(1).Panes(1).Activate
  • Selection ведет себя по-разному в различных режимах просмотра документа.
  • При обработке макросами, старайтесь использовать режим просмотра "Обычный" (wdNormalView). Это повышает быстродействие. Особенно при работе с таблицами.
  • При переключении режима просмотра, может изменится Selection.Range, т.к. есть режимы, где отображаются не все элементы документа.
    • Пример. В режиме просмотра "Обычный" / "Черновик" (wdNormalView) не видны объекты. И если, в режиме "Разметка страницы" (wdPrintView), выбрать текст внутри надписи, то, при смене режима на "Обычный", схлопнется Selection.Range.

ПОИСК (Range.Find)

  • Подстановочные знаки
    • По одному и тому же шаблону, с подстановочными знаками, поиск вперед и назад может дать разные результаты. Тестируйте поисковые шаблоны, что бы знать, какие подходят для поиска вперед, а какие назад.
    • Поиск с подстановочными знаками "@" и "{1;}"
      • Дает не одно и тоже.
        • Пример. При поиске вперед в тексте "111+222+333":
          • по шаблону "1@" будет найден один символ "1", а по "1{1;}" - цепочка символов "111"
          • по шаблону "[!2]@+" будет найден текст "111+", а по шаблону "[!2]{1;}+" ничего не будет найдено
      • При сложном поиске, особенно в обратном направлении, больше подходит "@".
        • Пример. Поиск назад в тексте "Один Два Три" по шаблону "<[А-Я]{1;}[А-Яа-я]{1;}>" не даст результата, в отличие от "<[А-Я]@[А-Яа-я]@>".
      • По опыту, более стабильным является "{1;}".
        • Пример. Лучше использовать"<[А-Я]{1;}>", а не "<[А-Я]@>". Результат одинаков, но первый вариант надежнее.
    • Подстановочный знак \n, где n=1,2,3...:
      • Можно использовать не только в поле "Заменить" но и в поле "Найти".
        • Пример. Если ищем по шаблону "(ма)\1", то найдем текст "мама".
        • Пример. Можно искать повторяющиеся слова. Поиск слова встречающегося в тексте пять раз: "(<*>)*\1*\1*\1*\1".
      • Замененный текст, в некоторых случаях, наследует формат впередистоящего.
        • Пример. Если искать "(?)X" и заменять на "\1Y" то, когда первый символ найденного текста подстрочный, а второй нет, после замены и второй станет подстрочным. Поиск "X(?)" и замена на "Y\1" не приводит к наследованию.
    • Спецсимвол "!" при поиске с подстановочными знаками:
      • Использовать осторожно. Слишком глобально и много исключений, предусмотреть которые очень трудно.
      • Будут найдены только простые символы.
        • Пример. Поиск по шаблону "[!A]" не найдет графический объект, гиперссылку и т.п.
        • Пример. Поиск в таблице с обычным текстом по шаблону "Дом[!^12]{1;}" найдет текст от слова "Дом" до конца ячейки (тот же результат дает поиск назад по шаблону "Дом*").
    • При поиске с подстановочными знаками, старайтесь не использовать знак конца абзаца "^13" вместе со скобками. Замечено нестандартное поведение.
      • Пример. Если попробуем две точки в конце абзаца заменить одной, т.е. ищем "([!.].).(^13)" и заменяем на "\1\2", то в параграфе со списком получим интересный глюк.
    • При поиске и замене с помощью скобок (подстановочные знаки), поиск надо повторять дважды, когда заменяемая часть находится не в конце искомого текста.
      • Пример. При поиске "(X)+(X)" и замене на "\1=\2" в тексте "X+X+X+X+X" получим "X=X+X=X+X". Т.е. поиск надо повторить дважды или, выполняя поиск пошагово, корректировать оставшуюся область поиска.
    • Поиск с подстановочными знаками не работает с полями. То есть, с его помощью невозможно найти текст внутри поля.
    • Осторожно используйте длинные, сложные шаблоны поиска с подстановочными знаками. Бывают такие сочетания "шаблон поиска + обрабатываемый им документ", что подвешивают Word намертво. То есть, в одном документе все работает, а в другом - виснет. Чем проще, тем лучше.
  • Оптимизация массовых замен
    • Медленный способ, как ни странно:
      Range.Find.Execute Replace:=wdReplaceAll
    • Быстрый способ, особенно при больших объемах:
      Range.Find.Execute Replace:=wdReplaceNone
      If Range.Find.Found Then
          Range.Collapse wdCollapseStart
          Range.Find.Execute Replace:=wdReplaceAll
      End If
    • Самосброс. Некоторые параметры поиска, Word меняет самостоятельно. Есть взвимозависимые параметры, когда один параметр сбрасывается, при изменении вами другого. Есть параметры сбрасываемые Word в результате запуска вами поиска. Поэтому, при массовых заменах, советую для каждой замены прописывать все параметры.
  • Поиск, разное
    • При поиске стиля, наблюдаем интересный глюк в абзаце перед таблицей. Абзац стилизован одним стилем. При поиске назад, все в порядке. А вот при поиске вперед, сначала поиск находит абзац без знака абзаца, а при продолжении поиска - знак абзаца. Что через диалог, что макросом.
    • При замене текста, удаляются или повреждаются закладки:
      • Удаляются закладки, попадающие в заменяемый текст.
      • Удаляется закладка, область которой совпадает с заменяемым текстом.
      • Закладка, охватывающая часть текста, обрезается и вытесняется за текст.
      • Сохраняется точечная закладка, стоящая с края текста.
    • Продолжайте поиск с конца найденного блока. Например, с конца параграфа, а не с начала следующего. Иначе велика вероятность зацикливания, особенно в таблицах.
    • Поиск без текста - только формата (жирный, наклонный шрифт и т.п.), начинается с края выбранной области по направлению поиска. Область как бы предварительно схлопывается в направлении поиска.
    • Поиск не сработает, если искомый текст занимает всю область поиска.
      • Пример. В области R, содержащей текст R.Text="Иван", поиск R.Find.Text="Иван" не сработает.
    • В таблице, для поиска в последнем параграфе ячейки таблицы при помощи Selection, надо брать область параграфа без последнего символа. Причина хорошо видна, если выполнить код: Cell.Range.Characters.Last.Select
    • Учитывайте при поиске символы (Character) содержащие не один знак. Такие как символ конца ячейки таблицы (13 + 7), гиперссылки и т.п.
      • Пример. Поиск по шаблону "Вася[!.]" не найдет слово "Вася" стоящее последним в ячейке таблицы или перед гиперссылкой.
    • Если область поиска охватывает часть гиперссылки, то поиск будет произведен в гиперссылке целиком. Желательно выравнивать область поиска с началом/концом символа (Character). Например, так:
      Range.SetRange Start:=Range.Characters.First.Start, End:=Range.Characters.Last.End
    • При поиске в выбранной области (Selection) учтите, что в таблице невозможно выбрать: стока + ячейка.
      • Пример. Код, приведенный ниже, выберет все от начала строки с ячейкой таблицы до конца документа:
        Range(позиция в ячейке таблицы, позиция конца документа).Select
    • Команда Find.Execute иногда выдает False, в то время как поиск успешен и Find.Found=True. Т.е. надежнее писать так:
      Range.Find.Execute
      If Range.Find.Found = True Then ...
    • В виде макроса, реализовать опцию поиска "Выделить все...", для стиля, шрифта, или другого форматирования, можно с помощью команды SelectSimilarFormatting
      • Пример. Выделение всех вхождений стиля "Заголовок 1":
        Selection.Find.Style = "Заголовок 1"
        Selection.Find.Execute
        Application.Run "SelectSimilarFormatting"
    • Спецсимвол ^d (он же ^19 - начало поля, есть еще ^21 - конец поля) позволяет искать как любые поля, так и поля определенного типа. Более того, можно найти, выделить и обработать строго отфильтрованные, нужные поля.
      • Пример обработки полей типа AUTOTEXT:
        • Включим режим отображения кода полей (Alt+F9)
        • Откроем окно расширенного поиска (Ctrl+F, Ctrl+H)
        • В поле "Найти" водим текст: ^d^wAUTOTEXT^w
        • Активируем флаг "Выделить все элементы..."
        • Выполним поиск. В результате, будут выделены все поля типа AUTOTEXT. Причем, выделяются не искомые фрагменты кода полей, а именно поля целиком!
        • Выделенную группу полей можно вырезать, скопировать, удалить, форматировать и др.
        • Можно переключиться обратно - в режим отображения значений полей (Alt+F9). При этом, поля останутся выделенными.
    • Если выставить Selection.Find.Wrap = wdFindContinue, то при проходе поиска через край (начало/конец документа), этот параметр самосбросится и станет wdFindStop.
    • Глюк или так и надо? Случается, что область находки выдлядит странно: начало у области есть, а конца нет. То есть, Range.Start = 100, например, а Range.End = 0. Заметил, что происходит это, когда находка внитри поля, в конце ячеки и в других заковыристых случаях. Ситуация не случайная и легко повторима. У цекле поиска этот глюк приходится учитывать.

ШРИФТ (Font)

  • Свойство Range.Font не включает в себя информацию о пробелах и других пустых символах в области Range, если область содержит видимые символы.
  • При изменении любого параметра шрифта Range.Font, у пробелов и других пустых символов, стоящих последними в области Range, после видимого символа, параметры шрифта не изменятся.

СКРЫТЫЙ ТЕКСТ (Font.Hidden)

  • Когда скрытый текст виден (ShowHiddenText=True), то он ведет себя как обычный текст.
  • Когда скрытый текст не виден (ShowHiddenText=False), то:
    • Скрытый текст исключается из свойств:
      Paragraphs
      Range.Characters
      Range.Text
    • Скрытый текст остается в свойствах:
      Range.Start
      Range.End
      Range.Font
      Selection.Type
  • При переключении видимости скрытого текста (ShowHiddenText), проверяйте и корректируйте области Range. Желательно избегать ситуации, когда текст скрыт, а край области находится внутри скрытого текста.

ТАБЛИЦЫ (Table)

  • Команда Select, для выбора столбцов таблицы, работает по-разному, когда таблица находится на одной странице и когда на нескольких.
  • Если область схлопнута и находится в начале параграфа сразу за таблицей, то у этой области Range.Tables.Count = 1. Поэтому, нахождение в таблице лучше проверять функцией Range.Information(wdWithInTable).
  • Если Selection находится сразу за последней ячейкой строки таблицы то:
    Selection.Cells.Count = 1
    Selection.Range.Cells.Count = 0
  • Осторожно использовать команды перехода по параграфам в таблицах с объединенными ячейками. Например: Selection.Move Unit:=wdParagraph, Count:=1. При поиске возможно зацикливание.
  • Вставка нового столбца в таблицу может быть невозможна из-за ошибки "Превышена максимальная ширина". Поэтому, при создании таблицы макросом, лучше задать столбцам фиксированную ширину, а уже после заполнения можно включить автоподбор ширины и др.

СТИЛИ (Styles)

  • Имена стилей чувствительны к регистру букв, чего нельзя сказать о коллекции Styles. Например, если в документе есть стиль с именем "МОЙСТИЛЬ", то команда Styles("мойстиль").Delete его спокойно удалит. А вот команда OrganizerDelete работает правильно: удалит стиль "МОЙСТИЛЬ" и вызовет ошибку при удалении "мойстиль". Аналогично плохо команда Styles(i).Delete возвращает коды ошибок.
  • При работе со стилями документа, этот документ должен быть активным документом Word (ActiveDocument). Иначе, некоторые операции вызовут ошибку. Например, если документ не активен, то в нем:
    • Свойство BaseStyle блокируется, когда другой, но активный документ, защищен от записи.
    • Первое применение вновь созданного встроенного стиля вызывает ошибку.
    • Ошибки странные, надеюсь исправят.
  • Желательно исключить пробелы из имен стилей, созданных пользователем. Например, при наличии пробелов, сбоит функция "Выделить все" стиля. Встроенных стилей это не касается.
  • Имена встроенных стилей привязаны к региональным настройкам и пишутся на языке интерфейса. Например, стиль "Заголовок 1" в русском Word, это "Header 1" в английском. В макросах, для встроенных стилей, надо использовать номера wdBuiltinStyle, для повышения совместимости.
  • Осторожно работайте с неиспользуемыми стилями (Style.InUse = False). Хотя эти стили и находятся в коллекции документа (Document.Styles), но к документу пока не относятся, правильнее считать их отдельной группой. Word следит за такими стилями, и даже простое чтение макросом свойств (не всех, но например Style.Description) неиспользуемого стиля, вызывает автоматическое подключение этого стиля к документу и цепную перенастройку других стилей. В результате чего, документ будет изменен (Document.Saved = False), связи его стилей (свойства BaseStyle, LinkStyle) будут перенастроены по какому-то внутреннему алгоритму Word, могут появиться изменения в форматировании документа.
  • Параметр стиля InUse означает, что стиль подключен к документу. Это не значит, что стиль используется прямо сейчас, достаточно было применить стиль ранее. Так же, это может быть стиль, созданный или модифицированный в этом документе.
    • Пример. Если применить в документе стандартный стиль "Подпись", а затем удалить все стилизованные им фрагменты, то параметр InUse стиля "Подпись" останется равным True.
  • Присвоение стиля делайте через имя, не через объект.
    • Ошибка (сбой произойдет, если имя стиля "005", то есть какой-то номер в виде текста):
      Selection.Find.Style = MyStyle
    • Правильно:
      Selection.Find.Style = MyStyle.NameLocal
  • В стиле таблицы программно (макросом) нельзя задать:
    • Вертикальное выравнивание текста ячеек.
    • Значения полей ячеек по умолчанию (для всей таблицы) (TopPadding и др. меняет поля у всех ячеек стиля сразу).
    • Параметр "Как во всей таблице" для полей ячейки.

ВЫБРАННЫЙ ФРАГМЕНТ (Selection)

  • Объект Selection является уникальным, также как и многие его свойства и методы. Например, у объекта Range набор инструментов для работы с областью существенно уступает Selection.
  • Несомненный плюс Selection в том, что возможна работа с несколькими фрагментами, выбранными в разных местах документа. В отличие от Range, где возможна обработка только одного непрерывного фрагмента документа.
  • Старайтесь как можно реже использовать Selection в макросах, особенно в сложных. Только по необходимости. Причина - к изменению Selection, привязано очень много автоматических операций Word. Использование Selection, в лучшем случае, сильно замедлит работу макроса, в худшем - приведет к ошибке, сбою.
  • Не путать одинаковые свойства и методы у Объект.Свойства и Объект.Range.Свойства. Например, свойства Selection и те же свойства Selection.Range могут существенно различаться.
  • При некоторых типах Selection.Type (например, если выбрано полотно) не работает команда ActiveDocument.Styles.Add.
  • Когда Selection.Range в начале параграфа, команда Selection.Collapse wdCollapseStart иногда переводит курсор в конец предыдущего параграфа.
  • Свойства Selection относятся к активной части документа.
    • Пример:
      ActiveDocument.StoryRanges(Index:=wdFootnotesStory).Select
      Selection.Find.Execute ' что-то ищем и находим...
      ' до следующей команды Selection находится в FootnotesStory
      ' ОШИБКА:
      ActiveDocument.Range(Selection.Start, Selection.End).Select
      ' выбрали неизвестно что в главной части документа (wdMainTextStory)
      ' ПРАВИЛЬНО:
      Selection.SetRange Selection.Start, Selection.End
  • Без использования буфера, выбранный фрагмент (Selection), можно копировать и перемещать внутри документа с помощью команд CopyText и MoveText соответственно.

ОБЪЕКТЫ

  • Проверка объекта:
    • Объект is Nothing = True, если объект не определен.
    • IsObjectValid(Объект) <> True, если объект был удален.
      • Рекомендую использовать эту проверку при пакетной обработке объектов в цикле For Each.
      • Кроме удаленных, эта проверка отлавливает и поврежденные объекты (встречаются и такие).
  • Проверка типа объекта:
    • If TypeOf Объект Is Тип Then
  • Имя типа объекта:
    • S = VBA.TypeName(Объект)
  • Запись свойства объекта по имени:
    • CallByName Selection.Find, "Text", vbLet, "стул"
    • Аналог: Selection.Find.Text = "стул"
  • Чтение свойства объекта по имени:
    • S = CallByName(Selection.Find, "Text", vbGet)
    • Аналог: S = Selection.Find.Text
  • Вызов метода объекта по имени:
    • CallByName Selection.Find, "Execute", vbMethod, "стул", True
    • Аналог: Selection.Find.Execute "стул", True
  • Удаляя параграф, вы удаляете прикрепленные к нему рисунки, надписи и другие объекты.
  • При работе с рисунками (объекты Shape и InLineShape) надо серьезно учитывать версию Word. Результат работы одного и того же кода, в разных версиях Word, может существенно отличаться.
  • Объекты типа Shape, привязывается не к параграфу, а к месту в параграфе. Соответственно работает и ShapeRange.
    • Пример. Знак "разрыв страницы" делит параграф на две части (не на два параграфа). Первая часть будет на одной странице, вторая - на другой. И рисунки можно будет вставлять как на одну страницу, так и на другую, с привязкой к одному и тому же параграфу. Аналогично действует знак "разрыв колонки".
  • Параметр Anchor, при создании Shape, зачастую игнорируется. Помогает вырезание и вставка Shape. В этом случае, Anchor всегда совпадает с местом вставки, что позволяет привязать Shape даже к одному знаку.
    • Пример вставки и привязки фигуры "Сердце":
      Dim R as Range, SH as Shape
      Set R = Selection.Range ' место привязки
      R.Collapse wdCollapseStart
      Set SH = ActiveDocument.Shapes.AddShape(msoShapeHeart, 0, 0, 100, 100, R) ' глючит
      If R.Start <> SH.Anchor.Start Then ' проверка и коррекция
          SH.Anchor.Cut
          R.Paste
          Set SH = R.ShapeRange(1)
      End If
  • При позиционировании Shape на странице - при изменении свойств Top и Left, используйте переменные типа Variant. Иначе, позиция Shape может скакать. Например, при использовании типа Single.

ФОРМА, ПАНЕЛЬ, МЕНЮ

  • Параметр TakeFocusOnClick, у элементов немодальной формы (ShowModal=False), всегда оставляйте True. Иначе, форма будет либо не получать фокус, когда она не активна, либо терять фокус, когда элемент формы вызывает другой диалог.
  • При создании элементов панели инструментов (кнопок, меню и др.), в команде CommandBarControls.Add параметр Temporary игнорируется. Temporary всегда False, как бы.

РАЗНОЕ

  • После удаления области командой Range.Delete, может остаться пробел или абзац. Причина - настройки автозамены и автоформатирования Word, которые препятствуют полному удалению. Например, между двумя таблицами Word, может остаться пустой абзац. Помогает либо временное отключение параметров Word, либо такая конструкция:
    Range.Duplicate.Delete
    If Range.Start < Range.End Then Range.Delete
  • При проверке кода символа учитывайте, что функция AscW() может выдать отрицательное число, так как диапазон Unicode от -32768 до 65535.
    • Например, надо проверить, что код символа от 0 до 32:
      if AscW(S) <= 32 then ' ошибка!
      if AscW(S) >= 0 and AscW(S) <= 32 then ' правильно
  • Команды Copy, Cut, Paste и другие, работающие с буфером обмена, дополняйте командой DoEvents. Иначе, может возникнуть ошибка "в буфере отсутствуют данные или они имеют неверный формат". Особенно актуально при использовании буфера в цикле.
  • При открытии документа в режиме "только для чтения", в нем, тем не менее, могут произойти изменения. При этом, свойство Document.Saved станет равно False. Это происходит из-за параметров документа и Word. Например, при активном параметре "автоматически обновлять связи при открытии".
  • Коллекция Application.Documents включает в себя и скрытые документы (Window.Visible = False).
  • Учитывайте, что Range.Start и Range.Characters.First.Start не всегда совпадают. Например, когда Range.Start внутри перекрестной ссылки, гиперссылки и т.п.
  • Даже когда область Range схлопнута Range.Characters.Count=1. Поэтому, нулевую длину области надо проверять так:
    If Range.Start = Range.End Then ...
  • Не путать Len(Range.Text) c Range.Characters.Count. Один Character может содержать несколько символов, а значит возможна ситуация когда: Len(Range.Text) > Range.Characters.Count
  • Функция InRange вернет False, если проверяемая область схлопнута и стоит в конце области-родителя. Но вернет True, если схлопнутая область в начале. Такая хитрая логика, не прописанная в документации.
  • Команда Application.Run не возвращает параметры типа Variant. Задавайте тип явно.
    • Пример с ошибкой:
      Sub AAA()
          Dim V As Variant ' надо писать As Long
          Application.Run MacroName:="BBB", VarG1:=V
          MsgBox V
      End Sub
      Sub BBB(ByRef V)
          V = 123
      End Sub
  • Команда InsertParagraphBefore/After иногда не срабатывает. Помогает ее замена на: InsertBefore Text:=vbCr.
  • Область с последним символом документа ведет себя нестандартно, что может привести к зацикливанию.
    • Пример:
      ActiveDocument.Range.Characters.Last.Select
      Selection.Collapse Direction:=wdCollapseEnd ' глюк здесь
  • Оператор With ... End With аналогичен объявлению и освобождению новой переменной. Имя переменной как бы пустое, а для доступа к ее свойствам достаточно напечатать точку.
    • Пример с ошибкой:
      Dim C As Cell, i As Long
      With Selection
          For i = 1 To Selection.Cells.Count ' ячеек несколько
              .Cells(i).Range.Text = "X"
          Next i
      End With
    • Исправленный пример:
      Dim C As Cell, i As Long
      With Selection.Cells
          For i = 1 To .Count
              .Item(i).Range.Text = "X"
          Next i
      End With
  • Переход в начало N-ой страницы документа:
    ActiveDocument.GoTo(wdGoToPage, wdGoToAbsolute, N).Select
    или
    Selection.GoTo(wdGoToPage, wdGoToAbsolute, N)
  • ReDim - это одновременно и Dim, ReDim Preserve - нет. То есть, перед ReDim A(5) не нужно объявлять переменную A, а перед ReDim Preserve A(5) нужно добавлять Dim A. При наличии Option Explicit конечно.
  • ReDim Preserve сдвигает индекс первого элемента массива на указанный в параметре Option Base.
    • Пример с ошибкой:
      Option Base 0
      ReDim A(1 to 1)
      A(1) = 100
      ReDim Preserve A(2) ' вместо A(1 to 2) имеем A(0 to 2), где A(0) = 100
  • Глюк Word (может исправят, в какой-то версии). Если буфер отмены пуст, то команда UndoRecord.StartCustomRecord приводит к аварийному перезапуску Word. Можно сделать что-то нейтральное, чтобы наполнить буфер и обойти глюк.
  • Когда одновременно запущено несколько приложений Word, использующих одну надстройку dot(m), невозможно выполнить команду Document.Save для этой надстройки, ее будут блокировать остальные Word-приложения. То есть, если вы храните какие-то данные в теле надстройки, например в переменных (Variables), сохранить их не получится. Возможно это и хорошо, но если сохранять нужно, то используйте ini-файл, реестр или др.

наверх

http://mtdmacro.ru/ | © Александр, 2007-2023 | alex@mtdmacro.ru | mtdmacro@gmail.com