Запуск макроса по времени

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

Давайте разберемся с тем, какие в Excel и Windows есть возможности для реализации подобного.

Запуск макроса с заданной частотой

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

Откройте редактор Visual Basic одноименной кнопкой на вкладке Разработчик (Developer) или сочетанием клавиш Alt+F11, вставьте новый модуль через меню Insert - Module и скопируйте туда следующий код:

Dim TimeToRun   'глобальная переменная, где хранится следующее время запуска

'это главный макрос
Sub MyMacro()
    Application.Calculate                               'пересчитываем книгу
    Range("A1").Interior.ColorIndex = Int(Rnd() * 56)   'заливаем ячейку А1 случайным цветом :)
    Call NextRun                                        'запускаем макрос NextRun для назначения след.времени запуска
End Sub

'этот макрос назначает время следующего запуска главного макроса
Sub NextRun()
    TimeToRun = Now + TimeValue("00:00:03")     'прибавляем к текущему времени 3 сек
    Application.OnTime TimeToRun, "MyMacro"     'назначаем следующий запуск
End Sub

'макрос для запуска последовательности повторений
Sub Start()
    Call NextRun
End Sub

'макрос для остановки последовательности повторений
Sub Finish()
    Application.OnTime TimeToRun, "MyMacro", , False
End Sub

Давайте разберемся что здесь что.

Для начала, нам нужна переменная, где будет храниться время следующего запуска нашего макроса - я назвал её TimeToRun. Обратите внимание, что содержимое этой переменной должно быть доступно всем нашим последующим макросам, поэтому её надо сделать глобальной, т.е. объявить в самом начале модуля до первого Sub.

Дальше идет наш главный макрос MyMacro, который будет выполнять основную задачу - пересчитывать книгу с помощью метода Application.Calculate. Чтобы было нагляднее, я добавил на лист в ячейку А1 формулу =ТДАТА(), которая выводит дату и время - при пересчете её содержимое будет обновляться прямо у нас на глазах (только включите отображение секунд в формате ячейки). Для дополнительного веселья я добавил в макрос еще и команду заливки ячейки А1 случайно выбранным цветом (код цвета - это целое числов в диапазоне 0..56, которое генерит функция Rnd и округляет до целого числа функция Int).

Заготовка

Макрос NextRun добавляет к предыдущему значению TimeToRun еще 3 секунды и затем назначает следующий запуск главного макроса MyMacro на это новое время. Само-собой, на практике можно использовать любые другие нужные вам временные интервалы, задавая аргументы функции TimeValue в формате "чч:мм:сс".

Ну и, наконец, просто для удобства добавлены еще макросы запуска последовательности Start и её завершения Finish. В последнем из них для прерывания последовательности используется четвёртый аргумент метода OnTime равный False.

Итого, если запустить макрос Start, то вся эта карусель завертится, и мы увидим на листе вот такую картину:

Запуск макроса через 3 сек

Остановить последовательность можно, запустив, соответственно макрос Finish. Для удобства можно обоим макросам назначить сочетания клавиш, используя команду Макросы - Параметры на вкладке Разработчик (Developer - Macros - Options).

Запуск макроса по расписанию

Само-собой, всё описанное выше возможно только в том случае, если у вас запущен Microsoft Excel и в нём открыт наш файл. Теперь давайте рассмотрим более сложный случай: нужно по заданному расписанию, например, каждый день в 5:00 запускать Excel, открывать в нем большой и сложный отчет и обновлять в нем все связи и запросы, чтобы к нашему приходу на работу он был уже готов :)

В такой ситуации лучше воспользоваться Планировщиком Windows - специально встроенной в любую версию Windows программой, которая умеет по расписанию выполнять заданные действия. По факту, вы уже используете его, сами того не зная, ведь ваш ПК регулярно проверяет обновления, качает новые антивирусные базы, синхронизирует облачные папки и т.д. - это всё работа Планировщика. Так что наша задача сводится к тому, чтобы добавить к уже имеющимся задачам ещё одну, которая будет запускать Excel и открывать в нём заданный файл. А мы с вами повесим наш макрос на событие Workbook_Open этого файла - и задача решена.

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

Запускаем Планировщик

Итак, давайте запустим Планировщик. Для этого можно либо:

  • Щелкнуть правой кнопкой мыши по кнопке Пуск и выбрать Управление компьютером (Computer management)
  • Выбрать в Панели управления: Администрирование - Планировщик заданий (Control Panel - Administrative Tools - Task Scheduler)
  • Выбрать в главном меню Пуск - Стандартные - Служебные - Планировщик заданий
  • Нажать сочетание клавиш Win+R, ввести taskschd.msc и нажать Enter

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

Планировщик заданий

Создаем задачу

Чтобы создать новую задачу с помощью простого пошагового мастера нажмем на ссылку Создать простую задачу (Create Basic Task) в правой панели.

На первом шаге мастера нужно ввести название и описание создаваемой задачи:

Создаем задание

Жмем на кнопку Далее (Next) и на следующем шаге выбираем триггер - частоту запуска или событие, которое будет запускать нашу задачу (например, включение компьютера):

Выбираем триггер

Если вы выбрали Ежедневно (Daily), то на следующем шаге нужно будет выбрать конкретное время, дату начала последовательности и шаг (каждый 2-й день, 5-й день и т.д.):

Выбираем время

Следующий шаг - выбираем действие - Запуск программы (Start a program):

Выбираем действие - старт программы

И, наконец, самое интересное - что именно нужно открывать:

Выбираем программу и файл

В поле Программа или сценарий (Program/script) нужно ввести путь к Microsoft Excel как к программе, т.е. непосредственно к исполняемому файлу Excel. На разных компьютерах с разными версиями Windows и Office этот файл может лежать в разных папках, поэтому вот вам несколько способов, как можно узнать его местоположение:
  • Щелкнуть правой кнопкой мыши по иконке (ярлычку) запуска Excel на рабочем столе или в панели задач и выбрать команду Свойства (Properties), а затем в открывшемся окне скопировать путь из строки Target:

    Где лежит excel.exe                      Путь к файлу EXCEL.EXE


  • Открыть любую книгу Excel, затем открыть Диспетчер задач (Task Manager) нажатием Ctrl+Alt+Del и, щелкнув правой кнопкой мыши по строке Microsoft Excel, выбрать команду Свойства (Properties). В открывшемся окне можно скопировать путь, не забыв потом дописать к нему обратный слэш и EXCEL.EXE в конце:

    Excel в Диспетчере задач Windows              Свойства процесса Excel.exe

  • Открыть Excel, открыть редактор Visual Basic сочетанием клавиш Alt+F11, открыть панель Immediate сочетанием Ctrl+G, ввести в неё команду:
    ? Application.Path
    ... и нажать на Enter

    Путь к Excel через VBA
    Cкопировать получившийся путь, не забыв потом дописать к нему обратный слэш и EXCEL.EXE в конце.
В поле Добавить аргументы (необязательно) (Add arguments (optional)) нужно вставить полный путь к книге с макросом, которую мы хотим открыть.

Когда всё ввели, то жмем Далее и затем Готово (Finish). Задача должна добавиться в общий список:

Управление созданной задачей

Управление созданной задачей удобно осуществлять с помощью кнопок справа. Здесь можно протестировать задачу, запустив её немедленно (Run), не дожидаясь наступления заданного срока. Можно временно деактивировать задачу (Disable), чтобы она перестала выполняться на время, например, вашего отпуска. Ну, и изменить параметры (даты, время, имя файла) тоже всегда можно через кнопку Свойства (Properties).

Добавляем макрос на открытие файла

Теперь осталось повесить в нашей книге запуск нужного нам макроса на событие открытия файла. Для этого откроем книгу и перейдем в редактор Visual Basic с помощью сочетания клавиш Alt+F11 или кнопки Visual Basic на вкладке Разработчик (Developer). В открывшемся окне в левом верхнем углу нужно найти наш файл на дереве и двойным щелчком мыши открыть модуль ЭтаКнига (ThisWorkbook).

Если у вас в редакторе Visual Basic не видно этого окна, то его можно открыть через меню View - Project Explorer.

В открывшемся окне модуля добавим обработчик события открытия книги, выбрав его из выпадающих списков в верхней части Workbook и Open, соответственно:

Добавляем обработчик события открытия книги

На экране должна появиться заготовка процедуры Workbook_Open, куда между строчками Private Sub и End Sub и нужно вставить те команды на VBA, которые должны автоматически выполняться при открытии этой книги Excel, когда её по расписанию откроет Планировщик. Вот несколько полезных вариантов для разгона:

  • ThisWorkbook.RefreshAll - обновление всех внешних запросов к данным, запросов Power Query и сводных таблиц. Самый универсальный вариант. Только не забудьте разрешить по умолчанию подключения к внешним данным и обновление связей через Файл - Параметры - Центр управления безопасностью - Параметры центра управления безопасностью - Внешнее содержимое, иначе при открытии книги появится стандартное предупреждение и Excel, ничего не обновляя, будет ждать от вас благословления в виде нажатия на кнопку Включить содержимое (Enable content):

    Предупреждение о подключении к внешним данным

  • ActiveWorkbook.Connections("Имя_Соединения").Refresh - обновление данных по соединению Имя_Соединения.
  • Sheets("Лист5").PivotTables("СводнаяТаблица1").PivotCache.Refresh - обновление отдельно взятой сводной таблицы с именем СводнаяТаблица1 на листе Лист5.
  • Application.Calculate - пересчет всех открытых книг Excel.
  • Application.CalculateFullRebuild - принудительный пересчет всех формул и перестроение всех зависимостей между ячейками во всех открытых книгах (равносильно повторному вводу всех формул).
  • Worksheets("Отчет").PrintOut - распечатать лист Отчет.
  • Call MyMacro - запустить макрос с именем MyMacro.
  • ThisWorkbook.Save - сохранить текущую книгу
  • ThisWorkbooks.SaveAs "D:\Архив\Отчет " & Replace(Now, ":", "-") & ".xlsx" - сохранить книгу в папку D:\Архив под именем Отчет с добавлением к имени даты и времени.

Если вы хотите, чтобы макрос выполнялся только при открытии файла Планировщиком в 5:00, а не каждый раз при открытии книги пользователем в течение рабочего дня, то имеет смысл добавить проверку на время, например:

If Format(Now, "hh:mm") = "05:00" Then ThisWorkbook.RefreshAll

Вот и всё. Не забудьте сохранить книгу в формате с поддержкой макросов (xlsm или xlsb) и можно смело закрывать Excel и отправляться домой, оставив компьютер включенным. В заданный момент (даже если ПК заблокирован) Планировщик запустит Excel и откроет в нём заданный файл, а наш макрос выполнит запрограммированные действия. А вы будете нежиться в постели, пока ваш тяжелый отчёт автоматически пересчитывается - красота! :)

Ссылки по теме


03.12.2018 11:19:11
Все настроил, но при запуске появляется ошибка. Путь и имя файла содержит пробелы,  планировщик обрезает путь до первого пробела и ругается, что не может найти источник.  Как обойти эту неприятность? У меня Win 10
04.12.2018 11:32:38
мне помогло взять весь путь в двойные кавычки

Win7
19.02.2021 12:05:36
Спасибо!! подходит и к Win10
24.02.2021 16:22:05
Также вопрос решается нижним подчеркиванием _ между словами
13.02.2019 09:41:24
второй способ не подходит если файл каждый день обновляется с тем же именем, да к тому же не в xlsm или xlsb и на открытие файла запуск макроса не повесить получается... а первый способ неудобен тем что excel всегда должен быть открыт. Пришлось делать чуть по другому) Создать пустой файл xlsm, в нем Call своего макроса, в уже в самом макросе сначала открываем нужную книгу)  
19.02.2019 10:22:37
А я всегда на планировщик VBS-ку вешаю. В которой можно прописать не только отрытие документа, но и запуск внутри него конкретного макроса

Call Run_macros

'запуск макроса'
Sub Run_macros()
   'запускаем Excel-процесс
   set objExcel = CreateObject ("Excel.Application")
   objExcel.Visible = true    
   Op_writ="Путь до файла с макросом"
   objExcel.Workbooks.Open (Op_writ)
   'запуск макроса
   objExcel.run "Имя макроса"
   'по завершению закрываем документ. Пишем только имя файла, без пути
    objExcel.Workbooks("Мой_файл.xlsb").Close(false)
   'закрываем Excel-процесс
    objExcel.Quit
end sub


Из плюсов, что не нужно ставить макрос на открытие документа, а можно перебором запускать все любые. И даже использовать несколько разных документов
03.03.2019 11:43:16
Отличный вариант! Спасибо, Алексей! :)
31.10.2019 17:36:30
Алексей, приветствую.
А какой макрос в модуле книги? При таком варианте книга сохраняется только, когда запуск через разработчик.

Private Sub Workbook_Open()
ThisWorkbook.RefreshAll
ThisWorkbook.Save
End Sub
06.12.2019 17:46:31
Интересно а можно ли через Call запустить по очерёдности к примеру три макроса и потом закрыть книгу?
19.03.2019 16:29:53
Отличная статейка!
Спасибо! :like::like::like:
Роберт Инкогнито
30.08.2019 14:16:24
Здравствуйте. У меня задача немного иного типа. данные Excel отображаются через браузер. При редактировании на нашей стороне все понятно, а кк сделать чтоб при просмотре данные обновлялись через каждые 2-3 минуты и можно ли такое сделать. Заранее благодарен!
31.10.2019 17:35:23
Спасибо
13.01.2020 13:48:26
Добрый день!!! У меня на работе установлена центральная корпоративная система "Oracle". Возможно ли сделать так, чтобы в этой системе запускался в 05-45 час. утра определенный документ, который ко времени моего приезда на работу был бы преобразован в отсортированный и преобразованный заданным образом готовый Excel-файл?
16.03.2020 15:12:47
Добрый день. Так а как настроить автоматическую рассылку почты с помощью планировщика заданий? Вроде все просто, но после нажатия на кнопку "Готово" выпадает ошибка "Определение задачи использует нерекомендуемый компонент".
14.04.2021 19:18:14
День добрый! Есть вопрос. Дано: книга в гугл-таблице с нумерацией листов 1,2,3, и тд до 21. Как сделать макрос, который ровно в 8:00 утра будет открывать следующий по номеру лист и при этом скрывать предыдущий?
23.12.2022 12:13:19
в закрытом файле ведь макрос не будет работать?
нужно открыть файл - скопировать в него данные макросом из другого, сохраниться и закрыться.
сделать 1 раз в сутки.
получается что макрос на время - только если макрос работает в закрытом файле.
через планировщик? но тогда нельзя ставить макрос на пересчет на открытие. только если с контролькой на время...
Спасибо, очень полезно! Подскажите, как потом закрыть и сохранить открытые фалы, тоже по расписанию.
Наверх