Vba excel сделать лист активным

VBA Excel. Рабочий лист (создание, копирование, удаление)

Создание, копирование, перемещение и удаление рабочих листов Excel с помощью кода VBA. Методы Sheets.Add, Worksheet.Copy, Worksheet.Move и Worksheet.Delete.

Создание новых листов

Создание новых рабочих листов осуществляется с помощью метода Sheets.Add.

Синтаксис метода Sheets.Add

expression.Add [Before, After, Count, Type]

где expression – переменная, представляющая собой объект Sheet.

Компоненты метода Sheets.Add

  • Before* – необязательный параметр типа данных Variant, указывающий на лист, перед которым будет добавлен новый.
  • After* – необязательный параметр типа данных Variant, указывающий на лист, после которого будет добавлен новый.
  • Count – необязательный параметр типа данных Variant, указывающий, сколько листов будет добавлено (по умолчанию – 1).
  • Type – необязательный параметр типа данных Variant, указывающий тип листа: xlWorksheet** (рабочий лист) или xlChart (диаграмма), по умолчанию – xlWorksheet.

*Если Before и After не указаны, новый лист, по умолчанию, будет добавлен перед активным листом.

**Для создания рабочего листа (xlWorksheet) можно использовать метод Worksheets.Add, который для создания диаграмм уже не подойдет.

Примеры создания листов

  • Лист1 в After:=Лист1 – это уникальное имя листа, указанное в проводнике редактора VBA без скобок.
  • Лист1 в After:=Worksheets(«Лист1») – это имя на ярлыке листа, указанное в проводнике редактора VBA в скобках.

Создаваемый лист можно присвоить объектной переменной:

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

Копирование листов

Копирование рабочих листов осуществляется с помощью метода Worksheet.Copy.

Синтаксис метода Worksheet.Copy

expression.Copy [Before, After]

где expression – переменная, представляющая собой объект Worksheet.

Компоненты метода Worksheet.Copy

  • Before* – необязательный параметр типа данных Variant, указывающий на лист, перед которым будет добавлена копия.
  • After* – необязательный параметр типа данных Variant, указывающий на лист, после которого будет добавлена копия.

*Если Before и After не указаны, Excel создаст новую книгу и поместит копию листа в нее. Если скопированный лист содержит код в проекте VBA (в модуле листа), он тоже будет перенесен в новую книгу.

Примеры копирования листов

Если рабочие книги указаны как элементы коллекции Workbooks, в том числе ActiveWorkbook и ThisWorkbook, листы нужно указывать как элементы коллекции Worksheets, использование уникальных имен вызовет ошибку.

Перемещение листов

Перемещение рабочих листов осуществляется с помощью метода Worksheet.Move.

Синтаксис метода Worksheet.Move

expression.Move [Before, After]

где expression – переменная, представляющая собой объект Worksheet.

Компоненты метода Worksheet.Move

  • Before* – необязательный параметр типа данных Variant, указывающий на лист, перед которым будет размещен перемещаемый лист.
  • After* – необязательный параметр типа данных Variant, указывающий на лист, после которого будет размещен перемещаемый лист.

*Если Before и After не указаны, Excel создаст новую книгу и переместит лист в нее.

Примеры перемещения листов

Если рабочие книги указаны как элементы коллекции Workbooks, в том числе ActiveWorkbook и ThisWorkbook, листы нужно указывать как элементы коллекции Worksheets, использование уникальных имен вызовет ошибку.

Удаление листов

Удаление рабочих листов осуществляется с помощью метода Worksheet.Delete

Синтаксис метода Worksheet.Delete

где expression – переменная, представляющая собой объект Worksheet.

Примеры удаления листов

Если рабочие книги указаны как элементы коллекции Workbooks, в том числе ActiveWorkbook и ThisWorkbook, листы нужно указывать как элементы коллекции Worksheets, использование уникальных имен вызовет ошибку.

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

Select и Activate – зачем нужны и нужны ли?

Все начинающие изучать VBA сталкиваются с тем, что записанные через макрорекордер коды пестрят методами Select и Activate.
Если не знакомы с работой макрорекордера – Что такое макрос и где его искать?
Это значительно ухудшает читабельность кода и, как ни странно – быстродействие. Но есть недостатки и куда более критичные. Если код выполняется достаточно долго и он постоянно что-то выделяет – пользователь может заскучать и забыться и начнет тыкать мышкой по листам и ячейкам, выделяя не то, что выделил ранее код. Что повлечет ошибки логики. Т.е. код может и выполнится, но совершенно не так, как ожидалось. Поэтому избавляться от Select и Activate необходимо везде, где это возможно.

Читать еще:  Как сделать бонсай из денежного дерева

Для начала рассмотрим два кода, выполняющие одни те же действия – запись в ячейку А3 листа Лист2 слова “Привет”. При этом сам код запускается с Лист1 и после выполнения код Лист1 должен остаться активным. Чтобы сделать эти действия вручную потребуется сначала перейти на Лист2, выделить ячейку А3, записать в неё слово “Привет” и вернуться на Лист1. Поэтому запись макрорекордером этих действий приведет к такому коду:

Sub Макрос1() Sheets(“Лист2”).Select ‘выделяем Лист2 Range(“A3”).Select ‘выделяем ячейку А3 ActiveCell.FormulaR1C1 = “Привет” ‘записываем слово Привет Range(“A4”).Select ‘после нажатия Enter автоматически выделяется ячейка А4 Sheets(“Лист1”).Select ‘возвращаемся на Лист1 End Sub

Нигде не говорится, что в большинстве случаев все эти Select и Activate в кодах не нужны. Однако вышеприведенный код можно значительно улучшить, если убрать все ненужные Select и Activate:

Sub Макрос1() Sheets(“Лист2”).Range(“A3”).FormulaR1C1 = “Привет” End Sub

Как видно, вместо 5-ти строк кода получилась одна строка. Которая выполняет ту же задачу, что и код из 5-ти строк.
Прежде чем понять как правильно избавляться от лишнего давайте разберемся зачем же тогда VBA записывает эти Select и Activate? Как ни странно, но здесь все очень просто. VBA просто не знает, что Вы будете делать после того, как выделили Лист2. И когда Вы переходите на Лист2 – VBA записывает именно переход(его активацию, выделение). Когда выделяете ячейку – так же именно это действие записывает VBA. Захотите ли Вы затем выделить еще что-то, или закрасить ячейку, или записать в неё формулу/значение – VBA не знает. Поэтому в дальнейшем VBA работает именно с выделенным объектом Selection на активном листе.
Но при написании кода вручную или при правке записанного рекордером мы уже вольны в выборе и знаем, чего хотели добиться и какие действия нам точно не нужны.
Итак, чтобы записать в ячейку слово “Привет” рекордер предложит нам такой код:

Sub Макрос1() Range(“A3”).Select ‘выделяем ячейку А3 ActiveCell.FormulaR1C1 = “Привет” ‘записываем слово Привет Range(“A4”).Select ‘после нажатия Enter автоматически выделяется ячейка А4 End Sub

однако выделять ячейку( Range(“A3”).Select ) совершенно необязательно. Значит один Select уже лишний. После этого идет обращение к активной ячейке – ActiveCell . .FormulaR1C1 = “Привет” означает запись значения “Привет” в эту ячейку.
Пусть не смущает FormulaR1C1 – VBA всегда так указывает запись и значения и формулы. Т.к. перед словом “Привет” нет знака равно – то это значение.
Т.к. ActiveCell является обращением к выделенной ячейке, а выделили мы до этого А3, значит их можно просто “сократить”:

Sub Макрос1() Range(“A3”).FormulaR1C1 = “Привет” Range(“A4”).Select ‘после нажатия Enter автоматически выделяется ячейка А4 End Sub

Теперь у нас код получился короче и понятнее. Однако остался один Select: Range(“A4”).Select . Если нет необходимости выделять ячейку А4 после записи в А3 значения, то надо просто удалить эту строку и после выполнения кода активной будет та ячейка, которая была выделена до выполнения(т.е. выделенная ячейка просто не изменится). Таким образом мы с трех строк сократим код до 1-ой:

Sub Макрос1() Range(“A3”).FormulaR1C1 = “Привет” End Sub

Теперь несложно догадаться, что с листами все в точности так же. Sheets(“Лист2”).Select – Select хоть и не нужен, но и ActiveSheet после него нет. Здесь необходимо знать некоторую иерархию в Excel. Сначала идет сам Excel – Application, потом книга – Workbook. В книгу входят рабочие листы(Worksheets), а уже в листах – ячейки и диапазоны – Range и Cells(Application ->Workbook ->Worksheet ->Range). Если перед Range или Cells не указывать явно лист: Range(“A3”).FormulaR1C1 = “Привет” , то значение будет записано на активный лист. Подробнее можно прочесть в статье: Как обратиться к диапазону из VBA

Маленький нюанс: если сокращаем обращение к объектам, то Select-ов быть не должно вообще. Иначе есть шанс получить ошибку “Subscript out of range”:

буквально это означает, что указанный индекс вне досягаемости. А появляется эта ошибка потому, что нельзя выделить ячейку НЕактивного листа или лист НЕактивной книги. Легко эту ошибку получить например в таком коде:

Читать еще:  Как сделать гидроизоляцию крыши

Sub Макрос2() Windows(“Книга3”).Activate ‘здесь появится ошибка, т.к. пытаемся выделить лист в Книга2 ‘а на данный момент активной является Книга3 Windows(“Книга2”).Sheets(“Лист3”).Select End Sub

Ошибка обязательно появится, т.к. сначала мы активировали кодом книгу “Книга3”, а потом пытаемся активировать лист НЕактивной на этот момент книги “Книга2”. А это сделать невозможно без активации той книги, в которой активируемый лист. Т.е. активация должна происходить именно последовательно: Книга ->Лист ->Ячейка. И никак иначе, если мы хотим активировать именно конкретную ячейку конкретного листа в конкретной книге.
И пример с ячейками:

Sub Макрос2() Sheets(“Лист3”).Select ‘здесь появится ошибка, т.к. пытаемся выделить ячейку на листе “Лист1” ‘а на данный момент активным является Лист3 Sheets(“Лист1”).Range(“C7”).Select End Sub

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

Еще небольшой пример оптимизации:

Sub Макрос2() Windows(“Книга3”).Activate Sheets(“Лист3”).Select Range(“C7”).Select ActiveCell.FormulaR1C1 = “Привет” Range(“C7”).Select Selection.Font.Bold = True With Selection.Interior .Pattern = xlSolid .PatternColorIndex = xlAutomatic .Color = 65535 .TintAndShade = 0 .PatternTintAndShade = 0 End With End Sub

Этот код записывает в ячейку С7 Лист3 книги “Книга3” слово “Привет”, потом делает жирным шрифт и назначает желтый цвет заливке. Убираем активацию книги, листа и ячейки, заменив их прямым обращением:

Приёмы отладки VBA-кода (на примере MS Excel)

Многие из тех, кто часто работает в MS Excel, используют книги или надстройки с VBA-макросами. Зачастую требуется доработать существующее решение, добавив новую функциональность или исправив найденный баг. В поисках места, где скрывается баг или производится нужное вычисление, можно провести немало времени, особенно если проект содержит десятки тысяч строк кода (увы, такие макросы иногда встречаются). Можно прибегнуть к текстовому поиску (например по тексту сообщения, вшитому в код), но иногда удобнее запустить макрос и прибегнуть к пошаговой отладке.

В этом посте описаны несколько приёмов, которые могут быть полезны при отладке макросов на VBA в приложениях MS Office на примере MS Excel.

1. Стандартные точки останова (breakpoint). Step-into, step-over

2. Окна Immediate (“REPL-терминал”), Locals (локальные переменные), Watches (наблюдатели)

3. Условные точки останова на базе watch expression

4. Обработка ошибок

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

появится такая отметка (можно установить и кликом мышью по области слева, где красный кружок):

Теперь как только поток исполнения доберётся до этой строки, он будет приостановлен, а Вы увидите желтый указатель, указывающий на следующую инструкцию:

Многие не знают, что этот указатель можно перемещать на любой statement в пределах функции, просто перетащив мышью желтую стрелку!

Когда Вы приостановили исполнение кода, можете продолжить его исполнение пошагово, с помощью команд step-into, step-over и step-out:

* step-into (F8) – шаг вперёд. Будет выполнен код на строке под указателем, а сам указатель перемещён на следующую строку. Однако если в текущей строке есть вызов другой функции, указатель переместится внутрь этой функции

* step-over (Shift-F8) – полностью аналогичен step-into, за исключением того, что эта команда позволяет не “проваливаться” в вызов вложенных функций

* step-out (Ctrl-Shift-F8) – текущая функция будет исполнена до конца, а исполнение приостановлено в вызывающей функции. Полезна, если Вы случайно провалились в длинную функцию командой step-into

Теперь немного о том, как узнать значения переменных и иную полезную информацию.

2. В нижней части экрана VBE (Visual basic editor) Вы можете увидеть три окна:

* Immediate (терминал для выполнения кода и вывода текстовой информации)

* Locals (локальные переменные)

Если Вы не видите эти окна, включите их отображение в меню View

Читать еще:  Дверь мне сделал видео

Разберём подробнее, какие возможности открывают нам эти инструменты.

Окно Immediate представляет собой REPL-терминал, в котором можно ввести выражение и запустить его нажатием Enter. Чтобы вывести результат в этот же терминал, передайте результат выражения в функцию Debug.Print (кстати, эту функцию можно вызвать и в основном коде макроса – результат так же будет выведен в консоль Immediate). В самой консоли можно воспользоваться и сокращённой версией этой команды – знаком вопроса:

Обратите внимание, что с помощью сочетаний Ctrl+Space и Ctrl+J можно вызывать окно IntelliSense , также как и в основном редакторе кода.

Окно Locals позволяет увидеть значения переменных, доступных в текущем контексте:

Например, текущее значение счётчика цикла или состав коллекции. Обратите внимание, что для объектов Collection при раскрытии отображаются значения элементов коллекции, а для словарей (Dictionary) – их ключи. Поэтому чтобы узнать значение самого элемента в словаре, нужно вычислить выражение, например такое:

Это можно сделать при помощи “наблюдателя” – watch expression

Выделите выражение и выполните команду Add watch. в контекстном меню (доступном с помощью правой кнопки мыши), или введите нужно выражение вручную в окне добавления наблюдателя:

Осторожно: выражение d.Item(“key1”) при вычислении может добавить элемент к словарю, если такой ключ в словаре отсутствует. Поэтому не забудьте удалить наблюдатель, когда он станет ненужным, иначе в дальнейшем можно провести немало времени, выясняя откуда взялся лишний элемент в словаре.

3. Условные точки останова, которые можно реализовать с помощью наблюдателей.

Вероятно, Вы обратили внимание, что в меню добавления наблюдателя помимо стандартной опции “Watch Expression” есть ещё две: “Break When Value Is True” и “Break When Value Changes”. Они позволяют добиться приостановки исполнения макроса при наступлении соответствующего условия (выражение истинно, либо значение выражения изменилось). Эта возможность может оказаться особенно полезной, например, при отладке циклов. Если Вы знаете, что макрос, который в цикле обрабатывает строки на листе Excel, сталкивается с ошибкой, скажем, на строке 42, то можно избежать ручного “пролистывания” 41 предшествующей итерации, добавив выражения вида i=42 с опцией Break When Value Is True, где i – это переменная счётчика цикла.

4. Напоследок хотел бы немного рассказать об обработке ошибок в VBA.

В настройках VBE Вы можете найти выбор из трёх опций (меню Tools -> Options, вкладка General):

Break on All Errors

Break in Class Module

Break on Unhandled Errors

По умолчанию, как правило, установлена последняя опция, которая позволяет программисту обрабатывать ошибки с помощью директив On Error Goto (показать сообщение об ошибке, “прибраться за собой” – закрыть книгу или соединение) и On Error Resume Next (игнорировать ошибку и продолжать исполнение). Однако, когда Вы столкнётесь с ошибкой вида “Извините, что-то пошло не так =(“, которая отображается из обработчика в On Error Goto, будет трудно определить место, где произошла ошибка. В этом случае пригодится опция Break on All Errors, которая позволит проигнорировать директивы On Error и перейти к тому месту в коде, где и произошла ошибка. В этот момент может пригодиться и окно Locals, где Вы сможете увидеть, например, текущее значение счётчика цикла, и понять, при обработке какой строки на листе Excel возникла ошибка.

Указанные опции обработки ошибок устанавливаются на уровне настроек пользователя, и не сохраняются в VBA-проекте.

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

В свободное время я пилю надстройку общего назначения для MS Excel на платформе VSTO. Проект доступен на гитхабе под лицензией MIT (можете свободно использовать в своих проектах, форкать и изменять под свои нужды):

Призываю неравнодушных пользователей оставить пожелания по добавлению новых функций (заводите issue на гитхабе, или пишите прямо тут в комментариях), а разработчиков, знакомых с технологией VSTO (или желающих познакомиться) – присоединяться к разработке!

Это мой первый пост на Пикабу, буду рад конструктивной критике в комментариях и ЛС.

Источники:

http://vremya-ne-zhdet.ru/vba-excel/rabochiy-list-sozdaniye-kopirovaniye-udaleniye/

http://www.excel-vba.ru/chto-umeet-excel/select-i-activate-zachem-nuzhny-i-nuzhny-li/

http://pikabu.ru/story/priyomyi_otladki_vbakoda_na_primere_ms_excel_7151540

Ссылка на основную публикацию
Статьи на тему: