Vba excel макрос по времени

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

Весьма частый случай на практике: вам нужно запускать один или несколько ваших макросов в заданное время или с определенной периодичностью. Например, у вас есть большой и тяжелый отчет, который обновляется полчаса и вы хотели бы запускать обновление за полчаса до вашего прихода на работу утром. Или у вас есть макрос, который должен делать автоматическую рассылку сотрудникам с заданной периодичностью. Или, работая со сводной таблицей, вы хотите, чтобы она обновлялась «на лету» каждые 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 и откроет в нём заданный файл, а наш макрос выполнит запрограммированные действия. А вы будете нежиться в постели, пока ваш тяжелый отчёт автоматически пересчитывается — красота! :)

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

  • Что такое макросы, как их использовать, куда вставлять код на Visual Basic в Excel
  • Как создать свою надстройку с макросами для Excel
  • Как использовать Личную Книгу Макросов (Personal Macro Workbook) как библиотеку для своих макросов в Excel

Содержание

  1. Трюк №82. Как запустить макрос в определенное время
  2. VBA Excel. Метод Application.OnTime
  3. Синтаксис метода Application.OnTime
  4. Параметры метода Application.OnTime
  5. Примеры выполнения процедур по времени
  6. Schedule a Macro with VBA Application.OnTime
  7. The VBA Tutorials Blog
  8. The Application.OnTime Method
  9. Scheduling the Macro
  10. Specific Times
  11. Relative Times
  12. Specifying the Macro
  13. Scheduling Macros in Other Workbooks
  14. Scheduling Macros in Closed Workbooks
  15. Automation and Recursion
  16. Continuity and Canceling
  17. Stability
  18. Conclusion

Трюк №82. Как запустить макрос в определенное время

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

При помощи метода Application.OnTime можно запускать макрос автоматически, но сначала необходимо провести небольшую настройку. Предположим, есть макрос, который вы хотите запускать каждый день в 15:00 (3:00 p.m.). Сначала нужно определить, как заставить выполниться метод OnTime. Это можно сделать с помощью события Workbook_0pen в частном модуле для объекта Workbook.

В Windows самый быстрый способ попасть в частный модуль объекта Workbook (ThisWorkbook, Эта Книга) — правой кнопкой мыши щелкнуть значок Excel рядом с меню Файл (File) и в контекстном меню выбрать команду Исходный текст (View Code). (На Macintosh откройте VBE и затем откройте модуль объекта Workbook в окне Project.) Введите код из листинга 7.2.

//Листинг 7.2 Private Sub Workbook Open () Application.OnTime T1meValue(«15:00:00»). «MyMacro» End Sub

Вместо MyMacro следует подставить имя макроса, который вы хотите выполнить. Он должен находиться в стандартном модуле и содержать метод OnTime, как показано в листинге 7.3.

//Листинг 7.3 Sub MyMacro () Application.OnTime T1meValue(«15:00:00»), «MyMacro» ‘ВАШ КОД End Sub

Процедура MyMacro будет запускаться каждый день в 15:00, пока Excel остается открытым.

Теперь предположим, вы хотите выполнять MyMacro каждые 15 минут после открытия книги. И снова вы будете запускать процедуру во время открытия книги, поэтому правой кнопкой мыши щелкните значок Excel рядом с меню Файл (File), выберите команду Исходный текст (View Code) и введите код из листинга 7.4.

//Листинг 7.4 Private Sub Workbook_BeforeClose(Cancel As Boolean) Application.OnTime dTime. «MyMacro». . False End Sub Private Sub Workbook_Open() Application.OnTime Now + TimeValue(«00:15:00»), «MyMacro» End Sub

В любом стандартном модуле (который можно открыть командой Insert → Module) введите код, приведенный в листинге 7.5.

//Листинг 7.5 Public dTime As Date Sub МуМасrо() dTime = Now + TimeValue(«00:15:00») Application.OnTime dTime, «MyMacro» ‘ВАШ КОД End Sub

Обратите внимание, что.вы передаете значение времени, равное 15 минутам, общей (public) переменной dTime. Это нужно, чтобы вы могли отменить метод OnTime в событии Workbook_BeforeC1ose, присвоив дополнительному аргументу Schedule значение Ложь (False). По умолчанию его значение равно Истина (True), поэтому, изменив значение на Ложь (False), вы приказываете Excel отменить метод OnTime, настроенный на выполнение в указанное время.

Если не передать время в переменную, Excel не будет знать, какой метод OnTime нужно отменить, так как значение Now + TimeValue(«00:15:00») не является статическим, но становится статическим, когда передается в переменную. Если вы не присвоите дополнительному аргументу Schedule значение Ложь (False), рабочая книга будет автоматически открываться каждые 15 минут, после того как вы закроете ее, и выполнять макрос MyMacro.

Источник

VBA Excel. Метод Application.OnTime

Выполнение процедуры VBA Excel без аргументов в назначенное время или через определенный промежуток времени с помощью метода Application.OnTime.

Синтаксис метода Application.OnTime

Параметры метода Application.OnTime

Основные параметры:

  1. EarliestTime – время, когда необходимо выполнить указанную процедуру.
  2. Procedure – имя выполняемой процедуры.

Процедура Procedure не должна иметь аргументов и не может быть объявлена в модуле формы.

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

  • TimeValue(«hh:mm:ss») – чтобы запланировать выполнение указанной процедуры в определенное время суток.
  • Now + TimeValue(«hh:mm:ss») – чтобы запланировать выполнение указанной процедуры по истечении заданного времени с момента запуска процедуры с методом Application.OnTime .

Дополнительные параметры:

  1. LatestTime – интервал времени, в течение которого можно запустить указанную процедуру, если Microsoft Excel в назначенное время выполняет другую процедуру. По умолчанию указанная процедура будет запущена в любом случае после завершения предыдущей процедуры. Подробнее об этом читайте на сайте разработчика.
  2. Schedule – если задано значение True, будет запланировано выполнение указанной процедуры, False – очистка ранее установленной процедуры. Значение по умолчанию – True.

Параметр LatestTime я не тестировал, а вот любое применение параметра Schedule в значении False у меня в Excel 2016 вызывает ошибку. Поэтому в примерах я эти параметры не использую.

Примеры выполнения процедур по времени

Пример 1
Однократный запуск внешней процедуры через заданный промежуток времени:

Источник

Schedule a Macro with VBA Application.OnTime

The VBA Tutorials Blog

Programmers love to make things more efficient. Pushing buttons just to make a code run is particularly annoying, especially when the code is supposed to run at the same time every time. Fortunately, Excel makes scheduled macro automation simple with the Application.OnTime method.

The Application.OnTime Method

The Application.OnTime method is part of the Application object, which means it lives inside Excel’s main application. If you’re using Intellisense, when you type Application.OnTime , you should see this:

Notice there are four arguments, two of which are optional:

  • EarliestTime is the time you want your specified macro to start running
  • Procedure is the name of the macro you want to call, which can be in the same workbook or another workbook
  • LatestTime is optional, and it specifies the last time the macro can be run. It puts a limit or deadline on the latest time Excel will attempt to start the macro, and if the deadline is missed, the macro is not executed
  • Schedule is used for canceling previously scheduled OnTime macros

Scheduling the Macro

There are many ways to schedule your macros to run using the OnTime method. The most common ways are via specific times (1am, 11:45, 19:30) or a time relative to the existing time. You can also make other scheduling decisions, like scheduling a macro to run relative to a future date based on some user input.

Again, the argument EarliestTime is your start time, and the scheduling mechanism will try to execute the specified macro at this time. As long as nothing prevents the called macro from running, this is synonymous with the start time. Conversely, if there is something preventing the called macro from running, LatestTime is essentially the time at which Excel stops trying to run the macro.

Specific Times

If a task must be run every day at the same time, it makes sense to apply the specific time technique. Let’s say you have to run a macro every day at 7am before you come into the office. You would execute a code snippet like this to make sure your macro runs before you even arrive:

In this example, early_morning_task is the name of the macro you have to run at 7am.

You could also use the TimeSerial function or the CDate function if you were grabbing your times from user-input variables:

Make powerful macros with our free VBA Developer Kit

It’s easy to copy and paste a macro like this, but it’s harder make one on your own. To help you make macros like this, we built a free VBA Developer Kit and wrote the Big Book of Excel VBA Macros full of hundreds of pre-built macros to help you master file I/O, arrays, strings and more — grab your free copy below.

Notice the use of CInt to ensure the value going into TimeSerial is an integer. Also, note that this setup uses 24-hour format, and you will need to account for that by explicitly forcing users to use 24-hour formats, making an educated guess (programmatically!), or by offering the option of entering AM/PM and calculating the 24-hour format of the input.

Relative Times

You can also schedule macros to run at relative times. The most common way is to schedule it relative to the current time. You would do this by using the Now function to grab the current time then adding some amount of time to it.

The DateAdd function is a good option if you want to add two times together, and it plays well with the Now function. The following snippet fires off the macro nseconds from now, where nseconds is determined by the user.

If you’re scheduling over longer time periods, you can change the “s” to an “m” for minutes or “h” for hours and adjust the prompt.

Remember that a macro is executed line-by-line, so if the InputBox opens at 19:33:09 and the user waits 10 seconds then enters 15, the macro will fire at 19:33:34, not at 19:33:24.

Specifying the Macro

When you only have a single workbook, you can reference the macro directly by using its name. To write more robust code, you can specify the module to ensure no future changes to the workbook, like adding another module with an identically-named macro, will cause issues.

In this snippet, we are running the macro_to_schedule from Module2. If the Application.OnTime line runs in Module1 and there is a macro entitled macro_to_schedule there, we must specify we want the identically-named macro from Module2 . It’s certainly allowed, but I don’t recommend naming your macros exactly the same in different modules because it can become confusing for a human.

Scheduling Macros in Other Workbooks

Believe it or not, you can extend the Application.OnTime method to other workbooks, even if they have identically-named macros. I have plenty of workbooks that have subroutines named main , for example.

Keep in mind that Application.OnTime lives at the application level and schedules there, so you can run the OnTime method from one workbook and it will execute macros in another workbook as long as you properly specify the name of the other workbook. A call to a workbook named Other Workbook.xlsm with a macro named main in it will look like this:

Don’t forget that Excel uses ! to separate the workbook name from the Modules and Sheets but uses . to separate the Module/Sheet from the macro.

Scheduling Macros in Closed Workbooks

This extends even further to closed workbooks. Since the scheduling happens at the application level, as long as the application is open, the scheduled macro should execute. A user can close all of the workbooks but leave the application running and it will be fine. In other words, all the workbooks can be closed but Excel must remain open for the OnTime method to operate.

To call a macro in a closed workbook, you need to supply the full filepath to the workbook. Other than this, it’s exactly the same as scheduling a macro in another workbook:

Important: the workbook will open and try to execute the macro. If security settings are such that the opened workbook is not trusted, the macro cannot run until someone clicks “Enable Macros”. Make sure you set the workbook to be trusted before using this method or you won’t get much automation benefit.

Automation and Recursion

If you run the scheduler once, you will get a single scheduled event. However, if you need to run the macro with the scheduler to schedule it every day, you just shifted the burden from running the macro directly to running the scheduler.

There are times this is useful, like when you cannot determine programmatically when you will need the macro, but you will know before the end of the day and it must be run overnight. In that case, you could run the scheduling macro before you go home only on days you need it.

But if you know your macro will run every day no matter what, you can actually automate the scheduling itself. The best way to do this is write a recursive subroutine, which is a subroutine that calls itself.

There are two common ways to do this: call the scheduler macro from the task macro or roll everything into one and make the scheduler macro the same as the task macro.

First Method
This is a code block using two separate subroutines, which makes breaking them apart easier:

This will run task_sub every day at 5am. Notice how the task_sub macro calls the scheduler macro at the end, which queues up the next execution of the macro for the following morning.

Second Method
This method calls the scheduling method Application.OnTime at the end of the macro, although you can make it the beginning or anywhere in between, if you’d like. The main drawback is you must run the full task every time. It also violates the etiquette of breaking code into more readable chunks with specific purposes. But nevertheless, it works just as well.

Continuity and Canceling

For Application.OnTime to work, the Excel instance in which it was run must remain open. It is possible to open more than one instance of Excel, and that may be useful if you use Excel often and habitually close the main window. If the instance is closed, all scheduled information will be lost — even if Excel is reopened. This is very important to remember.

If you need to run a macro at a certain time each day even if Excel is closed, you’ll have to call the macro from a file, like a .vbs file, and schedule your macro using the Task Scheduler.

There is also the possibility that a scheduled task must be canceled. This can be done by quitting the instance of Excel in which it was created, but doing this will nullify all scheduled tasks. What if you only wanted to cancel one schedule macro? To keep the Excel instance open and schedule a particular task, the exact time and name of the scheduled subroutine must be used. Then the Schedule parameter of the OnTime method should be set to the Boolean False .

This code block has a scheduler macro and a cancellation macro:

To cancel a scheduled task_sub macro, the user can simply run the cancel_macro routine. Notice the positional passing of parameters. If you don’t want to use blank positional arguments like here, use named arguments like this:

Because exact times are important, and sometimes different users might enter different times, you will need to store these scheduled times somewhere. One obvious place is in a cell that won’t be overwritten. Another, but more involved option, is to write the time and macro name variables to a simple text file. A third, even more involved option, is to write custom properties for the workbook in which the scheduler resides. However you do it, it is a good idea to store the times somewhere or risk having to close Excel to cancel a macro you “lost.”

Stability

Automation is great, but only if the code is stable and what you expected to happen actually happens. If your application is meant to run a macro at a certain time every day and you plan to automate it with recursion, it is very important that Excel remains stable. That could mean manual garbage collection, learning about Windows and how the operating system interacts with Excel, and error trapping.

In fact, error trapping is extremely important for rapid automation in VBA. If an application is designed to run every 5 minutes and there is no error trapping, you’re almost guaranteed to come back to a run-time error or useless output. This becomes particularly important when no humans are monitoring the program. Computers won’t fix themselves, so you’ll need a way to alert humans. One way to do this is to send yourself an email once an error is encountered.

Don’t neglect stability and error trapping, especially in unattended automation scenarios. Alert humans to the errors.

Conclusion

Application.OnTime makes scheduling macros easy, as long as Excel remains open. Since scheduling inherently involves some future time, the OnTime method can be called and your macro will run later. This makes recursion easy because the code is not executed immediately like most other VBA macros. That means automation becomes easy, and that’s the point of writing macros, right? It’s certainly one of the most prominent uses of Application.OnTime .

The most important caveats are that 1. Excel, the application, cannot be closed 2. cancelation requests require the exact naming and time used to schedule the task to properly cancel the task. 3. code and macros must be stable for long-term, reliable automation 4. error trapping is not to be dismissed

If you address these caveats satisfactorily, scheduling and automation in Excel using Application.OnTime can open many, many opportunities.

I hope you’ll take a minute to subscribe for more VBA tips. Simply fill out the form below and we’ll share our best time-saving VBA tips.

Ready to do more with VBA?
We put together a giant PDF with over 300 pre-built macros and we want you to have it for free. Enter your email address below and we’ll send you a copy along with our VBA Developer Kit, loaded with VBA tips, tricks and shortcuts.

Before we go, I want to let you know we designed a suite of VBA Cheat Sheets to make it easier for you to write better macros. We included over 200 tips and 140 macro examples so they have everything you need to know to become a better VBA programmer.

This article was written by Cory Sarver, a contributing writer for The VBA Tutorials Blog. Visit him on LinkedIn and his personal page.

Источник

Выполнение процедуры VBA Excel без аргументов в назначенное время или через определенный промежуток времени с помощью метода Application.OnTime.

Application.OnTime EarliestTime, Procedure, LatestTime, Schedule

Параметры метода Application.OnTime

Основные параметры:

  1. EarliestTime – время, когда необходимо выполнить указанную процедуру.
  2. Procedure – имя выполняемой процедуры.

Процедура Procedure не должна иметь аргументов и не может быть объявлена в модуле формы.

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

  • TimeValue(«hh:mm:ss») – чтобы запланировать выполнение указанной процедуры в определенное время суток.
  • Now + TimeValue(«hh:mm:ss») – чтобы запланировать выполнение указанной процедуры по истечении заданного времени с момента запуска процедуры с методом Application.OnTime.

Дополнительные параметры:

  1. LatestTime – интервал времени, в течение которого можно запустить указанную процедуру, если Microsoft Excel в назначенное время выполняет другую процедуру. По умолчанию указанная процедура будет запущена в любом случае после завершения предыдущей процедуры. Подробнее об этом читайте на сайте разработчика.
  2. Schedule – если задано значение True, будет запланировано выполнение указанной процедуры, False – очистка ранее установленной процедуры. Значение по умолчанию – True.

Параметр LatestTime я не тестировал, а вот любое применение параметра Schedule в значении False у меня в Excel 2016 вызывает ошибку. Поэтому в примерах я эти параметры не использую.

Примеры выполнения процедур по времени

Пример 1
Однократный запуск внешней процедуры через заданный промежуток времени:

Sub Primer1()

    Application.OnTime Now + TimeValue(«00:00:10»), «Procedure1»

End Sub

Sub Procedure1()

    MsgBox «Процедура запущена!»

End Sub

Процедура Procedure1 будет выполнена через 10 секунд после запуска процедуры Primer1.

Пример 2
Однократный запуск внешней процедуры в заданное время:

Sub Primer2()

    Application.OnTime TimeValue(«12:00:00»), «Procedure2»

End Sub

Sub Procedure2()

    MsgBox «Системное время — 12 часов!»

End Sub

Процедура Procedure2 будет выполнена в 12 часов по системному времени компьютера, если ранее была запущена процедура Primer2.

Пример 3
Многократный запуск внешней процедуры:

Sub Primer3()

    Application.OnTime Now + TimeValue(«00:00:01»), «Procedure3»

End Sub

Sub Procedure3()

    Cells(1, 1) = Cells(1, 1) + 1

        If Cells(1, 1) = 100 Then Exit Sub

    Call Primer3

End Sub

Процедура Primer3 запускает «условно бесконечный» секундомер в ячейке A1 активного рабочего листа, ограниченный 100 секундами с помощью условия.

Пример 4
Сохранение рабочей книги Excel каждые 10 минут:

Sub Primer4()

    Application.OnTime Now + TimeValue(«00:10:00»), «Procedure4»

End Sub

Sub Procedure4()

    ThisWorkbook.Save

    Call Primer4

End Sub

Процедуры Primer4() и Procedure4() будут работать в бесконечном цикле, сохраняя рабочую книгу Excel каждые 10 минут, до закрытия этой книги. Закрывать книгу следует не менее, чем через 10 минут после внесения последних изменений, для гарантированного их сохранения.


If you need Excel to run some VBA at a specific time, or repeatedly at set intervals, you can use the Application.OnTime method.

A basic call to Ontime requires that you supply a time when you want the code to run, and the name of the macro you want to run.

basic ontime call

The argument EarliestTime is called this because Excel will actually execute the Procedure no earlier than EarliestTime, but possibly later.

There’s no guarantee that your scheduled macro will run exactly when you want because Excel may be busy doing something else.

It may be executing some other VBA, or you may be entering data into a sheet (Enter mode). If Excel is not in Ready, Copy, Cut or Find mode, execution of your scheduled macro may be delayed.

There are two optional arguments, LatestTime and Schedule.

ontime call with all arguments

As we’ve just seen, Excel may not run your macro exactly at the time you want. By specifying LatestTime, we’re giving Excel a window, between EarliestTime and LatestTime, during which you want it to run your VBA.

If your scheduled code is delayed, and Excel is only ready to execute the macro after LatestTime, then it won’t run it at all.

The value of Schedule indicates whether your are setting a task (True), or cancelling one (False).

The default value is True so there’s no need to specify Schedule unless you are cancelling a previously set task.

Cancelling OnTime

If you want to cancel an OnTime task once you’ve scheduled it, you can do so like this

cancelling ontime

Cancelling OnTime requires that you specify the name of the macro, and exact time it is set to run. This means you need to store both of these somewhere.

Excel doesn’t provide any way for you to check what macros are scheduled to run, so you must keep track of these things yourself.

The easiest way would be to store the values in public variables/constants, or on a worksheet. Although you could store them in the registry if you want.

Download Example Workbook

Enter your email address below to download the sample workbook.

By submitting your email address you agree that we can email you our Excel newsletter.

Running Code at Set Intervals

If you want to repeatedly run the same macro at set periods you make the macro call itself.

First, write the macro that sets the OnTime schedule, I’m calling it SetOnTime. This macro will set a schedule for a macro called MyCode.

Then write the MyCode macro, which has the code you want to execute, and a call to SetOnTime.

When you run SetOnTime it sets the OnTime call, which when it runs, calls MyCode.

MyCode then calls SetOnTime again, and so on ……..

Running OnTime at set intervals

Specifying the Time

Time in Excel is a funny old thing and often causes a lot of confusion.

If you understand the way time is stored as serial number you can set an OnTime task like this

5 Seconds from Now

ontime 5 seconds from now

1 Hour from Now

ontime 1 hour from now

1 Day from Now

ontime 1 day from now

Or you can use TimeValue and TimeSerial to set a task for a particular time from now.

TimeValue : 1 hour 15 mins From Now

timevalue 1 hour 15mins from now

TimeSerial : 45 seconds From Now

timeserial 45 seconds from now

If you want to set a macro to run at a specific time, use Timevalue.

TimeValue : Run at 8.30pm.

timevalue run at specific time

Storing Time in a Public Constant

Of course if you are setting something to run at intervals you can use a public constant and store the interval in that.

I’ve declared a public constant called Interval and set it to 5.

By using TimeSerial I can set the interval that the macro runs at to every 5 seconds.

using public constant for interval

Multiple OnTime Tasks

You can set multiple tasks to run using OnTime. But remember that you need to keep a record of them if you want to be able to programatically unschedule them.

Running a Macro from a Closed Workbook

If you schedule a macro and then close the workbook containing the macro, Excel will try to open that workbook before running the macro.

In this scenario, if the workbook is not in a trusted location, you may find that macros in the workbook are disabled, and the scheduled macro will not run.

When Scheduled Tasks Won’t Run

A scheduled macro won’t run if the Excel application is closed.

A scheduled task will not execute in break mode. If you are debugging your VBA, like stepping through code, or a VBA routine has caused an error and you have started to debug it, scheduled tasks won’t execute and you’ll get an error telling you so.

break mode

If another VBA routine has caused an unhandled error and halted, scheduled tasks won’t execute until that error is acknowledged and Ended.

end the code not debug

Запуск макроса через определённое время
Таймер. Application.OnTime

Хочу рассказать как можно в Excel использовать таймеры. Как ни странно, но они очень часто применяются, например, при составлении тестов, когда необходимо дать определённое время на выполнение теста. Или необходимость запускать автосохранение книги через каждые 5 минут. А так же во многих других случаях. Делается таймер при помощи команды

Application.OnTime

Запуск макроса через некоторое время

Продемонстрирую на примере простейшего кода:

Sub Procedura_1()

Application.OnTime Now + TimeValue(«00:00:03»), «Proc»

End Sub

Sub Proc()

MsgBox «Время вышло!», vbInformation, «Пример таймера»

End Sub

В этом примере таймер задаётся в процедуре Procedura_1(), а вот процедура Proc() выполняется через заданный промежуток времени. В данном случае тут отсчитывается 3 секунды от текущей даты Now + TimeValue(«00:00:03»).
Оператор Now в данном случае является переменной, которая несёт в себе полную информацию, т.е. число, месяц, год, часы, минуты, секунды. Это хорошо заметно при пошаговом выполнении макроса.

Дальше идёт прибавление некоторого значения к текущему времени Now + TimeValue(«00:00:03»). В данном случае мы к текущей дате прибавили всего 3 секунды.
И после того как мы задали время, через запятую, указываем имя самого макроса, который должен выполниться «Proc».

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

Теперь понятно, что макрос «Proc» выполнится через 3 секунды после макроса Procedura_1.

Хочу обратить внимание, что TimeValue(«00:00:03») можно заменить на TimeSerial(0, 0, 3) и предыдущую процедуру можно записать так:

Sub Procedura_2()

Application.OnTime Time + TimeSerial(0, 0, 3), «Proc»

End Sub

Из скриншота видно, что цифры через запятую обозначают часы, минуты и секунды.

Запуск макроса в заданное время

Теперь рассмотрим такой случай когда необходимо, чтобы макрос сработал в заданное время. Например в 18:00. Делается это по аналогии с предыдущей записью, только мы упускаем оператор Now или Time.

Sub Zapusk()

Application.OnTime TimeValue(«18:00:00»), «Proce»

End Sub

Sub Proce()

MsgBox «Время пришло!», vbInformation, «Пример таймера»

End Sub

При такой записи процедура Proce() выполнится в 18:00 вечера.

Отмена таймера

Ну вот. Всё вроде хорошо. Но вдруг мы передумали и нам теперь не надо запускать этот макрос в 18:00 вечера. Отменить данную команду можно при помощи команды Schedule:=False, которая отменяет запуск указанного макроса. Например:

Sub Zapusk()

Application.OnTime TimeValue(«18:00:00»), «Proce»

End Sub

Sub Otmena()

Application.OnTime TimeValue(«18:00:00»), «Proce», Schedule:=False

End Sub

Sub Proce()

MsgBox «Время пришло!», vbInformation, «Пример таймера»

End Sub

В этом случае у нас есть макрос который включает таймер — Zapusk, и макрос который отключает таймер —Otmena.

Если запустить макрос Zapusk, то в 18:00 у нас выполнится макрос Proce. А вот если до 18:00 выполнить макрос Otmena, то макрос Proce не запустится.

Зацикливание таймера

Ну вот мы и подошли к вопросу как сделать автосохранение книги, или внесение каких-то определённых данных через заданный промежуток времени. Сделать это просто.

Sub Procedura_2()

Application.OnTime Time + TimeSerial(0, 0, 5), «Proc»

End Sub

Sub Proc()

MsgBox «Время вышло!», vbInformation, «Пример таймера»

Procedura_2

End Sub

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

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

Public sostoyanie As Boolean

Sub Procedura_2_Zapusk()

sostoyanie = True

Procedura_2

End Sub

Sub Procedura_2_Otmena()

sostoyanie = False

End Sub

Sub Procedura_2()

Application.OnTime Time + TimeSerial(0, 0, 5), «Proc»

End Sub

Sub Proc()

MsgBox «Время вышло!», vbInformation, «Пример таймера»

If sostoyanie = True Then Procedura_2

End Sub

В этом случае запуск макроса осуществляется процедурой Procedura_2_Zapusk, а его остановка процедуройProcedura_2_Otmena.

Событие возникающее при открытии и закрытии книги

Открытие книги. Workbook_Open

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

Делается это следующим образом. Заходим в окно VB, щёлкаем слева по книге «ЭтаКнига». Открывается окно. В левом верхнем окошке выбираем пункт Workbook и правом окошке Open.

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

Private Sub Workbook_Open()

End Sub

Если в этот код поместить информационное сообщение, то при открытии книги нам будет появляться сообщение (не забываем, что при отключенных макросах такое сообщение нам не появится).

Private Sub Workbook_Open()

MsgBox «Привет » & Application.UserName, vbInformation, «Приветствие»

End Sub

Закрытие книги. Workbook_BeforeClose

Рассмотрим событие, которое возникает при закрытии книги, если быть точнее, то перед закрытием.

Заходим в окно VB, щёлкаем слева по книге «ЭтаКнига». Открывается окно. В левом верхнем окошке выбираем пункт Workbook и правом окошке BeforeClose.

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

Private Sub Workbook_BeforeClose(Cancel As Boolean)

End Sub

Если в этот код поместить информационное сообщение, то при попытке закрыть книгу нам будет появляться сообщение.

Private Sub Workbook_BeforeClose(Cancel As Boolean)

MsgBox «Прощай » & Application.UserName, vbInformation, «Прощание»

End Sub

Событие возникающее при сохранении книги

Макрос срабатывающий перед сохранением книги.
Workbook_BeforeSave

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

Делается это следующим образом. Заходим в окно VB, щёлкаем слева по книге «ЭтаКнига». Открывается окно. В левом верхнем окошке выбираем пункт Workbook и правом окошке BeforeSave.

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

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

End Sub

Если в этот код поместить информационное сообщение, то при сохранении книги нам будет появляться сообщение (не забываем, что при отключенных макросах такое сообщение нам не появится).

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

MsgBox «Вы сохраняете книгу», vbInformation, «Сохранение»

End Sub

Возможно даже сохранить книгу своим способом или отменить её сохранение.

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

Res = MsgBox(«Вы хотите сохранить эту книгу?», vbQuestion + vbYesNo, «Сохранение»)

If Res = vbNo Then Cancel = True

End Sub

Если пользователь в этом макросе откажется от сохранения, то книга не будет сохраняться, так как происходит отмена сохранения посредством переменной Cancel = True.

Макрос срабатывающий после сохранения книги.
Workbook_AfterSave

Теперь посмотрим на событие, которое возникает после сохранения книги. Заходим в окно VB, щёлкаем слева по книге «ЭтаКнига». Открывается окно. В левом верхнем окошке выбираем пункт Workbook и правом окошке AfterSave.

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

Private Sub Workbook_AfterSave(ByVal Success As Boolean)

End Sub

Если в этот код поместить информационное сообщение, то после сохранения книги нам будет появляться сообщение.

Private Sub Workbook_AfterSave(ByVal Success As Boolean)

MsgBox «Книга успешно сохранена», vbInformation, «Отчёт»

End Sub

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

Public Tm As Date, Res As Double

‘Макрос срабатывающий перед сохранением книги

Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)

Res = MsgBox(«Вы хотите сохранить эту книгу?», vbQuestion + vbYesNo, _

«Сохранение»)

Tm = Time

If Res = vbNo Then Cancel = True

End Sub

‘Макрос срабатывающий после сохранения книги

Private Sub Workbook_AfterSave(ByVal Success As Boolean)

Dim T As Integer

If Res = vbNo Then

Else

T = (Time — Tm) * 24 * 60 * 60 ‘Время в секундах

MsgBox «Книга успешно сохранена за » & T & » секунд!», vbInformation, _

«Отчёт»

End If

End Sub

Событие книги
Правая и левая кнопка мыши

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

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

Двойной щелчок левой кнопки мыши

Выбираем ЭтаКнига, в левом окошке выбираем Workbook, в правом окошке выбираемSheetBeforeDoubleClick, как показано на скриншоте ниже.

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

Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, _

ByVal Target As Range, Cancel As Boolean)

End Sub

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

Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, _

ByVal Target As Range, Cancel As Boolean)

MsgBox «Вы произвели двойное нажатие ЛКМ», vbInformation, «Пример»

End Sub

Для того чтобы не входить в режим редактирования добавляем в коде Cancel = True

Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, _

ByVal Target As Range, Cancel As Boolean)

Cancel = True

MsgBox «Вы произвели двойное нажатие ЛКМ», vbInformation, «Пример»

End Sub

Правая кнопка мыши

Теперь посмотрим на событие, которое возникает на всех листах книги, при нажатии на правую кнопку мыши. Заходим в окно VB, щёлкаем слева по книге «ЭтаКнига». Открывается окно. В левом верхнем окошке выбираем пункт Workbook и правом окошке SheetBeforeRightClick.

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

Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, _

ByVal Target As Range, Cancel As Boolean)

End Sub

Если в этот код поместить информационное сообщение, то при нажатии правой кнопки мыши на любом листе книги, нам будет появляться сообщение.

Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, _

ByVal Target As Range, Cancel As Boolean)

Cancel = True

MsgBox «Вы произвели нажатие ПКМ», vbInformation, «Пример»

End Sub

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

Private Sub Workbook_SheetBeforeRightClick(ByVal Sh As Object, _

ByVal Target As Range, Cancel As Boolean)

Cancel = True

ActiveCell.Rows.Delete

MsgBox «Строка удалена!», vbExclamation, «Пример»

End Sub

Как отличить текст от числа?
Целое или дробное? Чётное или нечётное?
Остаток от деления

Текст или число?

При написании программы с возможностью ручного ввода данных , очень часто возникает необходимость отличить какие именно данные введены — текст или число? Предположим вы пишите программу, которая запрашивает от пользователя ввести число от 0 до 50, но пользователь не знает цифр и вместо этого пишет в поле ввода данных — батон. И после таких данных наша программа выдаст окно VB с ошибкой, так как нам надо было число или цифру, а не текст. И для того, чтобы такого не происходило я покажу Вам как отличить что именно ввёл пользователь — число или текст. 
Делается это при помощи проверочной команды:

IsNumeric(a)

где a — это проверяемая переменная (текст, цифра, число).
Данная команда может принимать только два значение — False или True (если запись будет выглядеть так: b=IsNumeric(a)).

Напишем простенькую программку, которая будет определять введённые данные.

Sub Text()

Dim a As Variant ‘описываем переменную

a = InputBox(«Введите текст или число.», «Ввод данных»)

If a = «» Then Exit Sub ‘Если данных не введено, то выходим из процедуры

If IsNumeric(a) Then ‘проверяем число или текст

MsgBox «Вы ввели число!», vbInformation, «Число»

Else

MsgBox «Вы ввели текст или смешанные данные!», vbInformation, _

«Смешанные данные»

End If

End Sub

Как видно из программы — a присваивает значение введённых данных.
Далее в условии Если То проверяется число это или текст, и если введённые данные это число, то нам выскакивает сообщение о том, что Вы ввели число. В противном случае нам покажется сообщение о смешанных данных или что это текст.
If a = «» Then Exit Sub — если пользователь не ввёл никаких данных, то просто выходим из процедуры.

Как работают все представленные в уроке программы можно посмотреть на небольшом видеоролике.

Остаток числа (модуль)

Теперь научимся определять остаток числа при делении. Делается это при помощи оператора Mod, другими словами — модуль, но не путайте с математическим понятием модуля. Синтаксис записи его следующий:

c = a Mod b

А вот теперь надо понять что происходит при такой записи. Объясняю логику работы данного модуля:
Первым делом это значение a делится на значение b. Если деление произошло без остатка (например, 4:2 или 9:3), то в результате запишетсяc = 0. В противном случае, если при делении образуется остаток (например, 9:2 — остаток 1, 9:5 — остаток 4), то c будет равно остатку (при этом, если остаток не целый, то он округляется, например 15:6.3=2, остаток 2.4 — округляем в большую сторону получается 3.
Рассмотрим как это будет выглядеть програмно. Напишем простенькую программу, которая нам будет определять округлённый остаток.

Sub modul()

a = InputBox(«Введите первое число A в выражении C = A Mod B.», «Ввод данных»)

b = InputBox(«Введите второе число B в выражении C = A Mod B.», «Ввод данных»)

c = a Mod b

MsgBox a & » Mod » & b & «= » & c, vbInformation, «Модуль»

End Sub

Как отличить целое число от дробного?

Этот вопрос волновал многих людей, которые работаю с большими табличными данными. И очень часто возникал вопрос: Как отличить дробное число от целого?
Теперь Вы это узнаете. Делается это при помощи простого оператора Int или Fix.

Int(a)

Fix(a)

А вот чем они отличаются это мы сейчас и увидим на простом примере.

Sub IntFix()

a = InputBox(«Введите любое дробное число через запятую, например 68,8», _

«Ввод данных»)

b = Int(a)

c = Fix(a)

MsgBox «Int(a) = » & b & Chr(13) & _

«Fix(a) = » & c, vbInformation, «Целое»

End Sub

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

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

Число

Оператор

Результат

23,2

Int(a)

23

23,2

Fix(a)

23

23,8

Int(a)

23

23,8

Fix(a)

23

23,5

Int(a)

23

23,5

Fix(a)

23

-23,2

Int(a)

-24

-23,2

Fix(a)

-23

-23,8

Int(a)

-24

-23,8

Fix(a)

-23

-23,5

Int(a)

-24

-23,5

Fix(a)

-23

Исходя из заданных чисел и полученных результатов видно, что при положительных значениях чисел, операторы Int и Fix округляют число в меньшую сторону, тем самым получается, что просто отделяется целая часть от положительного числа.
А вот с отрицательными числами всё интересней. Оператор Int продолжает округлять число в меньшую сторону, т.е. число, например, -23,2 превращается в -24 (так как в меньшую сторону), т.е. мы уже не можем воспользоваться данным опертором для отделения целой части отрицательных чисел, так как будет выдаваться ложный результат.
А вот оператор Fix уже можно использовать в качестве отделения им целой части отрицательных чисел, так как он округляет в большую сторону (как видно из таблицы), и число -23,2 будет иметь значение -23, что нам и нужно.

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

Sub celoe()

a = InputBox(«Введите любое дробное число через запятую, например 68,8» & _

» или -56,4.», «Ввод данных»)

c = Fix(a)

MsgBox «Целая часть от числа » & a & » = » & c, vbInformation, «Целая часть»

End Sub

Чётное или нечётное?

Теперь зная всё выше рассказанное, мо можем составить полноценную программу, которая сможет определять чётное число или нечётное. Логика её работы будет такая:
— определяем введённые данные (текст или число);
— если это число, то определяем дробное оно или нет;
— если число не дробное, то делим его на 2, чтобы узнать есть ли остаток при делении;
— если образовался остаток при делении на 2, то относим число к нечётному, в противном случае число является чётным.

А теперь посмотрим на её код:

Sub Chetnoe()

a = Cells(3, 1) ‘берём данные из ячейки А3

If IsNumeric(a) Then

If Int(a) = a And a Mod 2 = 0 Then

MsgBox «Введёное вами число » & a & » — Чётное», vbInformation, «Чётное»

Else

MsgBox «Введёное вами число » & a & » — Нечётное», vbInformation, «Нечётное»

End If

Else

MsgBox «Введены некорректные данные!!!», vbCritical, «Ошибка ввода»

End If

End Sub

В примере можно посмотреть её работу.

Применение функций в Excel
Создание своих собственных функций

Функция (отображение, оператор, преобразование) — математическое понятие, отражающее связь между какими-либо значениями. Можно сказать, что функция — это «закон», по которому одна величина зависит от другой величины.

Это стандартное определение, которое все знают из википедии. И в принципе уже всё понятно. Однако, хочу заметить, что в Excel, функция может быть и не математической. А, например, логической, финансовой или текстовой.

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

или на ленте выбрать вкладку Формулы и сразу откроется весь список имеющихся функций

Создание собственной функции

Если же из указанного списка вы не нашли нужную функцию, то вам нажна UDF. UDF (User Defined Function) — это функция, которую Вы создаете сами при помощи VBA.
А теперь создадим свою собственную функцию, на основе VBA. Разберём на простом примере, в котором функция должна будет прибавлять НДС к некоторой сумме.

Заходим в окно VB (Alt+F11), нажимаем Insert и добавляем новый модуль Module.

Синтаксис записи функции в VB следующий

Function name [(arglist)] [As type]

[statements]

[name = expression]

[Exit Function]

[statements]

[name = expression]

End Function

Function — объявление функции
name — имя функции (подчиняются тем же правилам, что и имена в процедурах Sub);
[(arglist)] [As type] — аргументы функции и их тип (иногда их не указывают и они принимают значение variant);
[statements] — Любая группа инструкций для выполнения в рамках процедуры Function;
[name = expression] — присвоение функции значение, которое она должна возвращать;
[Exit Function] — В случае, если результат достигнут раньше, то можно выйти из функции, первоначально присвоив name нужное значение;
End Function — конец функции.

Теперь создадим небольшую табличку, в которой мы и будем применять нашу функцию.

В столбик Цена с НДС мы запишем нашу функцию, которую мы создадим.
Теперь в новом созданном модуле запишем следующий код:

Function Cena_S_NDS(Cena_bez_NDS As Long)

Cena_S_NDS = Cena_bez_NDS * 1.18

End Function

Из данной процедуры видно, что имя нашей функции Cena_S_NDS, которая присваивает значение цены без НДС и умножает на 1,18. Вот вообщем, то и вся формула. Теперь нам надо её применить в созданной таблице. Для этого ставим курсор в столбец Цена с НДС и нажимаем на строке формул на функцию.

После этого появится окно со всеми функциями, которые имеются в данном документе. Мы выбираем из выпадающего списка пункт «Определённые пользователем».

При этом появится функция, которую мы создали.

Выбираем созданную функцию и нажимаем ОК. Теперь нам появилось новое окно, в котором необходимо указать переменную, которую мы объявили. В данном случае — это Цена без НДС.

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

Цифры прописью

Теперь рассмотрим другой пример. Создадим функцию, которая будет определять цифры от 1 до 10 и записывать их прописью.

Для этого в модуле запишем следующий код:

Function Cifra(C As Variant)

Select Case C

Case 1

Cifra = «Один»

Case 2

Cifra = «Два»

Case 3

Cifra = «Три»

Case 4

Cifra = «Четыре»

Case 5

Cifra = «Пять»

Case 6

Cifra = «Шесть»

Case 7

Cifra = «Семь»

Case 8

Cifra = «Восемь»

Case 9

Cifra = «Девять»

Case 10

Cifra = «Десять»

Case Else

Cifra = «Введены некорректные данные»

End Select

End Function

В связи с тем, что пользователь может записать вместо цифры буквы, то описываем переменную Сзначением Variant. Теперь остаётся только в ячейку В2 записать нашу функцию и всё будет готово.

Scheduling Excel to Run a Procedure at periodic intervals or at a specific time of day, with the OnTime Method. Automatically run macros.

Excel Application.OnTime Method — Scheduling OnTime Events

Use the Application.OnTime Method to run a procedure at specified intervals or at a specific time of day. Syntax: ApplicationObject .OnTime(EarliestTime, ProcedureName, LatestTime, Schedule). Using this method you can schedule to run a procedure in the future. You can either fix specific intervals, starting from now, when the procedure will run, or you can fix a specific time of day. The (Excel) Application Object represents the entire Excel application, and is the top-most object in the Excel object model. The EarliestTime and ProcedureName arguments are required to be specified while the other arguments are optional. The EarliestTime argument specifies the time when the procedure is to be run. The ProcedureName argument specifies the name of the procedure you want to be executed. With the LatestTime argument you can set the time limit for running the procedure viz. if you set the LatestTime to «EarliestTime + 20» and if meanwhile another procedure is being executed and Excel is not in ready mode within 20 seconds, this procedure will not run. Omitting the LatestTime argument will make Excel wait and run the procedure. Omitting the Schedule argument will default to True, which sets a new Ontime procedure. To cancel an existing OnTime procedure set earlier, specify False.

To fix specific intervals starting from now, to run the procedure, use «Now + TimeValue(time)». To fix a specific time of day for the procedure to run, use «TimeValue(time)». See below examples on using these.

Stop or Cancel a Running Procedure (using the OnTime method)

If you attempt to close the workbook while a procedure is being run using Application.Ontime, Excel will re-open the workbook, and leave it open post completion of the procedure. Hence, you will need to cancel the procedure at a certain point or time.

To cancel a running procedure (using the OnTime method), the precise time of its scheduled run is required. Note that if you don’t pass the time to a variable, Excel will not know which OnTime method to cancel, as Now + TimeValue(«00:00:03») is not static, but becomes static when passed to a variable. This means that the time when the procedure is to run (EarliestTime argument) should be assigned to a variable (use a Public variable to make the variable available to all Procedures in all modules) and then use it to cancel the OnTime.


Example 1: This procedure uses the OnTime Method to auto increment cell value at specific time intervals, and Stops the procedure on crossing a specific cell value.

The procedure should be entered in a Standard Module (select Insert>Module, in VBE code window).

‘Dim as a Public variable and it will be available to all Procedures in all modules.
Public rTime As Date

_____________________________________

Sub CellValueAutoIncr1()
‘This procedure uses the OnTime Method to auto increment cell value at specific time intervals, and Stops the procedure on crossing a specific cell value.
‘The procedure should be entered in a Standard Module (select Insert>Module, in VBE code window).

‘To run a procedure at a specific time, use TimeValue(time) viz. TimeValue(«20:30:00») will run a procedure at 8.30 pm. To run a procedure at specified time intervals (say, from now), use Now + TimeValue(time) viz. Now + TimeValue(«00:00:05») sets the time interval at 5 seconds, at which interval the procedure will run.
‘set the time interval at 3 seconds, at which interval the procedure will run.
rTime = Now + TimeValue(«00:00:03»)
‘procedure named CellValueAutoIncr1 will autmatically run, at the sheduled time interval, with the OnTime Method.
Application.OnTime EarliestTime:=rTime, Procedure:=«CellValueAutoIncr1», schedule:=True
‘increment the value in cell A1 (in Active Worksheet) by 5, for each time the Macro is repeated:
Cells(1, 1).Value = Cells(1, 1).Value + 5

‘If you attempt to close the workbook while a procedure is being run using Application.Ontime, Excel will re-open the workbook, and leave it open post completion of the procedure. Hence, you will need to cancel the

procedure at a certain point or time.

‘stop the procedure at a specified point — the procedure will stop after cell A1 value crosses 25 for the first time.

If Cells(1, 1).Value > 25 Then

‘If you need to cancel an OnTime, you must provide the exact time that the event was schedule to take place.

‘Therefore, you need to store the time at which the procedure is to run in a Public variable and use that variable’s value in calls to OnTime.

‘To cancel a running procedure (using the OnTime method), the precise time of its scheduled run is required. Note that if you don’t pass the time to a variable, Excel will not know which OnTime method to cancel, as

Now + TimeValue(«00:00:03») is not static, but becomes static when passed to a variable. This means that the time when the procedure is to run (EarliestTime argument) should be assigned to a variable (Public

variable rTime in this example) and then use it to cancel the OnTime.

‘cancel the procedure by setting the Schedule argument to False:

Application.OnTime rTime, «CellValueAutoIncr1», , False

End If

End Sub


Example 2: This procedure uses the OnTime Method to auto increment cell value at specific time intervals, and Stops the procedure after it runs for a specific number of times.

The procedure should be entered in a Standard Module (select Insert>Module, in VBE code window).

Public eTime As Date
Dim count As Integer

__________________________

Sub CellValueAutoIncr2()
‘This procedure uses the OnTime Method to auto increment cell value at specific time intervals, and Stops the procedure after it runs for a specific number of times.

eTime = Now + TimeValue(«00:00:03»)
Application.OnTime eTime, «CellValueAutoIncr2», , True
Cells(1, 1).Value = Cells(1, 1).Value + 5
count = count + 1

‘stop the procedure after it runs for 5 times:

If count = 5 Then

Application.OnTime eTime, «CellValueAutoIncr2», , False

count = 0

End Sub


Example 3: Start the OnTime procedure automatically when the workbook is opened; stop the OnTime procedure automatically on closing the workbook. This Application.OnTime procedure sets reminders at specific times and auto-closes workbook at a specified time.

For live code, click to download excel file.

Add code (workbook procedures) to the Workbook module (ThisWorkbook):

Private Sub workbook_open()
‘to start the procedure automatically when the workbook is opened — add this code to the Workbook module (ThisWorkbook)

‘call SetReminder procedure:

End Sub

Private Sub Workbook_BeforeClose(Cancel As Boolean)
‘to stop the procedure automatically on closing the workbook, add this code to the Workbook module (ThisWorkbook)

On Error Resume Next
‘call StopSetReminder procedure to stop the Application.OnTime:
StopSetReminder
‘save workbook before closing:

End Sub

The procedures to be entered in a Standard Module:

Public dTime As Date

______________________

Sub SetReminder()
‘This Application.OnTime procedure sets reminders at specific times and auto-closes workbook at a specified time:

On Error Resume Next
dTime = Now + TimeValue(«00:00:01»)
‘procedure named SetReminder will autmatically run, at the sheduled time interval, with the OnTime Method.
Application.OnTime dTime, «SetReminder»

‘Close the workbook at the specified time:

If Time = TimeSerial(18, 30, 0) Then

CloseWorkBook

End If
‘set OfficeClose reminder:

If Time = TimeSerial(17, 30, 0) Then

Application.OnTime dTime, «OfficeClose»

End If
‘set LunchBreak reminder:

If Time = TimeSerial(13, 0, 0) Then

Application.OnTime dTime, «LunchBreak»

End If
‘set CoffeeBreak reminder:

If Time = TimeSerial(11, 15, 0) Then

Application.OnTime dTime, «CoffeeBreak»

End Sub

Dim obj As Object
Dim strMsg As String
Set obj = CreateObject(«WScript.Shell»)
‘play the Beep sound, you can customize the sound / message you wish to play:
Beep
‘the Popup Message Box will automatically close by itself, without user action of clicking Ok:

strMsg = obj.Popup(«Coffee Break Sir!», vbOKCancel)

End Sub

Dim obj As Object
Dim strMsg As String
Set obj = CreateObject(«WScript.Shell»)
Beep

strMsg = obj.Popup(«Lunch Break Sir!», vbOKCancel)

End Sub

Dim obj As Object
Dim strMsg As String
Set obj = CreateObject(«WScript.Shell»)
Beep

strMsg = obj.Popup(«Office Closing Sir!», vbOKCancel)

Sub StopSetReminder()
‘Stop the Application.OnTime procedure named SetReminder

Application.OnTime dTime, «SetReminder», , False

End Sub

Sub CloseWorkBook()
‘close the workbook

On Error Resume Next
‘call StopSetReminder procedure to stop the Application.OnTime:
StopSetReminder
‘save workbook before closing:
ThisWorkbook.Save
‘close workbook:

End Sub

Run a macro every 30 seconds, 1 minute, 10 minutes, 1 hour, etc.; this method allows you to run a macro at any set interval.

Sections:

The Code

Stop an Interval Macro

Notes

The Code

Sub macro_timer()

'Tells Excel when to next run the macro.
Application.OnTime Now + TimeValue("00:00:10"), "my_macro"

End Sub
Sub my_macro()

'Macro code that you want to run.
MsgBox "This is my sample macro output."

'Calls the timer macro so it can be run again at the next interval.
Call macro_timer

End Sub

This code requires two separate macros in order to run.

This specific setup gets the interval going. In order to be able to stop the interval when you want, look to the next section below.

Below, I’ll separate the macros and talk about each one.

Macro that sets the interval

Sub macro_timer()

'Tells Excel when to next run the macro.
Application.OnTime Now + TimeValue("00:00:10"), "my_macro"

End Sub

This is the timer macro. It is currently set to run another macro, called my_macro, 10 seconds after this timer macro is run.

my_macro is the name of the macro that you want to run each interval.

TimeValue(«00:00:10») is the part of the code that says how long to wait before running the macro; this is the interval. Currently, this is set to run the macro every 10 seconds. The first set of zeros is for hours, the second for minutes, and the third for seconds.

Interval time examples:

TimeValue(«05:00:00») run every 5 hours.

TimeValue(«00:10:00») run every 10 minutes.

TimeValue(«00:00:30») run every 30 seconds.

TimeValue(«01:30:00») run every 1.5 hours.

Macro that does something

Sub my_macro()

'Macro code that you want to run.
MsgBox "This is my sample macro output."

'Calls the timer macro so it can be run again at the next interval.
Call macro_timer

End Sub

This is the regular macro that has the code that you want executed at every interval.

You only need to make sure that, at the end of this macro, it calls the original timer macro.

Call macro_timer is the line that must be at the end of your macro. macro_timer is simply the name of the first macro in this example and Call is what tells the macro to «call» or run the other macro.

Stop an Interval Macro

The easiest way to stop a macro that runs on an interval is to hit Ctrl + Break on the keyboard.

Here is our tutorial on stopping a macro from running.

You can also use this setup:

96c95df267b24db656932d6dd4e1e0fe.jpg

Full code:

Public interval As Double
Sub macro_timer()

interval = Now + TimeValue("00:00:10")

'Tells Excel when to next run the macro.
Application.OnTime interval, "my_macro"

End Sub
Sub my_macro()

'Macro code that you want to run.
MsgBox "This is my sample macro output."

'Calls the timer macro so it can be run again at the next interval.
Call macro_timer

End Sub
Sub stop_macro()

Application.OnTime earliesttime:=interval, procedure:="my_macro", schedule:=False

End Sub

To stop the macro using this setup, just run the stop_macro.

This setup is almost exactly the same as the first setup above except that you need one line of code above everything else, need to set the interval as a variable, and need a macro to stop the interval.

One extra line at the top

Public interval As Double this makes the variable «interval» a variable that can be accessed across different macros.

Interval variable

interval = Now + TimeValue(«00:00:10») the time value is stored in the interval variable instead of hard-coding it into the Application.OnTime method. This new variable is then used within the Application.OnTime method for the first parameter.

Stop macro

Sub stop_macro()

Application.OnTime Earliesttime:=interval, Procedure:="my_macro", Schedule:=False

End Sub

This macro simply contains another Application.OnTime method and it must have the same parameters as the initial Application.OnTime method, except here, the Schedule parameter must be included and set to false.

In this macro, the parameters are explicitly named, which is why you see Earliesttime:= and Procedure:= and Schedule:= written out, whereas you don’t see that in the initial macro setup in the first section above.

Notes

The macros in the attached workbook are from the last example since that is the most versatile method to use.

Download the sample file to get these examples in Excel.

Similar Content on TeachExcel

Automatically Run a Macro at a Certain Time — i.e. Run a Macro at 4:30PM every day

Macro: Automatically run an Excel macro at a certain time. This allows you to not have to worry a…

Run Macros at Set Intervals in Excel

Tutorial: [files in side column or below here]…

Stop Excel Events from Triggering when Running a Macro

Tutorial: Create a macro that will run without triggering events, such as the Change event, or Activ…

Disable Calculation of Cells when Running a Macro in Excel

Tutorial: How to stop formulas and functions from updating in Excel when running a macro. This can s…

Run a Macro when a User Does Something in the Workbook in Excel

Tutorial:
How to run a macro when a user does something within the Workbook in Excel, such as openi…

Subscribe for Weekly Tutorials

BONUS: subscribe now to download our Top Tutorials Ebook!

Понравилась статья? Поделить с друзьями:
  • Vba excel массивы диапазоны
  • Vba excel макрос на изменение ячейки excel
  • Vba excel массивы ubound
  • Vba excel массивы range
  • Vba excel макрос изменения макроса