Vba excel. цикл do until… loop

Алан-э-Дейл       27.08.2023 г.

The Next Loop: Loops Through a Set of Numbers

We can also use the For Next Loop to loop through a set of numbers.  This can be useful when we are looping through userform controls, arrays, or if we want to loop through a collection backwards.
The basic operation of the For Next Loop is the same as the For Each Loop.  The difference is the format of the For line.

Step 1 – Declare a Variable for a Number

To loop through a set of numbers we first need to declare a variable to a whole number data type.  We can use Integer or Long integer.

Dim i As Long

The variable is referred to as the Counter because it increments or counts up/down for each iteration in the loop.

A side note on Long: The Long (integer) data type holds a bigger number than Integer.  It takes up more memory, but today’s computer have so much memory that it’s no longer a problem.  We can use Long variables all the time.  The letter L looks like the number 1 in VBA, so I’m now using i as the variable name even though I use Long as the data type.  This is all a matter of personal preference and you can name the variable whatever you want.

Step 2 – Write the For Statement

Next we write the For statement.  The basic construct is the keyword For, followed by the variable name (counter), then equals sign, start value To end value.

For i = 1 To 10

The start and end values can be referenced as numbers, or we can use integer/long variables in their place.

For i = iStart To iEnd

We can also use properties of objects that return a number.

For i = 1 To ActiveWorkbook.Worksheets.Count

That line of code would return the number of sheets in the active workbook.  However, it is NOT looping through each worksheet.  The loop is just looping through a set of numbers.  We have to create a reference to a worksheet with the counter variable (i) as the index number of the Worksheets property.  Step 3 shows this reference.

Step 3 – Add Code that Repeats for Each Iteration

The rest of the loop functions the same as the For Each loop.  We can add lines between the For and Next lines that will run for each iteration of the loop.  The counter variable can be used multiple times in these lines of code.

Worksheets(i).Visible = True

Step 4 – The Next Line Increments the Number & Loops Back

Finally, we add the Next line at the bottom.

Next i

When the macro runs it will set the variable equal to the first number in the For line.  When the macro hits the Next line, it will add 1 to the value of the variable, or count up.  So, i = 2 in the second iteration of the loop.  It continues to loop until the last number in the loop is reached.

By default, 1 is added to the variable counter for each iteration in the loop.  This is called the Step Value, and we can control the value of each step in the counter.  The Step value is added to the end of the For line.  The following line will add 2 to the counter for each iteration in the loop.

For i = 2 To 20 Step 2

If you wanted to shade every other row in a sheet, you might use a loop like this.

Looping Backwards

We can also use the Step Value to loop backwards by specifying a negative number.

For i = 100 To 1 Step -1

Notice that the Start Value is now the larger number and the End Value is the smaller number.  The loops starts at 100 (Start Value) and subtracts 1 from the counter variable (Step -1) for each iteration in the loop until it gets to 1 (End Value).

The Step keyword is optional.  If you do not specify it then VBA assumes a Step value of 1.

Looping backwards is great if you are deleting items.  I will write a separate post on this, but the general idea is that when we are looping through a collection and deleting items, the size of the collection gets smaller as items are deleted.  The loop will typically hit an error once it gets to the 10th item, when there are now only 9 items in the collection.  Looping backwards prevents this potential error.

The For Each Next Loop: цикл по коллекции элементов

Как мы видели выше, цикл «The For Each Next Loop» позволяет нам перебирать коллекцию предметов или объектов. Это, наверное, самый распространенный цикл, который мы используем в Excel, потому что мы работаем с коллекциями объектов. Опять же, эти коллекции представляют собой ячейки в диапазоне, рабочие таблицы в рабочей книге, сводные таблицы в рабочей таблице и т.д.

Мы будем использовать пример написания цикла «For Each Next Loop», чтобы просмотреть все рабочие листы в рабочей книге.

Существует четыре основных шага для написания цикла For Each Next в VBA:

  1. Объявите переменную для объекта.
  2. Напишите для каждой строки переменную и коллекцию
    ссылок.
  3. Добавьте строку (и) кода для повтора для каждого
    элемента в коллекции.
  4. Напишите следующую строку, чтобы закрыть цикл.

Давайте рассмотрим каждый из этих шагов подробно.

Шаг 1 — объявить переменную для объекта

Сначала нам нужно объявить переменную, которая будет
временно хранить ссылку на объект.

Строка Dim в верхней части макроса объявляет переменную, как объект. В этом случае объект является рабочим листом. Мы можем создать любое имя переменной, если захотим, если оно не совпадает с другой ссылкой в VBA. «Ws» — наиболее распространенное имя переменной для объекта листа, но вы можете изменить его.

Шаг 2 — Для каждой строки

Далее мы напишем оператор For Each. Это первая строка кода в цикле.

Первые два слова For Each. Затем мы вводим имя переменной, за которым следует слово In. Наконец, мы указываем, где располагается коллекция. В этом случае мы хотим просмотреть все рабочие листы в ActiveWorkbook. Итак, мы набираем ActiveWorkbook.Worksheets. Эта строка ссылается на все рабочие листы в ActiveWorkbook.

Если вы хотите пройтись по рабочим листам определенной
рабочей книги, вы можете использовать свойство Рабочие книги для ссылки на эту
рабочую книгу по имени.

Просто помните, что рабочая книга, на которую вы ссылаетесь,
должна быть открыта до запуска строки кода For Next. Конечно, мы можем
использовать метод Workbooks.Open, чтобы открыть рабочую книгу.

Шаг 3 — Добавить код для повторения для каждой итерации

После строки «For Each» мы добавляем строку(и) кода, которая будет выполняться на каждом листе. В этом примере у нас есть только одна строка кода, которая показывает лист.

В этой строке кода мы используем переменную ws для ссылки на
текущий рабочий лист в цикле. Когда цикл выполняется, он устанавливает
временную ссылку на переменную ws для каждой итерации в цикле.

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

Однако нам НЕ нужна эта строка с циклом For Each Next. Цикл
заботится о настройке переменной для нас для каждой итерации в цикле.

Для первой итерации в цикле ws установлен на Worksheets (1).
На следующей итерации ws устанавливается в Worksheets (2). Это продолжается,
пока цикл перебирает все листы в рабочей книге. Это очень мощно, потому что мы
можем повторно использовать переменную для ссылки на лист в цикле несколько
раз.

Шаг 4 — Next закрывает цикл

Последняя строка кода в цикле — Next.

Когда макрос попадает в эту строку кода, он делает две вещи:

  1. Во-первых, он изменяет ссылку на переменную на следующий элемент коллекции. В этом примере переменная ws изменяется для ссылки на следующий лист в рабочей книге.
  2. Во-вторых, он возвращается к выполнению строки кода непосредственно под строкой For Each. Затем он выполняет все строки кода между строками For Each и Next в порядке сверху вниз.

Когда будет достигнут последний элемент в коллекции (рабочий лист в рабочей книге), цикл останавливается, и макрос переходит к следующей строке кода ниже строки Next.

The VBA For Each Loop

The VBA For Each loop is used to read items from a collection or an array. We can use the For Each loop to access all the open workbooks. This is because Application.Workbooks is a collection of open workbooks.

 
 
This is a simple example of using the For Each Loop

    Dim wk As Workbook
    For Each wk In Workbooks
        Debug.Print wk.FullName
    Next wk

 Format of the VBA For Each Loop

You can see the format of the VBA for each loop here(See Microsoft For Each Next documentation):For Each <variable> in <collection>Next <variable>

To create a For Each loop we need a variable of the same type that the collection holds. In the example here we created a variable of type Workbook.

If the collection has different types of items we can declare the variable as a variant.

VBA contains a collection called Sheets. This is a collection of sheets of type Worksheet(normal) and Chart(when you move a chart to be a full sheet). To go through this collection you would declare the variable as a Variant.

 
 
The following code uses For Each to print out the name of all the sheets in the current workbook

    Dim sh As Variant
    For Each sh In ThisWorkbook.Sheets
        Debug.Print sh.Name
    Next sh

Order of Items in the For Loop

For Each goes through items in one way only.

For example, if you go through all the worksheets in a workbook it will always go through from left to right. If you go through a range it will start at the lowest cell e.g. Range(“A1:A10”) will return A1,A2,A3 etc.

This means if you want any other order then you need to use the For loop.

 
 
Both loops in the following example will read the worksheets from left to right:

    ' Both loops read the worksheets from left to right
    Dim wk As Worksheet
    For Each wk In ThisWorkbook.Worksheets
        Debug.Print wk.Name
    Next

    Dim i As Long
    For i = 1 To ThisWorkbook.Worksheets.Count
        Debug.Print ThisWorkbook.Worksheets(i).Name
    Next

 
 
As you can see the For Each loop is neater to write. However if you want to read the sheets in any other order e.g. right to left then you have to use the for loop:

    ' Reading the worksheets from right to left
    Dim i As Long
    For i = ThisWorkbook.Worksheets.Count To 1 Step -1
        Debug.Print ThisWorkbook.Worksheets(i).Name
    Next

Using the VBA For Each Loop With Arrays

One thing to keep in my is that the For Each loop is that it is read-only when you use it with arrays.

 
 
The following example demonstrates this:

' https://excelmacromastery.com/
Sub UseForEach()

    ' Create array and add three values
    Dim arr() As Variant
    arr = Array("A", "B", "C")

    Dim s As Variant
    For Each s In arr
        ' Changes what s is referring to - not value of array item
        s = "Z"
    Next

    ' Print items to show the array has remained unchanged
    For Each s In arr
        Debug.Print s
    Next

End Sub

 
 
In the first loop we try to assign s to “Z”. When happens is that s is now referring the string “Z” and no longer to the item in the array.

In the second loop we print out the array and you can see that none of the values have changed.

 
 
When we use the For Loop we can change the array item. If we change the previous code to use the For Loop you it will change all the array values to “Z”

' https://excelmacromastery.com/
Sub UsingForWithArray()

    ' Create array and add three values
    Dim arr() As Variant
    arr = Array("A", "B", "C")

    Dim i As Long
    For i = LBound(arr) To UBound(arr)
        ' Changes value at position to Z
        arr(i) = "Z"
    Next

    ' Print items to show the array values have change
    For i = LBound(arr) To UBound(arr)
        Debug.Print arr(i)
    Next

End Sub

If your Collection is storing Objects the you can change the items using a For Each loop.

Using Nested For Each Loops

We saw already that you can have a loop inside other loops. Here is the example from above:

' https://excelmacromastery.com/
Sub ListWorksheets()

    Dim i As Long, j As Long
    ' First Loop goes through all workbooks
    For i = 1 To Workbooks.Count

        ' Second loop goes through all the worksheets of workbook(i)
        For j = 1 To Workbooks(i).Worksheets.Count
            Debug.Print Workbooks(i).Name + ":" + Worksheets(j).Name
        Next j

    Next i

End Sub

This time we will use the For Each loop to perform the same task:

' https://excelmacromastery.com/
Sub ReadAllWorksheets()

    Dim wk As Workbook, sh As Worksheet
    ' Read each workbook
    For Each wk In Workbooks

        ' Read each worksheet in the wk workbook
        For Each sh In wk.Worksheets
            ' Print workbook name and worksheet name
            Debug.Print wk.Name + ": " + sh.Name
        Next sh

    Next wk

End Sub

As you can see this is a neater way of performing this task than using the For Loop:

This code run as follows:

  1. Get the first Workbook from the Workbooks collection
  2. Go through all the worksheets in this workbook
  3. Print the workbook/worksheet details
  4. Get the next workbooks in the collection
  5. Repeat steps 2 to 3
  6. Continue until no more workbooks are left in the collection

Примечания

Данные, считываемые с помощью Get, обычно пишутся в файл с put. Первая запись или байт в файле находятся на позиции 1, вторая запись или байт — на позиции 2 и т. д. Если вы не закроете рекнумбер, будет прочитана следующая запись или побистка после последнего утверждения Get or Put указано на последнюю функцию Seek). Необходимо добавить разделяющие запятые, например:

Для файлов, открытых в случайном режиме, применяются следующие правила:

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

  • Если считываемая переменная является строкой переменной длины, оператор Get считывает 2-байтовый дескриптор, содержащий длину строки, а затем считывает данные, попадающие в переменную. Таким образом, длина записи, указанная инструкцией Len оператора Open, должна быть как минимум на 2 байта больше фактической длины строки.

  • Если переменная, в которую считываются данные, является (вариантом) , оператор Get считывает 2 байта, определяющие VarType типа Variant, а затем данные, попадающие в переменную. Например, при считывании данных типа Variant, принадлежащих к VarType 3, оператор Get считывает 6 байт: 2 байта, определяющие тип Variant как VarType 3 (Long), и 4 байта, содержащие данные типа . Длина записи, указанная инструкцией Len оператора Open, должна быть как минимум на 2 байта больше фактического количества байт, необходимых для хранения переменной.

    Примечание

    Вы можете использовать заявление Get для чтения массива Variant с диска, но вы не можете использовать Get для чтения scalar Variant, содержащего массив. Оператор Get также можно использовать для чтения объектов с диска.

  • Если переменная, в которую считываются данные, имеет тип Variant, принадлежащий к VarType 8 (String), оператор Get считывает 2 байта, определяющие VarType, 2 байта, содержащие длину строки, а затем считывает данные строки. Длина записи, указанная предложением Len оператора Open, должна быть как минимум на 4 байта больше фактической длины строки.

  • Если данные считываются в динамический массив, оператор Get считывает дескриптор, длина которого равна 2 плюс 8-кратное число измерений, то есть 2 + 8 * NumberOfDimensions. Длина записи, указанная предложением Len оператора Open, должна быть больше или равна сумме всех байтов, необходимых для чтения данных и дескриптора массива. Например, для записи представленного ниже массива на диск необходимо 118 байт.

    118 bytes распределены следующим образом: 18 bytes для дескриптора (), и 100 bytes для данных ( ).

  • Если данные считываются в массив фиксированной длины, оператор Get считывает только данные. Дескриптор не считывается.

  • Если данные считываются в переменную любого другого типа (кроме строк переменной длины и типа Variant), оператор Get считывает только данные из переменной. Длина записи, указанная инструкцией Len оператора Open, должна быть больше или равна длине считываемых данных.

  • Оператор Get считывает элементы , так же как и при их отдельном считывании, но без заполняющих данных между элементами. На диске динамический массив в пользовательском типе (записанном с помощью оператора Put) предваряется дескриптором, длина которого составляет 2 плюс 8-кратное число измерений, то есть 2 + 8 * NumberOfDimensions. Длина записи, указанная с помощью инструкции Len оператора Open, должна быть больше или равна сумме всех байтов, необходимых для считывания отдельных элементов, включая массивы и их дескрипторы.

Для файлов, открытых в двоичном режиме, применяются все правила случайного режима, кроме следующих случаев:

  • Предложение Len оператора Open не влияет на считывание. Оператор Get считывает все переменные с диска непрерывно, то есть без заполняющих данных между элементами.

  • Для всех типов массивов, кроме массивов в пользовательском типе, оператор Get считывает только данные. Дескриптор не считывается.

  • Оператор Get считывает строки переменной длины, которые не являются элементами пользовательских типов, не учитывая 2-байтовый дескриптор. Число считываемых байтов равно числу символов, уже находящихся в строке. Например, приведенный ниже оператор считывает 10 байтов из 1:

Примеры циклов For Each… Next

Цикл для диапазона ячеек

На активном листе рабочей книги Excel выделите диапазон ячеек и запустите на выполнение следующую процедуру:

1
2
3
4
5
6
7
8
9

Subtest1()

Dimelement AsRange,aAsString

a=»Данные, полученные с помощью цикла For Each… Next:»

ForEachelement InSelection

a=a&vbNewLine&»Ячейка «&element.Address&_

» содержит значение: «&CStr(element.Value)

Next

MsgBoxa

EndSub

Информационное окно MsgBox выведет адреса выделенных ячеек и их содержимое, если оно есть. Если будет выбрано много ячеек, то полностью информация по всем ячейкам выведена не будет, так как максимальная длина параметра Prompt функции MsgBox составляет примерно 1024 знака.

Цикл для коллекции листов

Скопируйте следующую процедуру VBA в стандартный модуль книги Excel:

1
2
3
4
5
6
7
8
9

Subtest2()

Dimelement AsWorksheet,aAsString

a=»Список листов, содержащихся в этой книге:»

ForEachelement InWorksheets

a=a&vbNewLine&element.Index_

&») «&element.Name

Next

MsgBoxa

EndSub

Информационное окно MsgBox выведет список наименований всех листов рабочей книги Excel по порядковому номеру их ярлычков, соответствующих их индексам.

Цикл для массива

Присвоим массиву список наименований животных и в цикле For Each… Next запишем их в переменную a. Информационное окно MsgBox выведет список наименований животных из переменной a.

1
2
3
4
5
6
7
8
9
10
11

Subtest3()

Dimelement AsVariant,aAsString,group AsVariant

group=Array(«бегемот»,»слон»,»кенгуру»,»тигр»,»мышь»)

‘или можно присвоить массиву значения диапазона ячеек
‘рабочего листа, например, выбранного: group = Selection

a=»Массив содержит следующие значения:»&vbNewLine

ForEachelement Ingroup

a=a&vbNewLine&element

Next

MsgBoxa

EndSub

Повторим ту же процедуру VBA, но всем элементам массива в цикле For Each… Next присвоим значение «Попугай». Информационное окно MsgBox выведет список наименований животных, состоящий только из попугаев, что доказывает возможность редактирования значений элементов массива в цикле For Each… Next.

1
2
3
4
5
6
7
8
9
10
11
12

Subtest4()

Dimelement AsVariant,aAsString,group AsVariant

group=Array(«бегемот»,»слон»,»кенгуру»,»тигр»,»мышь»)

‘или можно присвоить массиву значения диапазона ячеек
‘рабочего листа, например, выделенного: group = Selection

a=»Массив содержит следующие значения:»&vbNewLine

ForEachelement Ingroup

element=»Попугай»

a=a&vbNewLine&element

Next

MsgBoxa

EndSub

Этот код, как и все остальные в этой статье, тестировался в Excel 2016.

Переменная не требуется после ключевого слова Next

Возможно, вы заметили, что я добавил переменную после ключевого слова Next в нижней части цикла в приведенных выше примерах.

Это НЕ обязательно, и вы можете не увидеть его в других примерах, которые вы найдете в Интернете. Однако мне нравится включать переменную после Next по двум причинам.

  1. Мы можем использовать его при отладке кода,
    чтобы увидеть значение переменной, наведя указатель мыши на переменную, когда
    код остановлен.
  2. Это облегчает понимание того, к какой строке For
    подключена следующая строка. Это особенно верно, когда у вас есть несколько циклов
    или вложенных циклов в ваших макросах.

Поэтому я рекомендую добавить переменную после ключевого слова Next в качестве лучшей практики. Немного дополнительной работы заранее сэкономит время и головную боль в будущем. Доверьтесь мне!

Примеры чтения и записи в файл

Пример 1
Открытие (или создание, если он не существует) текстового файла для чтения и записи и запись в него одной строки, состоящей из двух текстовых и одного числового значений. Файл с именем myFile1.txt будет создан в той же папке, где расположен файл Excel с кодом VBA.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

SubTest1()

Dimff AsInteger,ws AsObject

‘Получаем свободный номер для открываемого файла

ff=FreeFile

‘Открываем (или создаем) файл для чтения и записи

Open ThisWorkbook.Path&»\myFile1.txt»ForOutput Asff

‘Записываем в файл одну строку

Write#ff,»Дает корова молоко!»,_

«Куда идет король?»,25.35847

‘Закрываем файл

Close ff

‘Открываем файл для просмотра

Setws=CreateObject(«WScript.Shell»)

ws.Run ThisWorkbook.Path&»\myFile1.txt»

Setws=Nothing

EndSub

Строки и число можно предварительно присвоить переменным, объявленным с соответствующими типами данных, и использовать их для записи данных в файл (в строках кода с оператором Write #, как в этом и следующем примерах).

Пример 2
Открытие (или создание, если он не существует) файла без расширения для чтения и записи и запись в него трех строк: двух текстовых и одной в числовом формате. Файл с именем myFile2 будет создан в той же папке, где расположен файл Excel с кодом VBA.

Так как у файла нет расширения, Windows выведет диалоговое окно для выбора открывающей его программы. Выберите любой текстовый редактор или интернет-браузер.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

SubTest2()

Dimff AsInteger,ws AsObject

‘Получаем свободный номер для открываемого файла

ff=FreeFile

‘Открываем (или создаем) файл для чтения и записи

Open ThisWorkbook.Path&»\myFile2″ForOutput Asff

‘Записываем в файл три строки

Write#ff,»Дает корова молоко!»

Write#ff,»Куда идет король?»

Write#ff,25.35847

‘Закрываем файл

Close ff

‘Открываем файл для просмотра

Setws=CreateObject(«WScript.Shell»)

ws.Run ThisWorkbook.Path&»\myFile2″

Setws=Nothing

EndSub

Пример 3
Считываем строку, разделенную на отдельные элементы, из файла myFile1.txt и записываем в три переменные, по типу данных соответствующие элементам.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

SubTest3()

Dimff AsInteger,str1 AsString,_

str2 AsString,num1 AsSingle

‘Получаем свободный номер для открываемого файла

ff=FreeFile

‘Открываем файл myFile1.txt для чтения

Open ThisWorkbook.Path&»\myFile1.txt»ForInput Asff

‘Считываем строку из файла и записываем в переменные

Input#ff,str1,str2,num1

Close ff

‘Смотрим, что записалось в переменные

MsgBox»str1 = «&str1&vbNewLine_

&»str2 = «&str2&vbNewLine_

&»num1 = «&num1

EndSub

Попробуйте заменить в этом примере строку сначала на строку , затем на строку , чтобы наглядно увидеть разницу между операторами Input # и Line Input #.

В следующих примерах (4 и 5) замена оператора Input # на Line Input # не приведет ни к каким изменениям, так как данные в строках файла myFile2 не разделены на элементы (поля).

Пример 4
Считываем поочередно три строки из файла myFile2 и записываем в три элемента массива, объявленного как Variant, так как в этот файл ранее были записаны две строки с текстом и одна с числом.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

SubTest4()

Dimff AsInteger,a(2)AsVariant,iAsByte

‘Получаем свободный номер для открываемого файла

ff=FreeFile

‘Открываем файл myFile2 для чтения

Open ThisWorkbook.Path&»\myFile2″ForInput Asff

‘Считываем строки из файла и записываем в элементы массива

Fori=To2

Input#ff,a(i)

Next

Close ff

‘Смотрим, что записалось в элементы массива

MsgBox»a(0) = «&a()&vbNewLine_

&»a(1) = «&a(1)&vbNewLine_

&»a(2) = «&a(2)

EndSub

Пример 5
Считываем с помощью цикла Do While… Loop все строки из файла myFile2 и записываем построчно в переменную, объявленную как String (число из третьей строки запишется как текст). Для остановки цикла при достижении конца файла используем функцию EOF.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

SubTest5()

Dimff AsInteger,aAsVariant,bAsString

‘Получаем свободный номер для открываемого файла

ff=FreeFile

‘Открываем файл myFile2 для чтения

Open ThisWorkbook.Path&»\myFile2″ForInput Asff

‘Считываем строки из файла и записываем в элементы массива

DoWhileNotEOF(ff)

Input#ff,a

b=b&a&vbNewLine

Loop

Close ff

‘Смотрим, что записалось в переменную

MsgBoxb

EndSub

Смотрите, как создавать и открывать текстовые файлы с помощью методов CreateTextFile и OpenTextFile. Чтение файла, запись и добавление информации с помощью объекта TextStream.

Содержание рубрики VBA Excel по тематическим разделам со ссылками на все статьи.

For Each Common Examples

Close All Workbooks

This procedure will close all open workbooks, saving changes.

1
2
3
4
5
6
7
8
9

SubCloseAllWorkbooks()

Dimwb AsWorkbook

ForEachwb InWorkbooks

wb.Close SaveChanges=True

Nextwb

EndSub

Hide All Sheets

This procedure will hide all worksheets.

1
2
3
4
5
6
7
8

SubHideAllSheets()

Dimws AsWorksheet

ForEachws InSheets

ws.Visible=xlSheetHidden

Nextws

EndSub

Unhide All Sheets

This procedure will unhide all worksheets.

1
2
3
4
5
6
7
8

SubUnhideAllSheets()

Dimws AsWorksheet

ForEachws InSheets

ws.Visible=xlSheetVisible

Nextws

EndSub

Protect All Sheets

This procedure will protect all worksheets.

1
2
3
4
5
6
7
8

SubProtectAllSheets()

Dimws AsWorksheet

ForEachws InSheets

ws.Protect Password=»…»

Nextws

EndSub

Unprotect All Sheets

This procedure will unprotect all worksheets.

1
2
3
4
5
6
7
8

SubUnprotectAllSheets()

Dimws AsWorksheet

ForEachws InSheets

ws.Unprotect Password=»…»

Nextws

EndSub

Delete All Shapes On All Worksheets

This procedure will delete all shapes in a workbook.

1
2
3
4
5
6
7
8
9
10
11
12

SubDeleteAllShapesOnAllWorksheets()

DimSheet AsWorksheet

DimShp AsShape

ForEachws InSheets

ForEachShp Inws.Shapes

Shp.Delete

NextShp

Nextws

EndSub

Refresh All PivotTables

This procedure will refresh all PivotTables on a sheet.

1
2
3
4
5
6
7
8

SubRefreshAllPivotTables()

Dimpvt AsPivotTable

ForEachpvt InSheets(«Sheet1»).PivotTables

pvt.RefreshTable

Nextpvt

EndSub

Добавление текста в новый документ

Основные объекты, использующиеся в VBA Word для определения места вставки, добавления и форматирования текста – это Selection (выделение), Range (диапазон) и Bookmark (закладка).

Selection и Range позволяют заполнять текстом новые документы или редактировать существующие. Закладки можно использовать для вставки изменяемых реквизитов в шаблоны различных документов: договоры, акты, справки.

Объект Range имеет преимущество перед объектом Selection, так как он может быть создан только программно и не зависит от действий пользователя. Если для вставки и форматирования текста будет использоваться объект Selection, а пользователь во время работы программы просто поставит курсор в другое место документа, результат будет непредсказуем.

Word.Range кардинально отличается от объекта Range в Excel. В приложении Word он представляет из себя набор из одного или множества символов. А также он может вообще не содержать ни одного символа, а быть указателем ввода текста (виртуальным курсором).

Объект Range возвращается свойством Range других объектов приложения Word: Document, Selection, Bookmark, Paragraph, Cell (объект Table).

Вставка текста без форматирования

Если текст вставляется без форматирования, достаточно одной строки кода (myDocument – это переменная):

  • Вставка текста с заменой имеющегося:
  • Добавление текста после имеющегося:
  • Добавление текста перед имеющимся:

Методами InsertAfter и InsertBefore можно вставить текст и на пустую страницу, также, как с помощью свойства Text. Перейти на новый абзац и начать предложение с красной строки можно с помощью ключевых слов vbCr (vbNewLine, vbCrLf) и vbTab.

Вставка текста с форматированием

Для форматирования отдельных участков текста необходимо указать диапазон символов, входящих в этот участок. Здесь нам также поможет объект Range, которому можно задать любой набор символов, содержащихся в документе Word.

Синтаксис присвоения диапазона символов объекту Range:

1
2
3

myDocument.Range(Start=n,End=m)

‘или без ключевых слов Start и End

myDocument.Range(n,m)

  • myDocument – переменная;
  • n – номер точки перед начальным символом;
  • m – номер точки после конечного символа.

Счет точек вставки начинается с нуля. Знаки переноса строки, возврата каретки и табуляции учитываются как отдельные символы. 0 – это для объекта Word.Range виртуальная точка вставки на пустом документе, 1 – точка между первым и вторым символом, 2 – точка между вторым и третьим символом и т.д.

На пустом документе объекту Range можно присвоить только виртуальную точку вставки:

Первый символ в документе с текстом:

Диапазон с 11 по 20 символ:

Реальная точка вставки (курсор) принадлежит объекту Selection, который создается вручную или программно с помощью метода Select.

Вставляем курсор в начало документа:

Эта строка вставит курсор между пятым и шестым символами:

Ссылку на объект Range можно присвоить переменной, но при форматировании ее придется каждый раз переопределять и код получится длиннее. Пример присвоения ссылки объектной переменной:

1
2

DimmyRange AsWord.Range

SetmyRange=myDocument.Range(Start=,End=20)

Для в документе должно быть как минимум 20 символов.

Однострочные примеры редактирования и форматирования текста

Вставка дополнительного текста внутри имеющегося после заданной точки:

Новый абзац с красной строки (предыдущая строка должна заканчиваться символом возврата каретки или переноса строки):

Присвоение шрифту заданного диапазона зеленого цвета:

Меняем обычное начертание на курсив:

Указываем размер шрифта:

Применение стандартных стилей:

Если вас заинтересуют другие команды форматирования текста, запишите их макрорекордером в VBA Word и примените к объекту Range.

Кнопка – элемент управления формы

Вставка кнопки на лист

  1. Выберите вкладку «Разработчик» и нажмите на кнопку «Вставить».
  2. Нажмите на значок кнопки в коллекции «Элементы управления формы».
  1. Кликните в любом месте на рабочем листе Excel.
  2. Откроется окно «Назначить макрос объекту». Нажмите «Отмена», так как макрос для этой кнопки еще не готов.
  3. После нажатия кнопки «Отмена», на рабочем листе появится новая кнопка из коллекции «Элементы управления формы» в режиме редактирования.

Ухватив мышкой за один из кружочков, можно изменить размер кнопки. Ухватив кнопку за границу, можно перетащить ее в другое место. Также, в режиме редактирования, можно изменить название кнопки прямо на ее поверхности.

Чтобы выйти из режима редактирования кнопки из коллекции «Элементы управления формы», кликните в любом месте на рабочем листе.

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

Создание процедуры для кнопки

Кнопке из коллекции «Элементы управления формы» можно назначить макрос (процедуру), размещенную в стандартном программном модуле.

Создайте или откройте файл Excel с расширением .xlsm (Книга Excel с поддержкой макросов) и перейдите в редактор VBA, нажав сочетание клавиш «Левая_клавиша_Alt+F11».

Если вы не создавали ранее в этом проекте VBA стандартный программный модуль, нажмите кнопку «Module» во вкладке «Insert» главного меню. То же подменю откроется при нажатии на вторую кнопку (после значка Excel) на панели инструментов.

Ссылка на модуль появится в проводнике слева. Если модуль создан ранее, дважды кликните по его ссылке в проводнике, и он откроется справа для редактирования.

Нажмите кнопку «Procedure…» во вкладке «Insert» главного меню. Та же ссылка будет доступна при нажатии на вторую кнопку после значка Excel на панели инструментов.

В открывшемся окне добавления шаблона процедуры оставьте выбранным переключатель «Sub», вставьте в поле «Name» название процедуры «NovayaProtsedura» и нажмите «OK».

В стандартный программный модуль будет вставлен шаблон процедуры «NovayaProtsedura».

Вставьте внутрь шаблона процедуры следующий код:

1
2
3
4
5
6
7

‘Записываем в ячейку A1 число 44

Cells(1,1)=44

‘Записываем в ячейку B1 число 56

Cells(1,2)=56

‘Записываем в ячейку C1 формулу, которая
‘вычисляет сумму значений ячеек A1 и B1

Cells(1,3)=»=A1+B1″

На этом процедура (подпрограмма, макрос) для кнопки готова.

Назначение макроса кнопке

Кликните правой кнопкой мыши по кнопке на рабочем листе и в контекстном меню выберите строку «Назначить макрос…», откроется окно «Назначить макрос объекту».

Выберите в списке процедуру «NovayaProtsedura» и нажмите «OK». Кликните левой кнопкой мыши по рабочему листу, чтобы командная кнопка вышла из режима редактирования.

Теперь можете нажать созданную кнопку из коллекции «Элементы управления формы» для проверки ее работоспособности.

Возвращаемые значения

Диалоговое окно, созданное методом Application.InputBox, возвращает значение типа Variant и проверяет соответствие возвращаемого значения типу данных, заданному параметром Type. Напомню, что тип значений Variant является универсальным контейнером для значений других типов, а в нашем случае для возвращаемых в зависимости от значения параметра Type.

Аргументы параметра Type и соответствующие им типы возвращаемых значений:

Type Возвращаемое значение
Формула
1 Число
2 Текст (string)
4 Логическое значение (True или False)
8 Ссылки на ячейки в виде объекта Range
16 Значение ошибки (например, #н/д)
64 Массив значений
Гость форума
От: admin

Эта тема закрыта для публикации ответов.