Добавить в корзинуПозвонить
Найти в Дзене
Макрос решает

Макрос работает с датами в Excel — считает дни, выделяет просроченное и заполняет автоматически

Как написать VBA-макрос для работы с датами в Excel — подсчёт дней между датами, поиск просроченных строк, автозаполнение дат и форматирование — разбор кода с примерами. Даты в Excel — постоянный источник проблем. То формат не тот и вместо даты показывается число. То нужно посчитать сколько рабочих дней осталось до дедлайна — и непонятно какую формулу использовать. То таблица с платежами и нужно автоматически выделить всё что просрочено и напомнить что нужно оплатить на этой неделе. Формулы Excel частично решают эти задачи, но у них есть ограничения. Формула статична — она посчитала и всё. Макрос умеет делать больше: проверить условие, принять решение, изменить форматирование, вставить значение, отправить сообщение. И всё это за один запуск. В этой статье напишем несколько практичных макросов для работы с датами: подсчёт дней между датами, поиск и подсветка просроченных строк, автоматическое заполнение дат, расчёт рабочих дней. Каждый макрос решает конкретную задачу которая встречаетс
Оглавление

Как написать VBA-макрос для работы с датами в Excel — подсчёт дней между датами, поиск просроченных строк, автозаполнение дат и форматирование — разбор кода с примерами.

Макрос работает с датами в Excel — считает дни, выделяет просроченное и заполняет автоматически

Даты в Excel — постоянный источник проблем. То формат не тот и вместо даты показывается число. То нужно посчитать сколько рабочих дней осталось до дедлайна — и непонятно какую формулу использовать. То таблица с платежами и нужно автоматически выделить всё что просрочено и напомнить что нужно оплатить на этой неделе.

Формулы Excel частично решают эти задачи, но у них есть ограничения. Формула статична — она посчитала и всё. Макрос умеет делать больше: проверить условие, принять решение, изменить форматирование, вставить значение, отправить сообщение. И всё это за один запуск.

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

Как Excel хранит даты — важно понять один раз

Прежде чем писать код — нужно понять как Excel работает с датами внутри. Это объясняет почему некоторые операции с датами выглядят неожиданно.

Excel хранит даты как обычные числа. 1 января 1900 года — это число 1. Каждый следующий день — плюс один. Сегодняшняя дата — это число порядка 45000+. Формат «Дата» — это просто способ отображения числа в виде дд.мм.гггг.

Это означает несколько важных вещей. Разность двух дат — это разность двух чисел, результат — количество дней. Дата плюс число — это дата смещённая на столько дней. Сравнение дат — это сравнение чисел, всё работает через обычные операторы больше/меньше.

В VBA даты работают через тип данных Date. Переменная типа Date хранит дату и время. Функция Date возвращает сегодняшнюю дату. Функция Now возвращает текущую дату и время. Функция CDate преобразует текст или число в дату.

Это базовые знания без которых код с датами будет работать непредсказуемо. Разберём каждый сценарий на конкретных примерах.

Макрос 1 — подсчёт дней между датами

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

Sub СчитатьДниМеждуДатами()
Dim ws As Worksheet*
Dim lastRow As Long*
Dim i As Long*
Dim датаНачала As Date*
Dim датаКонца As Date*
Dim разница As Long*
Set ws = ActiveSheet*
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row*
' Заголовок третьего столбца*
ws.Cells(1, 3).Value = "Дней между датами"*
For i = 2 To lastRow*
' Проверяем что в ячейках действительно даты*
If IsDate(ws.Cells(i, 1).Value) And IsDate(ws.Cells(i, 2).Value) Then*
датаНачала = CDate(ws.Cells(i, 1).Value)*
датаКонца = CDate(ws.Cells(i, 2).Value)*
разница = DateDiff("d", датаНачала, датаКонца)*
ws.Cells(i, 3).Value = разница*
Else*
ws.Cells(i, 3).Value = "Ошибка — нет даты"*
End If*
Next i*
MsgBox "Готово. Количество дней рассчитано.", vbInformation*
End Sub

Макрос берёт дату из столбца A, дату из столбца B и вычисляет разницу в днях. Функция DateDiff — ключевой инструмент. Первый аргумент «d» означает дни. Можно заменить на «m» для месяцев, «yyyy» для лет, «ww» для недель, «h» для часов.

IsDate проверяет что значение в ячейке является датой — защита от ошибок если ячейка пустая или содержит текст. CDate преобразует значение ячейки в тип Date — это важно чтобы операции с датами работали правильно.

Макрос 2 — подсветка просроченных строк

Это один из самых востребованных сценариев. Таблица с дедлайнами — нужно автоматически выделить все строки где срок уже прошёл.

Sub ПодсветитьПросроченные()
Dim ws As Worksheet*
Dim lastRow As Long*
Dim i As Long*
Dim дедлайн As Date*
Dim сегодня As Date*
Dim просрочено As Long*
Dim скороИстекает As Long*
Set ws = ActiveSheet*
сегодня = Date ' Текущая дата*
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row*
' Снимаем предыдущую подсветку*
ws.Cells.Interior.ColorIndex = xlNone*
просрочено = 0*
скороИстекает = 0*
For i = 2 To lastRow*
If IsDate(ws.Cells(i, 4).Value) Then ' Столбец D — дата дедлайна*
дедлайн = CDate(ws.Cells(i, 4).Value)*
If дедлайн < сегодня Then*
' Просрочено — красный*
ws.Rows(i).Interior.Color = RGB(255, 205, 210)*
просрочено = просрочено + 1*
ElseIf дедлайн <= сегодня + 7 Then*
' Истекает в течение недели — жёлтый*
ws.Rows(i).Interior.Color = RGB(255, 249, 196)*
скороИстекает = скороИстекает + 1*
End If*
End If*
Next i*
MsgBox "Просрочено: " & просрочено & " строк." & vbNewLine & _*
"Истекает на этой неделе: " & скороИстекает & " строк.", vbInformation*
End Sub

Три зоны: прошедшая дата — красная подсветка, срок в ближайшие 7 дней — жёлтая, всё остальное — без подсветки. Макрос также считает количество строк в каждой зоне и показывает итог.

сегодня + 7 — это дата через неделю. Сложение числа с датой в VBA работает именно так: прибавляете количество дней. Для недели — 7, для месяца — 30, для двух недель — 14.

Число столбца 4 в строке ws.Cells(i, 4) — это столбец D. Измените на нужный номер в зависимости от структуры вашей таблицы.

Макрос 3 — автоматическое заполнение дат

Часто нужно создать список дат — например все рабочие дни месяца, или даты через каждые две недели, или последовательность дат начиная с сегодня. Делать это вручную долго. Макрос справляется за секунду.

Sub ЗаполнитьДатыРабочиеДни()
Dim ws As Worksheet*
Dim текущаяДата As Date*
Dim количество As Long*
Dim i As Long*
Dim строка As Long*
Set ws = ActiveSheet*
' Запрашиваем количество рабочих дней*
количество = CLng(InputBox("Сколько рабочих дней заполнить?", "Заполнение дат", "20"))*
If количество <= 0 Then Exit Sub*
текущаяДата = Date ' Начинаем с сегодня*
строка = 2*
i = 0*
' Добавляем заголовок*
ws.Cells(1, 1).Value = "Рабочие дни"*
ws.Cells(1, 1).Font.Bold = True*
Do While i < количество*
' Проверяем что день не выходной*
If Weekday(текущаяДата, vbMonday) <= 5 Then*
' Понедельник-пятница — рабочий день*
ws.Cells(строка, 1).Value = текущаяДата*
ws.Cells(строка, 1).NumberFormat = "DD.MM.YYYY"*
строка = строка + 1*
i = i + 1*
End If*
текущаяДата = текущаяДата + 1*
Loop*
MsgBox "Заполнено " & количество & " рабочих дней.", vbInformation*
End Sub

Функция Weekday возвращает номер дня недели. С параметром vbMonday понедельник = 1, вторник = 2, ..., воскресенье = 7. Условие <= 5 означает понедельник-пятница — рабочие дни. Суббота и воскресенье пропускаются.

NumberFormat = "DD.MM.YYYY" — устанавливает формат отображения даты. Можно изменить на "DD MMMM YYYY" для отображения месяца словом, или "YYYY-MM-DD" для международного формата.

Макрос 4 — расчёт рабочих дней между датами

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

Function РабочихДней(датаНач As Date, датаКон As Date) As Long
Dim текущаяДата As Date*
Dim счётчик As Long*
счётчик = 0*
текущаяДата = датаНач*
Do While текущаяДата <= датаКон*
If Weekday(текущаяДата, vbMonday) <= 5 Then*
счётчик = счётчик + 1*
End If*
текущаяДата = текущаяДата + 1*
Loop*
РабочихДней = счётчик*
End Function
Sub РасчётРабочихДней()
Dim ws As Worksheet*
Dim lastRow As Long*
Dim i As Long*
Set ws = ActiveSheet*
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row*
ws.Cells(1, 3).Value = "Рабочих дней"*
For i = 2 To lastRow*
If IsDate(ws.Cells(i, 1).Value) And IsDate(ws.Cells(i, 2).Value) Then*
ws.Cells(i, 3).Value = РабочихДней(_*
CDate(ws.Cells(i, 1).Value), _*
CDate(ws.Cells(i, 2).Value))*
End If*
Next i*
MsgBox "Готово. Рабочие дни рассчитаны.", vbInformation*
End Sub

Здесь два блока кода. Первый — функция РабочихДней которая принимает две даты и возвращает количество рабочих дней между ними. Второй — основной макрос который применяет эту функцию к каждой строке таблицы.

Функции в VBA — это многократно используемые блоки кода. Написали один раз — вызываете из любого места. В данном случае функцию РабочихДней можно также использовать прямо в формулах Excel как пользовательскую функцию. Введите в ячейку =РабочихДней(A2;B2) — и получите результат без запуска макроса.

Макрос 5 — напоминание о предстоящих событиях

Практичный макрос для таблиц с важными датами — договоры с датой окончания, дни рождения клиентов, плановые проверки. При открытии файла макрос проверяет ближайшие события и показывает напоминание.

Sub НапоминаниеОСобытиях()
Dim ws As Worksheet*
Dim lastRow As Long*
Dim i As Long*
Dim дата As Date*
Dim сегодня As Date*
Dim сообщение As String*
Dim дней As Long*
Set ws = ActiveSheet*
сегодня = Date*
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row*
сообщение = "Ближайшие события:" & vbNewLine & vbNewLine*
Dim найдено As Boolean*
найдено = False*
For i = 2 To lastRow*
If IsDate(ws.Cells(i, 2).Value) Then*
дата = CDate(ws.Cells(i, 2).Value)*
дней = DateDiff("d", сегодня, дата)*
' Показываем события в диапазоне от -3 до +14 дней*
If дней >= -3 And дней <= 14 Then*
If дней < 0 Then*
сообщение = сообщение & ws.Cells(i, 1).Value & _*
" — просрочено " & Abs(дней) & " дн. назад" & vbNewLine*
ElseIf дней = 0 Then*
сообщение = сообщение & ws.Cells(i, 1).Value & _*
" — СЕГОДНЯ!" & vbNewLine*
Else*
сообщение = сообщение & ws.Cells(i, 1).Value & _*
" — через " & дней & " дн. (" & _*
Format(дата, "DD.MM.YYYY") & ")" & vbNewLine*
End If*
найдено = True*
End If*
End If*
Next i*
If найдено Then*
MsgBox сообщение, vbExclamation, "Напоминание"*
End If*
End Sub

Макрос показывает события в диапазоне от трёх дней назад до двух недель вперёд. «-3 дня» — мягкое напоминание о только что просроченном. «0 дней» — событие сегодня. Положительные числа — сколько дней до события.

Чтобы макрос запускался автоматически при открытии файла — вставьте его вызов в специальную процедуру Workbook_Open. В редакторе VBA откройте «Эта книга» и добавьте:

Private Sub Workbook_Open()

  • НапоминаниеОСобытиях*
    End Sub

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

Часто используемые функции VBA для работы с датами

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

Date — возвращает сегодняшнюю дату без времени.

Now — возвращает текущую дату и время. Используйте когда нужна точность до минут.

DateDiff(интервал, дата1, дата2) — разница между датами. Интервалы: «d» — дни, «m» — месяцы, «yyyy» — годы, «ww» — недели, «h» — часы, «n» — минуты.

DateAdd(интервал, число, дата) — прибавить к дате. DateAdd("m", 3, Date) — дата через три месяца.

DatePart(интервал, дата) — извлечь часть даты. DatePart("m", Date) — номер текущего месяца. DatePart("yyyy", Date) — текущий год.

Day(дата), Month(дата), Year(дата) — короткие функции для извлечения дня, месяца, года.

Weekday(дата, первыйДень) — день недели числом. С vbMonday понедельник = 1.

Format(дата, формат) — преобразовать дату в строку с заданным форматом. Format(Date, "DD MMMM YYYY") — «01 июня 2026».

CDate(значение) — преобразовать текст или число в дату.

IsDate(значение) — проверить является ли значение датой.

Связанные материалы

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

Если хотите разобраться с формулами подстановки для работы с датами — читайте ПОИСКПОЗ в Excel и ИНДЕКС + ПОИСКПОЗ. А какие формулы чаще всего ломают таблицы с датами — в статье 3 формулы Excel которые ломают таблицы.

Подписывайтесь на Telegram — там каждый день практичные разборы Excel и VBA с готовыми файлами: t.me/macroschannel

Частые ошибки при работе с датами в VBA

Дата отображается как число. Ячейке не установлен формат даты. Добавьте строку: ws.Cells(i, col).NumberFormat = "DD.MM.YYYY"

Ошибка при сравнении дат. Значение в ячейке — текст а не дата. Добавьте проверку IsDate и преобразование CDate как в примерах выше.

DateDiff возвращает отрицательное число. Первая дата позже второй. Если нужно абсолютное значение — используйте функцию Abs: Abs(DateDiff("d", дата1, дата2)).

Формат даты зависит от региональных настроек. На компьютере с английскими настройками дата 01.06.2026 может не распознаться как дата. Используйте DateSerial(год, месяц, день) для создания дат без зависимости от региональных настроек: DateSerial(2026, 6, 1).

Макрос работает медленно на большой таблице с датами. Добавьте отключение обновления экрана в начало: Application.ScreenUpdating = False. Верните обратно в конце: Application.ScreenUpdating = True.

Итог

Пять макросов в статье закрывают самые распространённые задачи с датами в Excel. Подсчёт дней и рабочих дней, подсветка просроченных строк с градацией по срочности, автозаполнение рабочих дней, напоминания при открытии файла — всё это решается кодом в 20–40 строк.

Ключевые функции которые нужно помнить: Date для сегодняшней даты, DateDiff для разницы, DateAdd для прибавления, Weekday для определения дня недели, IsDate для проверки. С этим набором решается 90% задач с датами.

Главное правило при работе с датами в коде — всегда проверять IsDate перед операциями с датой и использовать CDate для преобразования. Без этого один неправильный формат в ячейке остановит весь макрос.