|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
down |
|
Macro package for formatting Microsoft Word documents.
Examples, tips, info about macros, VBA and Microsoft Office.
Author: © Alexander, 2007-2023, alex@mtdmacro.ru |
|
|
Patterns for search and replace in Word
|
SEARCHING WITH WILDCARD CHARACTERS
- Latin or Cyrillic letter: [A-Za-zА-ЯЁа-яё]
- Uppercase letter: [A-ZА-ЯЁ]
- Lowercase letter: [a-zа-яё]
- Letter or number: [A-Za-zА-ЯЁа-яё0-9]
- Cyrillic letter: [А-ЯЁа-яё]
- Uppercase Cyrillic letter: [А-ЯЁ]
- Lowercase Cyrillic letter: [а-яё]
- Latin letter: [A-Za-z]
- Uppercase Latin letter: [A-Z]
- Lowercase Latin letter: [a-z]
- Word: <[! ^s^t^13]{1;}>
- Uppercase word: <[A-ZА-ЯЁ]@['A-ZА-ЯЁ]@>
- Word Cyrillic: <[А-ЯЁа-яё]@['А-ЯЁа-яё]@>
- Lowercase word Cyrillic: <[а-яё]@['а-яё]@>
- Title word Cyrillic: <[А-ЯЁ]['а-яё]@>
- Uppercase word Cyrillic: <[А-ЯЁ]['А-ЯЁа-яё]@>
- Latin word: <[A-Za-z]@['A-Za-z]@>
- Latin title word: <[A-Z]['a-z]{1;}>
- Latin title word or uppercase word: <[A-Z]['A-Za-z]{1;}>
- Russian initials: <[А-ЯЁ].
- English initials: <[A-Z].
- Uppercase letter or digit: [A-ZА-ЯЁ0-9]
- Digit (Arabic): [0-9]
- Digits: [0-9]{1;}
- Number: <[0-9]{1;}>
- Numbers at the beginning of the word: <[0-9]{1;}
- Numbers at the end of word: [0-9]{1;}>
- Four-digit year: <[1-2][0-9]{3}>
- Uppercase Roman numeral: [IVXLCDM]
- Lowercase Roman numeral: [ivxlcdm]
- Capital Roman numeral: <[IVXLCDM]{1;}>
- Uppercase Roman numeral: <[IVX]{1;}>
- Arabic or Roman numerals: [0-9IVXLCDM]
- Chain of normal Spaces: [ ]{1;}
- Chain of Spaces: [ ^s]{1;}
- Chain of Tabs: [^t]{1;}
- Space, non-breaking space, tab: [ ^s^t]
- Empty space: [ ^s^t]{1;}
- Any dash or hyphen: [\-^=^+^~]
- Symbols of the Internet (website address, email): [A-Za-z0-9_.\-]
- Visible sign (use caution): [! ^t^s^m^n^-^l^13]
- Invisible sign: [ ^t^s^m^n^-^l^13]
- Characters with code from 33 to 255: [\!-я]
|
Note. The above templates, in the text of the form "{1;}" character semicolon (;) is customizable. This symbol is set in the regional settings of the operating system, the option
"List separator". The semicolon is used by default in the Russian version of Windows, the English adopted the symbol comma (,). See the "Language"
section.
|
Units of measurement
|
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)
|
Constants used by Word 2019, 2016, 2013, 2010, 2007, 2003
|
FONT (Font)
- Size
- minimum and maximum: from 1 to 1638 pt
- Spacing
- minimum and maximum: from -1584 to 1584 pt
- minimum step: 0.05 pt
- default value: 0 pt
- Position
- minimum and maximum: from -1584 to 1584 pt
- minimum step: 0.05 pt
- default value: 0 pt
- Scaling
- minimum and maximum: from 1 to 600 %
- minimum step: 1 %
- default value: 100 %
PARAGRAPH (ParagraphFormat)
- Minimum and maximum indent (LeftIndent, RightIndent, FirstLineIndent): from -55.87 to 55.87 cm
- minimum step Indent: 0.05 cm
- Minimum and maximum line spacing (LineSpacing): from 0.35 to 1584 pt
- minimum step line spacing: 0.05 pt
LIST (ListFormat)
- Maximum number of numbered list (StartAt): 32767
- Maximum number of levels in the list (ListLevels): 9
- Prefix list level number (NumberFormat): "%"
TABLE (Table)
- Maximum number of table columns (Columns): 63
- Maximum number of table rows (Rows): 32767
- Maximum table width in percent (PreferredWidth): 600 %
- minimum step the table width in percent: 0.5 %
- Maximum table width in centimeters (PreferredWidth): 55.87 cm
- minimum step the table width in centimeters: 0.01 cm
- Minimum and maximum height of cells or rows: from 1 to 1584 pt
MISC.
- Maximum subordinate styles in the chain (option "Based on style"): 9 styles
- The maximum length of the find (Find.Text) and replace (Find.Replacment.Text) fields: 255 characters
- Bookmark name:
- Begins with a letter or underscore (hidden).
- May contain letters, digits, underscore.
- Not case sensitive.
- Maximum length: 40 characters.
- Maximum scale of the object (ScaleWidth, ScaleHeight): 10675 %
- Maximum zoom window (View.Zoom.Percentage): 500 %
- The maximum number of visible errors:
- Spelling (SpellingErrors): 2000
- Grammatical (GrammaticalErrors): 2000
- The maximum value of the Roman number: 32766
- Date (as Date):
- from 1 January 100 to 31 December 9999
- from -657434 to 295846
|
Regional and Language Options in Word
|
THE MECHANISM OF DETERMINING THE LANGUAGE
Word in each sentence uses special language algorithms and statistical data. For single words or short phrases of the language is not defined. In determining the language of the range of possible
decisions gradually narrows to a set of languages, specified when setting up the Word in the following sequence.
Language detection is performed simultaneously with the work on the text and do not interfere with the user. In new documents shall be done from the very beginning as you enter each sentence, or
copy or paste text fragments. If you open a document that has never been tested, subjected to testing every sentence. In addition, any proposal to re-verified if it amends. To restart the language
recognition in the package "Metodichka" added macro M082_Правописание_Перепроверить .
Even if you use automatic language detection, you may need to apply language formats directly to your text. Word sometimes differ subtly on writing languages. Word might apply the wrong language
format or assume the default language for an entirely different language such as English. To address the latest issues in the package "Metodicka" included macro M080_Язык_текста.
INFLUENCE OF REGIONAL OPERATING SYSTEM SETTINGS
Changing the default country/region changes the standard settings for numbers, currencies, times and dates for the most commonly used for that country/region. Listed below are the regional settings
of Windows and their impact on specific elements of the Word:
-
Windows: List separator
- Word: Searching with wildcard characters
- Wildcard characters {n,} and {n,m}, designed to search for occurrences of the previous character or expression. In this case, use a comma (,), but if the regional settings set to a
semicolon (;), you need to use it. This applies both to find through dialogue and the search for VBA macro.
- Word: Field
- Some key fields require a list of items separated by commas (,) or semicolon (;), depending on what you selected in the regional settings of Windows.
- For example, fields such as: = (formula); TOC (table of contents), INDEX (pointer), EQ (equation), etc.
-
Windows: Decimal separator, date and time components, currency symbols, etc.
- Word: VBA functions that use the format or to convert from one format to another.
- For example, functions such as Format(), CStr(), CDate(), CCur(), CDbl(), CSng(), etc.
- Word: Field containing the number, date format, time, etc.
Note: In VBA for information about current regional settings feature is International.
THE DEFAULT NORMAL TEMPLATE LANGUAGE
The Normal template language settings determine how to create and run macros in Visual Basic for Applications (VBA). When you start Word and load a template installation language also changes some
default settings that depend on the language setting. If the modified template is Normal for a specific language copy on a computer that is configured to work with another language, their compatibility
may still prove problematic. In this case, it is best to allow the installation process to create a new Normal, and then use templates management tool to migrate settings styles, AutoText, macros,
and toolbars of the template that you created earlier. If necessary, you can rename the Normal template and upload it as a global template.
|
Built-in Word commands
|
COMMANDS LIST WITH DESCRIPTIONS
- General table: word_commands.xlsx
- Note: Some specific commands are available depending on the type of Word and of the operating system.
GET A LIST OF COMMANDS
- New document with a list of Word commands and combinations of keyboard shortcuts that match these commands, you can get any of the following ways:
- Interface:
- Open the Macros dialog box (Alt + F8).
- In the list "Macros in", select "Word commands".
- In the list "Macro name", select "ListCommands".
- Click "Run" button.
- In the dialog, select "All Word commands".
- Click "OK" button.
- Visual Basic: Application.ListCommands ListAllCommands:=True
- Note: A list of commands that is displayed in the "Macros" or produced by "ListCommands" is not complete.
COMMAND EXECUTION
- Execute the command can be any of the following ways:
- Interface:
- Open the Macros dialog box (Alt + F8).
- In the Name box, type the name of the command.
- Click "Run" button.
- Visual Basic: Application.Run "command name"
- Note: If the new macro set name as an existing built-in command in Word, instead of the built-in commands that will run this macro. For example, if you record a new macro and name it FileClose, this macro will be associated with the command "Close". Then, when you click the "Close" button, Word will perform the actions specified in the new macro.
|
Built-in Word styles
|
- Excel table with a full list of built-in Word styles: word_builtin_style.xlsx
- Described styles Word versions: 2019, 2016, 2013, 2010, 2007, 2002/XP, 2000
- Information about styles: English name, Russian name, Primary Style Name (XML), Code / Index, wdBuiltinStyle.
- Good to know: more than 350 built-in styles includes Word 2013.
|
Встроенные поля Word (Field)
|
- Таблица со списком встроенных полей Word: word_field.xlsx
- Описаны поля всех версий Word для Windows.
- Информация о полях: имя, код, ключи, краткое описание, wdFieldType, Type.
|
idMSO
|
LISTS Of CONTROL IDs And IMAGEMSO For 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 байта).
|
Macros in Word
|
ABOUT MACROS
- If you perform a task repeatedly in Word, you can automate the task with a macro. A macro is a series of commands and instructions that execute as a team.
- Macros are often used for the following purposes:
- to speed up routine editing and formatting;
- to combine multiple commands - for example, to insert a table with a specific size and borders, and a certain number of rows and columns;
- to simplify access to the parameters in the dialog boxes.
- to automate a complex series of tasks.
CREATE MACROS
- To create a macro in Word, there are two methods: the use of tools for recording macros and direct programming in the Visual Basic Editor.
- Recording a macro.
- In Word macro recorder works like a tape recorder. With the help of recorded keystrokes and mouse, which are translated into macro code Microsoft Visual Basic for Applications.
- When you record a new macro is allowed to use only the mouse to select commands and parameters. To record such action as selecting text, you must use the keyboard.
- Create a macro by using the Visual Basic Editor.
- In Visual Basic, you can write a very powerful and complex macros, which can not be written using the first method.
- In addition, the Visual Basic Editor, you can get support information to help you when you create a macro, such as reference information about objects and their properties.
STORING MACROS
- Macros are stored in templates and documents.
- By default, macros are stored in the Normal template so that they are available to all Word documents.
- If the macro is to be used only in one document, save it in this document.
- Individual macros in a document are stored in macro projects that you can copy from one document to another. Macro projects - a set of components, including forms, code, and class modules, that make up a macro.
|
Советы по написанию макросов 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
- Имя типа объекта:
- Запись свойства объекта по имени:
- 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-файл, реестр или др.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|