title | keywords | f1_keywords | ms.prod | api_name | ms.assetid | ms.date | ms.localizationpriority |
---|---|---|---|---|---|---|---|
WorksheetFunction.WorkDay method (Excel) |
vbaxl10.chm137347 |
vbaxl10.chm137347 |
excel |
Excel.WorksheetFunction.WorkDay |
358c358f-c76e-1309-4a2f-8e50f8d7e7d9 |
05/25/2019 |
medium |
WorksheetFunction.WorkDay method (Excel)
Returns a number that represents a date that is the indicated number of working days before or after a date (the starting date). Working days exclude weekends and any dates identified as holidays. Use WorkDay to exclude weekends or holidays when you calculate invoice due dates, expected delivery times, or the number of days of work performed.
Syntax
expression.WorkDay (Arg1, Arg2, Arg3)
expression A variable that represents a WorksheetFunction object.
Parameters
Name | Required/Optional | Data type | Description |
---|---|---|---|
Arg1 | Required | Variant | Start_date — a date that represents the start date. |
Arg2 | Required | Variant | Days — the number of nonweekend and nonholiday days before or after start_date. A positive value for days yields a future date; a negative value yields a past date. |
Arg3 | Optional | Variant | Holidays — an optional list of one or more dates to exclude from the working calendar, such as state and federal holidays and floating holidays. The list can be either a range of cells that contain the dates or an array constant of the serial numbers that represent the dates. |
Return value
Double
Remarks
[!IMPORTANT]
Dates should be entered by using the DATE function, or as results of other formulas or functions. For example, use DATE(2008,5,23) for the 23rd day of May, 2008. Problems can occur if dates are entered as text .
Microsoft Excel stores dates as sequential serial numbers so they can be used in calculations. By default, January 1, 1900 is serial number 1, and January 1, 2008 is serial number 39448 because it is 39,448 days after January 1, 1900. Microsoft Excel for the Macintosh uses a different date system as its default.
[!NOTE]
Visual Basic for Applications (VBA) calculates serial dates differently than Excel. In VBA, serial number 1 is December 31, 1899, rather than January 1, 1900.
If any argument is not a valid date, WorkDay returns the #VALUE! error value.
If start_date plus days yields an invalid date, WorkDay returns the #NUM! error value.
If days is not an integer, it is truncated.
[!includeSupport and feedback]
Определяем день ( рабочий или выходной) |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
||||||||
Ответить |
Функции для работы с датой и временем в VBA Excel. Синтаксис, параметры, спецсимволы, примеры. Функции, возвращающие текущие дату и время по системному таймеру.
Функция Date
Date – это функция, которая возвращает значение текущей системной даты. Тип возвращаемого значения – Variant/Date.
Синтаксис
Пример
Sub PrimerDate() MsgBox «Сегодня: « & Date End Sub |
Функция DateAdd
DateAdd – это функция, которая возвращает результат прибавления к дате указанного интервала времени. Тип возвращаемого значения – Variant/Date.
Синтаксис
DateAdd(interval, number, date) |
Параметры
Параметр | Описание |
---|---|
interval | Обязательный параметр. Строковое выражение из спецсимволов, представляющее интервал времени, который требуется добавить. |
number | Обязательный параметр. Числовое выражение, задающее количество интервалов, которые необходимо добавить. Может быть как положительным (возвращается будущая дата), так и отрицательным (возвращается предыдущая дата). |
date | Обязательный параметр. Значение типа Variant/Date или литерал, представляющий дату, к которой должен быть добавлен интервал. |
Таблицу аргументов (значений) параметра interval
смотрите в параграфе «Приложение 1».
Примечание к таблице аргументов: три символа – y, d, w – указывают функции DateAdd
на один день, который необходимо прибавить к исходной дате number
раз.
Пример
Sub PrimerDateAdd() MsgBox «31.01.2021 + 1 месяц = « & DateAdd(«m», 1, «31.01.2021») ‘Результат: 28.02.2021 MsgBox «Сегодня + 3 года = « & DateAdd(«yyyy», 3, Date) MsgBox «Сегодня — 2 недели = « & DateAdd(«ww», —2, Date) MsgBox «10:22:14 + 10 минут = « & DateAdd(«n», 10, «10:22:14») ‘Результат: 10:32:14 End Sub |
Функция DateDiff
DateDiff – это функция, которая возвращает количество указанных интервалов времени между двумя датами. Тип возвращаемого значения – Variant/Long.
Синтаксис
DateDiff(interval, date1, date2, [firstdayofweek], [firstweekofyear]) |
Параметры
Параметр | Описание |
---|---|
interval | Обязательный параметр. Строковое выражение из спецсимволов, представляющее интервал времени, количество которых (интервалов) требуется вычислить между двумя датами. |
date1, date2 | Обязательные параметры. Значения типа Variant/Date , представляющие две даты, между которыми вычисляется количество указанных интервалов. |
firstdayofweek | Необязательный параметр. Константа, задающая первый день недели. По умолчанию – воскресенье. |
firstweekofyear | Необязательный параметр. Константа, задающая первую неделю года. По умолчанию – неделя, в которую входит 1 января. |
Таблицу аргументов (значений) параметра interval
смотрите в параграфе «Приложение 1».
Примечание к таблице аргументов: в отличие от функции DateAdd
, в функции DateDiff
спецсимвол "w"
, как и "ww"
, обозначает неделю. Но расчет осуществляется по разному. Подробнее об этом на сайте разработчиков.
Параметры firstdayofweek
и firstweekofyear
определяют правила расчета количества недель между датами.
Таблицы констант из коллекций firstdayofweek
и firstweekofyear
смотрите в параграфах «Приложение 2» и «Приложение 3».
Пример
Sub PrimerDateDiff() ‘Даже если между датами соседних лет разница 1 день, ‘DateDiff с интервалом «y» покажет разницу — 1 год MsgBox DateDiff(«y», «31.12.2020», «01.01.2021») ‘Результат: 1 год MsgBox DateDiff(«d», «31.12.2020», «01.01.2021») ‘Результат: 1 день MsgBox DateDiff(«n», «31.12.2020», «01.01.2021») ‘Результат: 1440 минут MsgBox «Полных лет с начала века = « & DateDiff(«y», «2000», Year(Now) — 1) End Sub |
Функция DatePart
DatePart – это функция, которая возвращает указанную часть заданной даты. Тип возвращаемого значения – Variant/Integer.
Есть предупреждение по использованию этой функции.
Синтаксис
DatePart(interval, date, [firstdayofweek], [firstweekofyear]) |
Параметры
Параметр | Описание |
---|---|
interval | Обязательный параметр. Строковое выражение из спецсимволов, представляющее часть даты, которую требуется извлечь. |
date | Обязательные параметры. Значение типа Variant/Date , представляющее дату, часть которой следует извлечь. |
firstdayofweek | Необязательный параметр. Константа, задающая первый день недели. По умолчанию – воскресенье. |
firstweekofyear | Необязательный параметр. Константа, задающая первую неделю года. По умолчанию – неделя, в которую входит 1 января. |
Таблицу аргументов (значений) параметра interval
смотрите в параграфе «Приложение 1». В третьей графе этой таблицы указаны интервалы значений, возвращаемых функцией DatePart
.
Таблицы констант из коллекций firstdayofweek
и firstweekofyear
смотрите в параграфах «Приложение 2» и «Приложение 3».
Пример
Sub PrimerDatePart() MsgBox DatePart(«y», «31.12.2020») ‘Результат: 366 MsgBox DatePart(«yyyy», CDate(43685)) ‘Результат: 2019 MsgBox DatePart(«n», CDate(43685.45345)) ‘Результат: 52 MsgBox «День недели по счету сегодня = « & DatePart(«w», Now, vbMonday) End Sub |
Функция DateSerial
DateSerial – это функция, которая возвращает значение даты для указанного года, месяца и дня. Тип возвращаемого значения – Variant/Date.
Синтаксис
DateSerial(year, month, day) |
Параметры
Параметр | Описание |
---|---|
year | Обязательный параметр типа Integer. Числовое выражение, возвращающее значение от 100 до 9999 включительно. |
month | Обязательный параметр типа Integer. Числовое выражение, возвращающее любое значение (в пределах Integer), а не только от 1 до 12.* |
day | Обязательный параметр типа Integer. Числовое выражение, возвращающее любое значение (в пределах Integer), а не только от 1 до 31.* |
* Функция DateSerial автоматически пересчитывает общее количество дней в полные месяцы и остаток, общее количество месяцев в полные годы и остаток (подробнее в примере).
Пример
Sub PrimerDateSerial() MsgBox DateSerial(2021, 2, 10) ‘Результат: 10.02.2020 MsgBox DateSerial(2020, 1, 400) ‘Результат: 03.02.2021 End Sub |
Разберем подробнее строку DateSerial(2020, 1, 400)
:
- 400 дней = 366 дней + 31 день + 3 дня;
- 366 дней = 1 год, так как по условию month:=1, значит февраль 2020 входит в расчет, а в нем – 29 дней;
- 31 день = 1 месяц, так как сначала заполняется январь (по условию month:=1);
- 3 дня – остаток.
В итоге получается:
DateSerial(2020+1, 1+1, 3) = DateSerial(2021, 2, 3)
Функция DateValue
DateValue – это функция, которая преобразует дату, указанную в виде строки, в значение типа Variant/Date (время игнорируется).
Синтаксис
Параметр date
– строковое выражение, представляющее дату с 1 января 100 года по 31 декабря 9999 года.
Пример
Sub PrimerDateValue() MsgBox DateValue(«8 марта 2021») ‘Результат: 08.03.2021 MsgBox DateValue(«17 мая 2021 0:59:15») ‘Результат: 17.05.2021 End Sub |
Функция DateValue игнорирует время, указанное в преобразуемой строке, но если время указано в некорректном виде (например, «10:60:60»), будет сгенерирована ошибка.
Функция Day
Day – это функция, которая возвращает день месяца в виде числа от 1 до 31 включительно. Тип возвращаемого значения – Variant/Integer.
Синтаксис
Параметр date
– любое числовое или строковое выражение, представляющее дату.
Пример
Sub PrimerDay() MsgBox Day(Now) End Sub |
Функция IsDate
IsDate – это функция, которая возвращает True, если выражение является датой или распознается как допустимое значение даты или времени. В остальных случаях возвращается значение False.
Синтаксис
Параметр expression
– это переменная, возвращающая дату или строковое выражение, распознаваемое как дата или время.
Значение, возвращаемое переменной expression, не должно выходить из диапазона допустимых дат: от 1 января 100 года до 31 декабря 9999 года (для Windows).
Пример
Sub PrimerIsDate() MsgBox IsDate(«18 апреля 2021») ‘Результат: True MsgBox IsDate(«31 февраля 2021») ‘Результат: False MsgBox IsDate(«4.10.20 11:12:54») ‘Результат: True End Sub |
Функция Hour
Hour – это функция, которая возвращает количество часов в виде числа от 0 до 23 включительно. Тип возвращаемого значения – Variant/Integer.
Синтаксис
Параметр time
– любое числовое или строковое выражение, представляющее время.
Пример
Sub PrimerHour() MsgBox Hour(Now) MsgBox Hour(«22:36:54») End Sub |
Функция Minute
Minute – это функция, которая возвращает количество минут в виде числа от 0 до 59 включительно. Тип возвращаемого значения – Variant/Integer.
Синтаксис
Параметр time
– любое числовое или строковое выражение, представляющее время.
Пример
Sub PrimerMinute() MsgBox Minute(Now) MsgBox Minute(«22:36:54») End Sub |
Функция Month
Month – это функция, которая возвращает день месяца в виде числа от 1 до 12 включительно. Тип возвращаемого значения – Variant/Integer.
Синтаксис
Параметр date
– любое числовое или строковое выражение, представляющее дату.
Пример
Sub PrimerMonth() MsgBox Month(Now) End Sub |
Функция MonthName
MonthName – это функция, которая возвращает название месяца в виде строки.
Синтаксис
MonthName(month, [abbreviate]) |
Параметры
Параметр | Описание |
---|---|
month | Обязательный параметр. Числовое обозначение месяца от 1 до 12 включительно. |
abbreviate | Необязательный параметр. Логическое значение: True – возвращается сокращенное название месяца, False (по умолчанию) – название месяца не сокращается. |
Пример
Sub PrimerMonthName() MsgBox MonthName(10) ‘Результат: Октябрь MsgBox MonthName(10, True) ‘Результат: окт End Sub |
Функция Now
Now – это функция, которая возвращает текущую системную дату и время. Тип возвращаемого значения – Variant/Date.
Синтаксис
Пример
Sub PrimerNow() MsgBox Now MsgBox Day(Now) MsgBox Hour(Now) End Sub |
Функция Second
Second – это функция, которая возвращает количество секунд в виде числа от 0 до 59 включительно. Тип возвращаемого значения – Variant/Integer.
Синтаксис
Параметр time
– любое числовое или строковое выражение, представляющее время.
Пример
Sub PrimerSecond() MsgBox Second(Now) MsgBox Second(«22:30:14») End Sub |
Функция Time
Time – это функция, которая возвращает значение текущего системного времени. Тип возвращаемого значения – Variant/Date.
Синтаксис
Пример
Sub PrimerTime() MsgBox «Текущее время: « & Time End Sub |
Функция TimeSerial
TimeSerial – это функция, которая возвращает значение времени для указанного часа, минуты и секунды. Тип возвращаемого значения – Variant/Date.
Синтаксис
TimeSerial(hour, minute, second) |
Параметры
Параметр | Описание |
---|---|
hour | Обязательный параметр типа Integer. Числовое выражение, возвращающее значение от 0 до 23 включительно. |
minute | Обязательный параметр типа Integer. Числовое выражение, возвращающее любое значение (в пределах Integer), а не только от 0 до 59.* |
second | Обязательный параметр типа Integer. Числовое выражение, возвращающее любое значение (в пределах Integer), а не только от 0 до 59.* |
* Функция TimeSerial автоматически пересчитывает общее количество секунд в полные минуты и остаток, общее количество минут в полные часы и остаток (подробнее в примере).
Пример
Sub PrimerTime() MsgBox TimeSerial(5, 16, 4) ‘Результат: 5:16:04 MsgBox TimeSerial(5, 75, 158) ‘Результат: 6:17:38 End Sub |
Разберем подробнее строку TimeSerial(5, 75, 158)
:
- 158 секунд = 120 секунд (2 минуты) + 38 секунд;
- 75 минут = 60 минут (1 час) + 15 минут.
В итоге получается:
TimeSerial(5+1, 15+2, 38) = TimeSerial(6, 17, 38)
Функция TimeValue
TimeValue – это функция, которая преобразует время, указанное в виде строки, в значение типа Variant/Date (дата игнорируется).
Синтаксис
Параметр time
– строковое выражение, представляющее время с 0:00:00 по 23:59:59 включительно.
Пример
Sub PrimerTimeValue() MsgBox TimeValue(«6:45:37 PM») ‘Результат: 18:45:37 MsgBox TimeValue(«17 мая 2021 3:59:15 AM») ‘Результат: 3:59:15 End Sub |
Функция TimeValue игнорирует дату, указанную в преобразуемой строке, но если дата указана в некорректном виде (например, «30.02.2021»), будет сгенерирована ошибка.
Функция Weekday
Weekday – это функция, которая возвращает день недели в виде числа от 1 до 7 включительно. Тип возвращаемого значения – Variant/Integer.
Синтаксис
Weekday(date, [firstdayofweek]) |
Параметры
Параметр | Описание |
---|---|
date | Обязательный параметр. Любое выражение (числовое, строковое), отображающее дату. |
firstdayofweek | Константа, задающая первый день недели. По умолчанию – воскресенье. |
Таблицу констант из коллекции firstdayofweek
смотрите в параграфе «Приложение 2».
Пример
Sub PrimerWeekday() MsgBox Weekday(«23 апреля 2021», vbMonday) ‘Результат: 5 MsgBox Weekday(202125, vbMonday) ‘Результат: 6 End Sub |
Функция WeekdayName
WeekdayName – это функция, которая возвращает название дня недели в виде строки.
Синтаксис
WeekdayName(weekday, [abbreviate], [firstdayofweek]) |
Параметры
Параметр | Описание |
---|---|
weekday | Обязательный параметр. Числовое обозначение дня недели от 1 до 7 включительно. |
abbreviate | Необязательный параметр. Логическое значение: True – возвращается сокращенное название дня недели, False (по умолчанию) – название дня недели не сокращается. |
firstdayofweek | Константа, задающая первый день недели. По умолчанию – воскресенье. |
Таблицу констант из коллекции firstdayofweek
смотрите в параграфе «Приложение 2».
Пример
Sub PrimerWeekdayName() MsgBox WeekdayName(3, True, vbMonday) ‘Результат: Ср MsgBox WeekdayName(3, , vbMonday) ‘Результат: среда MsgBox WeekdayName(Weekday(Now, vbMonday), , vbMonday) End Sub |
Функция Year
Year – это функция, которая возвращает номер года в виде числа. Тип возвращаемого значения – Variant/Integer.
Синтаксис
Параметр date
– любое числовое или строковое выражение, представляющее дату.
Пример
Sub PrimerYear() MsgBox Year(Now) End Sub |
Приложение 1
Таблица аргументов (значений) параметраinterval
для функций DateAdd
, DateDiff
и DatePart
:
Аргумент | Описание | Интервал значений |
---|---|---|
yyyy | Год | 100 – 9999 |
q | Квартал | 1 – 4 |
m | Месяц | 1 – 12 |
y | День года | 1 – 366 |
d | День месяца | 1 – 31 |
w | День недели | 1 – 7 |
ww | Неделя | 1 – 53 |
h | Часы | 0 – 23 |
n | Минуты | 0 – 59 |
s | Секунды | 0 – 59 |
В третьей графе этой таблицы указаны интервалы значений, возвращаемых функцией DatePart
.
Приложение 2
Константы из коллекции firstdayofweek
:
Константа | Значение | Описание |
---|---|---|
vbUseSystem | 0 | Используются системные настройки |
vbSunday | 1 | Воскресенье (по умолчанию) |
vbMonday | 2 | Понедельник |
vbTuesday | 3 | Вторник |
vbWednesday | 4 | Среда |
vbThursday | 5 | Четверг |
vbFriday | 6 | Пятница |
vbSaturday | 7 | Суббота |
Приложение 3
Константы из коллекции firstweekofyear
:
Константа | Значение | Описание |
---|---|---|
vbUseSystem | 0 | Используются системные настройки. |
vbFirstJan1 | 1 | Неделя, в которую входит 1 января (по умолчанию). |
vbFirstFourDays | 2 | Неделя, в которую входит не менее четырех дней нового года. |
vbFirstFullWeek | 3 | Первая полная неделя года. |
В одном из заказов недавно столкнулся с проблемой получения праздничных дней согласно утвержденному производственному календарю. Да, я знаю, что в компаниях он может быть свой, отличный от опубликованного государством. И смысла как-то получать список праздничных дат с общедоступных порталов не было. Но вот именно сейчас потребовался именно общедоступный опубликованный календарь, чтобы можно было его автоматом скачать и применить. И оказалось, что это тоже не самая простая задача: многие календари в сети либо в формате PDF, либо в виде frame-ов по месяцам, либо вообще картинками. Только на одном сайте получилось найти файл для скачивания: https://data.gov.ru/opendata/7708660670-proizvcalendar. Но и там оказалась не сразу ссылка на готовый календарь, а описание набора, потом паспорт и уже только в паспорте набора можно найти ссылку на файл:
эта ссылка нам и нужна. И тут две проблемы:
Для рабочего проекта я выбрал способ получения дат через VBA(для поддержки всех версий независимо от надстроек), но в связи с популярностью Power Qwery решил сделать решение и при помощи этой надстройки.
Я постарался в коде в некоторых местах прописать комментарии, т.к. прописывать их напрямую в статье не очень удобно — код не маленький и описывать каждый кусок проблематично и больше запутает, чем прояснит процесс, как мне кажется.
'--------------------------------------------------------------------------------------- ' Author : Дмитрий (The_Prist) Щербаков ' Профессиональная разработка приложений для MS Office любой сложности ' Проведение тренингов по MS Excel ' https://www.excel-vba.ru ' info@excel-vba.ru ' WebMoney - R298726502453; Яндекс.Деньги - 41001332272872 ' Purpose: Загрузка праздничных дат из производственного календаря с сайта data.gov.ru ' https://www.excel-vba.ru/chto-umeet-excel/proizvodstvennyj-kalendar-v-excel-vba-i-power-qwery/ '--------------------------------------------------------------------------------------- Option Explicit 'объявление функции API - URLDownloadToFile для скачивания файла 'Идет в самом начале, т.к. API функции необходимо объявлять именно здесь ' работает на любых ПК под управлением ОС Windows ' на MAC код работать не будет #If Win64 Then 'для операционных систем с 64-разрядной архитектурой Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _ (ByVal pCaller As LongLong, ByVal szURL As String, ByVal szFileName As String, _ ByVal dwReserved As LongLong, ByVal lpfnCB As LongLong) As LongLong #Else #If VBA7 Then 'для любых операционных систем с офисом 2010 и выше Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _ (ByVal pCaller As LongPtr, ByVal szURL As String, ByVal szFileName As String, _ ByVal dwReserved As Long, ByVal lpfnCB As LongPtr) As LongPtr #Else 'для 32-разрядных операционных систем Declare Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" _ (ByVal pCaller As Long, ByVal szURL As String, ByVal szFileName As String, _ ByVal dwReserved As Long, ByVal lpfnCB As Long) As Long #End If #End If 'Основная процедура поиска ссылки и скачивания календаря ' в ходе работы использует остальные функции Sub LoadCalendar() Dim res, response$, surl$, sex$, sFName$, sMsg$ Dim oXMLHTTP As Object Dim lp&, le&, le2& Dim wbPrCalendar As Workbook Application.ScreenUpdating = False Err.Clear On Error GoTo err_handler 'подключаемся к сайту Set oXMLHTTP = CreateObject("MSXML2.XMLHTTP") With oXMLHTTP .Open "GET", "https://data.gov.ru/opendata/7708660670-proizvcalendar", False .send 'ждем пока страница прогрузится Do While .readyState <> 4 DoEvents Loop 'запоминаем исходный код страницы(для поиска ссылки) response = .responseText End With If Len(response) Then 'ищем место с ссылкой на наш CSV ' их там несколько, нам нужна "Гиперссылка (URL) на набор" lp = InStr(1, response, "Гиперссылка (URL) на набор", 1) If lp > 0 Then 'если нашли - ищем начало гиперссылки для скачивания(по ключевым http) le = InStr(lp, response, "http", 1) If le > 0 Then 'если это CSV - берем его le2 = InStr(le, response, ".csv", 1) 'CSV не нашли - пробуем найти xlsx(что вряд ли, но лушче попробовать) If le2 = 0 Then le2 = InStr(le, response, ".xls", 1) End If If le2 > 0 Then 'формируем только адрес ссылки для скачивания lp = InStr(le2, response, Chr(34), 1) surl = Mid(response, le, lp - le) lp = InStrRev(surl, ".") sex = Mid(surl, lp, Len(surl) - lp + 1) 'пробуем скачать при помощи функции API Set wbPrCalendar = CallDownload(surl, "prod_cal" & sex) 'обрабатываем скачанный файл If Not wbPrCalendar Is Nothing Then wbPrCalendar.Activate sFName = wbPrCalendar.FullName 'преобразуем данные в файле в столбец дат Call FillProdCalend(wbPrCalendar) wbPrCalendar.Close 0 DoEvents On Error Resume Next 'удаляем после обработки Kill sFName Err.Clear DoEvents sMsg = "Производственный календарь успешно обновлен" End If End If End If End If End If 'если будет какая-то ошибка - код перейдет сюда и покажет текст ошибки err_handler: If Err.Number <> 0 Then sMsg = "Не удалось обновить Производственный календарь." & vbNewLine & _ "Ошибка: " & Err.Description End If Application.ScreenUpdating = True MsgBox sMsg, vbInformation, "www.excel-vba.ru" End Sub '--------------------------------------------------------------------------------------- ' File : mDownloadFileFromURL ' Purpose: код позволяет скачивать файлы из интернета по указанной ссылке ' https://www.excel-vba.ru/chto-umeet-excel/kak-skachat-fajl-iz-interneta-po-ssylke/ '--------------------------------------------------------------------------------------- Function CallDownload(sFileURL As String, sFileName As String) As Workbook 'переменная для хранения пути к папке Dim sFilePath As String, ToPathName As String Dim h sFilePath = Environ("temp") If Right(sFilePath, 1) <> "" Then sFilePath = sFilePath & "" ToPathName = sFilePath & sFileName 'проверяем есть ли файл с таким же именем в выбранной папке If Dir(ToPathName, 16) <> "" Then On Error Resume Next Kill ToPathName DoEvents On Error GoTo 0 End If 'если не возникло ошибок при удалении файла - скачиваем его по ссылке ' если ошибка была - значит такой файл уже открыт ' и в дальнейшем все равно получим ошибку If Err.Number = 0 Then 'вызов функции API для непосредственно скачивания h = (URLDownloadToFile(0, sFileURL, ToPathName, 0, 0) = 0) 'если h = False - файл не удалось скачать, показываем инф.окно If h = False Then MsgBox "Невозможно скачать файл." & vbNewLine & _ "Возможно, у Вас нет прав на создание файлов в папке '" & sFilePath & "'.", _ vbInformation, "www.excel-vba.ru" Set CallDownload = Nothing Exit Function Else 'файл успешно скачан If IsBookOpen(sFileName) Then MsgBox "Файл с именем '" & sFileName & "' уже открыт. Закройте открытый файл и повторите попытку.", vbCritical, "www.excel-vba.ru" Else Set CallDownload = Application.Workbooks.Open(ToPathName) End If End If Else Set CallDownload = Nothing End If End Function 'функция заполнения листа "ProdCalend" датами из производственного календаря ' предварительно функция разбивает даты на отдельные ' т.к. изначально они записаны в виде перечня дней для каждого месяца Function FillProdCalend(wbCSV As Workbook) Dim acsv, ares() Dim dic As Object Dim llastr&, lr&, lc&, lcnt& Dim ly&, lm&, ld& Dim asp, sd$, s$, x Dim dt As Date With wbCSV.Worksheets(1) llastr = .Cells(.Rows.Count, 1).End(xlUp).Row acsv = .Cells(1, 1).Resize(llastr, 13).Value End With With ThisWorkbook.Sheets("ProdCalend") 'очищаем лист от старых данных .Columns(1).Cells.Clear 'здесь будем хранить список уникальных дат Set dic = CreateObject("scripting.dictionary") dic.comparemode = 1 'просматриваем каждую строку файла(год), начиная со 2-й For lr = 2 To UBound(acsv, 1) If IsNumeric(acsv(lr, 1)) Then ly = Val(Trim(acsv(lr, 1))) 'просматриваем каждый столбец файла(месяц), начиная со 2-го For lc = 2 To UBound(acsv, 2) lm = lc - 1 s = acsv(lr, lc) s = Trim(s) 'убираем символы + 'которыми обозначаются перенесенные праздничные дни s = Replace(s, "+", "") If Len(s) Then 'разбиваем единую строку вида 1,2,3,4,6*,7,9,10,16,17,23,24,30,31 'на отдельные дни asp = Split(s, ",") 'перебор каждого дня и создание из него даты 'с запоминанием в словарь дат dic For Each x In asp s = Trim(x) 'не учитываем даты со знаком * - это сокращенные предпраздничные дни If InStr(1, s, "*", 1) = 0 Then If Len(s) Then ld = Val(s) dt = DateSerial(ly, lm, ld) If Not dic.exists(dt) Then dic.Add dt, 0& End If End If End If Next End If Next End If Next 'даты есть - записываем на лист ' можно было поступить проще ' .Cells(2, 1).Resize(dic.Count).Value = Application.Transpose(dic.Keys) ' но этот метод опасен тем, что порой может выгрузить не все данные ' хотя в данном конкретном случае это очень маловероятно, т.к. ограничения касаются ' кол-ва строк в 65536 и текста в каждой строке до 255 символов If dic.Count > 0 Then ReDim ares(1 To dic.Count, 1 To 1) lr = 0 For Each x In dic.keys lr = lr + 1 ares(lr, 1) = x Next .Cells(1, 1).Value = "Праздники и выходные" .Cells(2, 1).Resize(dic.Count).Value = ares End If End With End Function 'Функция проверки - открыта ли книга с заданным именем 'подробнее: ' https://www.excel-vba.ru/chto-umeet-excel/kak-proverit-otkryta-li-kniga/ Function IsBookOpen(wbName As String) As Boolean Dim wbBook As Workbook For Each wbBook In Workbooks If Windows(wbBook.Name).Visible Then If wbBook.Name = wbName Then IsBookOpen = True: Exit For End If Next wbBook End Function
Чтобы использовать код необходимо создать файл Excel, в этом файле создать лист с именем «ProdCalend». Далее переходим в редактор VBA(Alt+F11) —Insert —Module. Вставляем туда код выше полностью. Или скачать файл ниже — там уже все сделано удобно и красиво:
Скачать файл с кодом:
В случае с Power Qwery все с одной стороны проще, а с другой есть свои нюансы. Взять хотя бы попытку получить напрямую текст страницы https://data.gov.ru/opendata/7708660670-proizvcalendar: если попытаться подключиться через стандартный метод(Другие(Other) —Из интернета(from Web), то придется очень долго разворачивать элемент Document на составные части разметки HTML в поисках тегов DIV и A для определения строки с гиперссылкой. Что на мой взгляд не оптимально и уж совсем не гибко — любое изменение структуры страницы, даже малейшее может привести к ошибке.
Поэтому я использовал менее очевидный, но куда более удобный в данном случае вариант — Lines.FromBinary(Web.Contents(«https://data.gov.ru/opendata/7708660670-proizvcalendar»)). Это самая важная строка в текущей задаче — она получает исходный текст страницы сайта в виде разбитого на строки текста, в котором потом можно будет просматривать и искать нужное нам
а дальше по сути идет тоже самое, что делалось кодом VBA: ищем в этом тексте ссылку, выдергиваем только ссылку для скачивания файла календаря, подключаемся к этой ссылке для получения конечного CSV и делаем преобразования. Только это выглядит куда проще и заметно короче, чем тоже самое на VBA Сам код из расширенного редактора:
let //получаем исходный текст страницы в виде разбитого на строки текста Source = Table.FromColumns({Lines.FromBinary(Web.Contents("https://data.gov.ru/opendata/7708660670-proizvcalendar"))}), //отбираем из строк ту, которая содержит внутри текст "Гиперссылка (URL) на набор" и ".csv" и превращаем все это в строку // т.к. изначально Table.SelectRows возвращает набор в виде таблицы CsvURLText = Table.SelectRows(Source, each Text.Contains([Column1], "Гиперссылка (URL) на набор") and Text.Contains([Column1], ".csv")){0}[Column1], //ищем начало гиперссылки url_start_pos = Text.PositionOf(CsvURLText,"http"), //ищем конец гиперссылки url_end_pos = Text.PositionOf(CsvURLText,".csv"), //формируем гиперссылку из CsvURLText url = Text.Middle(CsvURLText,url_start_pos,url_end_pos-url_start_pos+4), //скачиваем файл CSV по сформированной гиперссылке и открываем его //в заголовках будут имена месяцев csvfile = Table.PromoteHeaders(Csv.Document(Web.Contents(url),[Delimiter=",", Columns=18, Encoding=65001, QuoteStyle=QuoteStyle.None]), [PromoteAllScalars=true]), //сворачиваем столбцы с датами в два столбца: название месяца("Атрибут") и перечень дат("Значение") #"Несвернутые столбцы" = Table.UnpivotOtherColumns(csvfile, {"Год/Месяц", "Всего рабочих дней", "Всего праздничных и выходных дней", "Количество рабочих часов при 40-часовой рабочей неделе", "Количество рабочих часов при 36-часовой рабочей неделе", "Количество рабочих часов при 24-часовой рабочей неделе"}, "Атрибут", "Значение"), //убираем символы +, которыми обозначаются перенесенные праздничные дни #"Замененное значение1" = Table.ReplaceValue(#"Несвернутые столбцы","+","",Replacer.ReplaceText,{"Значение"}), //разбиваем столбец с днями на отдельные столбцы #"Разделить столбец по разделителю" = Table.SplitColumn(#"Замененное значение1", "Значение", Splitter.SplitTextByDelimiter(",", QuoteStyle.Csv), {"Значение.1", "Значение.2", "Значение.3", "Значение.4", "Значение.5", "Значение.6", "Значение.7", "Значение.8", "Значение.9", "Значение.10", "Значение.11", "Значение.12", "Значение.13", "Значение.14", "Значение.15", "Значение.16"}), //сворачиваем все столбцы с днями в два: "Атрибут.1"(нам не нужен) и день("Значение") #"Другие столбцы с отмененным свертыванием" = Table.UnpivotOtherColumns(#"Разделить столбец по разделителю", {"Год/Месяц", "Всего рабочих дней", "Всего праздничных и выходных дней", "Количество рабочих часов при 40-часовой рабочей неделе", "Количество рабочих часов при 36-часовой рабочей неделе", "Количество рабочих часов при 24-часовой рабочей неделе", "Атрибут"}, "Атрибут.1", "Значение"), //удаляем все строки с сокращенными днями #"Строки с примененным фильтром" = Table.SelectRows(#"Другие столбцы с отмененным свертыванием", each not Text.Contains([Значение], "*")), //в отдельном столбце формируем из столбцов с годом, месяцем и днем дату #"Добавлен пользовательский объект" = Table.AddColumn(#"Строки с примененным фильтром", "Пользовательский", each Date.FromText([Значение] & " " & [Атрибут] & " " & [#"Год/Месяц"],"Ru-ru")), //переименовываем столбец #"Переименованные столбцы" = Table.RenameColumns(#"Добавлен пользовательский объект",{{"Пользовательский", "Дата"}}), //удаляем лишние столбцы(по сути все, кроме столбца дата) #"Другие удаленные столбцы" = Table.SelectColumns(#"Переименованные столбцы",{"Дата"}), //преобразуем тип Any(Любой) в тип Дата #"Измененный тип" = Table.TransformColumnTypes(#"Другие удаленные столбцы",{{"Дата", type date}}) in #"Измененный тип"
Так же не стал расписывать со скринами по шагам все преобразования, т.к. каждый желающий может скачать файл(приложен ниже) с запросом PQ и просмотреть по шагам все действия:
Но если вдруг это надо будет — пишите в комментариях, постараюсь описать процесс наглядно(в будущем подготовлю видеоурок на данную тему).
0 / 0 / 0 Регистрация: 05.12.2016 Сообщений: 86 |
|
1 |
|
Заполнение выходных дней19.08.2019, 15:20. Показов 1847. Ответов 7
Добрый день, коллеги) Передо мной встала такая задача: Спасибо большое заранее.
0 |
0 / 0 / 0 Регистрация: 05.12.2016 Сообщений: 86 |
|
19.08.2019, 15:31 [ТС] |
2 |
Добавляю пример отчетности.
0 |
1813 / 1135 / 346 Регистрация: 11.07.2014 Сообщений: 4,002 |
|
20.08.2019, 17:43 |
3 |
Hikitosik, а что за сложности?
1 |
0 / 0 / 0 Регистрация: 05.12.2016 Сообщений: 86 |
|
21.08.2019, 12:13 [ТС] |
4 |
Это всё классно, уже попробовал реализовать. Всё можно сделать циклом, поскольку компаний константное количество. Даже формулу можно вывести Но хотелось бы, чтобы это делалось каким-то алгоритмом, который будет искать дни, которые были пропущены, и далее вставлять данные с ближайшей слева заполненной даты. Просто интересно не само заполнение выходных, а любого пропущенного дня. Тут я уже в ступоре, как проверить на отсутствие и скопировать необходимые данные. Пока ни одной толковый мысли не пришло, кроме как копировать и вставлять вручную))))
0 |
1813 / 1135 / 346 Регистрация: 11.07.2014 Сообщений: 4,002 |
|
21.08.2019, 16:20 |
5 |
копировать и вставлять вручную Что ж тоже вариант, только перед этим включить запись макроса, а после выполнения всех действий по копированию делаем Остановить запись. Получили макрос. Только вместо номера конкретного столбца ставите переменную, в которую вставляете индекс пустого столбца. А поиск пустой ячейки первой строки ну совсем просто — последовательной проверкой на космическую пустоту. В макрос вставляете добавление даты этого нового столбца на ещё 1 день.
0 |
0 / 0 / 0 Регистрация: 05.12.2016 Сообщений: 86 |
|
21.08.2019, 20:34 [ТС] |
6 |
Наверно, мы друг друга не совсем понимаем) Плюс проблема возникает в том, что таблица растёт в ширь. То есть необходимо будет приписывать справа к ней недостающие даты. Пока не осознал, как это правильно сделать
0 |
КостяФедореев Часто онлайн 790 / 529 / 237 Регистрация: 09.01.2017 Сообщений: 1,820 |
||||
22.08.2019, 00:07 |
7 |
|||
Hikitosik, попробуйте
Добавлено через 2 минуты Добавлено через 8 минут
2 |
1813 / 1135 / 346 Регистрация: 11.07.2014 Сообщений: 4,002 |
|
22.08.2019, 05:10 |
8 |
Hikitosik, у вас там в примере идет пустой столбец, я ориентировался по нему. Если пропущена дата, то это тоже просто, проверяешь разницу дат и, если больше 1, то делаешь то, что я писал. Мне хотелось, чтобы вы попробовали сами справиться и помочь в случае чего. Но если КостяФедореев взялся, то он вам всё напишет без проблем и без обучения. Удачи.
2 |
Содержание
- Обзор функции РАБДЕНЬ
- РАБДЕНЬ Синтаксис и входные данные функции:
- Найти ближайший рабочий день
- РАБДЕНЬ в Google Таблицах
- WORKDAY Примеры в VBA
Скачать пример рабочей книги
Загрузите образец книги
В этом руководстве показано, как использовать Функция РАБДЕНЬ в Excel в Excel добавить рабочие дни.
Обзор функции РАБДЕНЬ
Функция РАБДЕНЬ Возвращает рабочий день n количество рабочих дней (рабочие дни, исключая выходные: суббота и воскресенье) с даты начала. По желанию можно исключить праздники. Для нестандартных выходных используйте WORKDAY.INTL.
Чтобы использовать функцию рабочего листа Excel WORKDAY, выберите ячейку и введите:
(Обратите внимание, как появляется ввод формулы)
РАБДЕНЬ Синтаксис и входные данные функции:
1 | = РАБДЕНЬ (начальная_дата, дни, праздники) |
Дата начала — Дата начала в формате серийного номера Excel или введенная как дата с цитатами вокруг даты. Пример: нельзя вводить 11.12.2015 прямо в ячейку. Вместо этого вам нужно ввести «11/12/2015», или вам нужно будет использовать соответствующий серийный номер: 42320. В качестве альтернативы вы можете указать ячейку с введенной датой 11/12/2015. Excel автоматически преобразует даты, хранящиеся в ячейках, в последовательный формат (если дата не вводится как текст).
дней — Количество не выходных и не выходных дней с даты начала.
каникулы — ПО ЖЕЛАНИЮ. Массив со списком дат, представляющих праздники, которые следует исключить из рабочих дней.
Найти ближайший рабочий день
Чтобы найти ближайший рабочий день, используйте функцию РАБДЕНЬ:
Найти ближайший к сегодняшнему дню рабочий день
Чтобы найти ближайший к сегодняшнему дню рабочий день, используйте функцию СЕГОДНЯ с функцией РАБДЕНЬ:
1 | = РАБДЕНЬ (СЕГОДНЯ (); B3) |
Найти ближайший рабочий день за 10 дней
В этом примере будет найден ближайший рабочий день через 10 дней от даты начала:
Вы также можете использовать отрицательные дни для поиска рабочих дней в прошлом:
Рабочий день с праздниками
По умолчанию РАБДНИ игнорируют все праздники. Однако вы можете использовать третий необязательный аргумент для определения диапазона праздников:
1 | = РАБДЕНЬ (B3; C3; F3: F4) |
РАБДЕНЬ в Google Таблицах
Функция РАБДЕНЬ в Google Таблицах работает точно так же, как и в Excel:
WORKDAY Примеры в VBA
Вы также можете использовать функцию РАБДЕНЬ в VBA. Тип:Application.Worksheetfunction.Workday (начальная_дата, дни, праздники)
Выполнение следующих операторов VBA
123 | Диапазон («E2») = Application.WorksheetFunction.WorkDay (Диапазон («B2»), Диапазон («C2»))Диапазон («E3») = Application.WorksheetFunction.WorkDay (Диапазон («B3»), Диапазон («C3»))Диапазон («E4») = Application.WorksheetFunction.WorkDay (Диапазон («B4»), Диапазон («C4»), Диапазон («D4»)) |
даст следующие результаты
Для аргументов функции (начальная_дата и т. Д.) Вы можете либо ввести их непосредственно в функцию, либо определить переменные для использования вместо них.
Вернуться к списку всех функций в Excel
Вы поможете развитию сайта, поделившись страницей с друзьями
Содержание
- Метод WorksheetFunction.WorkDay (Excel)
- Синтаксис
- Параметры
- Возвращаемое значение
- Замечания
- Поддержка и обратная связь
- метод WorksheetFunction.WorkDay_Intl (Excel)
- Синтаксис
- Параметры
- Возвращаемое значение
- Замечания
- Поддержка и обратная связь
- Функция Weekday
- Синтаксис
- Settings
- Возвращаемые значения
- Замечания
- Пример
- См. также
- Поддержка и обратная связь
- VBA Excel. Расчет рабочего времени
- Календарь рабочего времени
- Заполнение строки часов
- Name already in use
- VBA-Docs / api / Excel.WorksheetFunction.WorkDay.md
Метод WorksheetFunction.WorkDay (Excel)
Возвращает число, представляющее дату, представляющую указанное число рабочих дней до или после даты (начальной даты). Рабочие дни исключают выходные и любые даты, определенные как праздники. Используйте WorkDay , чтобы исключить выходные или праздничные дни при расчете сроков выполнения счета, ожидаемого времени доставки или количества выполненных работ.
Синтаксис
expression. WorkDay (Arg1, Arg2, Arg3)
Выражение Переменная, представляющая объект WorksheetFunction .
Параметры
Имя | Обязательный или необязательный | Тип данных | Описание |
---|---|---|---|
Arg1 | Обязательный | Variant | Start_date — дата, представляющая дату начала. |
Arg2 | Обязательный | Variant | Days — количество ненедельных и ненедельных дней до или после start_date. Положительное значение для дней дает дату в будущем; отрицательное значение возвращает прошлую дату. |
Arg3 | Необязательный | Variant | Праздники — необязательный список одной или нескольких дат для исключения из рабочего календаря, например государственных и федеральных праздников и плавающих праздников. Список может быть диапазоном ячеек, содержащих даты, или константой массива серийных номеров, представляющих даты. |
Возвращаемое значение
Double
Замечания
Даты следует вводить с помощью функции DATE или в качестве результатов других формул или функций. Например, используйте date(2008,5;23) для 23-го дня мая 2008 г. Проблемы могут возникнуть, если даты вводятся в виде текста .
Microsoft Excel сохраняет даты как последовательные серийные номера, чтобы их можно было использовать в вычислениях. По умолчанию 1 января 1900 года — серийный номер 1, а 1 января 2008 года — серийный номер 39448, так как после 1 января 1900 г. это 39 448 дней. Microsoft Excel для Macintosh использует другую систему даты по умолчанию.
Visual Basic для приложений (VBA) вычисляет последовательные даты иначе, чем Excel. В VBA серийный номер 1 — 31 декабря 1899 года, а не 1 января 1900 года.
Если какой-либо аргумент не является допустимой датой, WorkDay возвращает #VALUE! значение ошибки.
Если start_date плюс дни возвращает недопустимую дату, WorkDay возвращает #NUM! значение ошибки.
Если число дней не является целым числом, оно усекается.
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
метод WorksheetFunction.WorkDay_Intl (Excel)
Возвращает серийный номер даты до или после указанного количества рабочих дней с пользовательскими параметрами выходных. Параметры выходного дня указывают, какое и сколько дней являются выходными днями. Выходные дни и все дни, указанные в качестве праздников, не считаются рабочими днями.
Синтаксис
expression. WorkDay_Intl (Arg1, Arg2, Arg3, Arg4)
Выражение Переменная, представляющая объект WorksheetFunction .
Параметры
Имя | Обязательный или необязательный | Тип данных | Описание | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Arg1 | Обязательный | Variant | Start_date — начальная дата, усеченная до целого числа. | ||||||||||||||||||||||||||||||
Arg2 | Обязательный | Variant | Days — количество рабочих дней до или после start_date. Положительное значение дает дату в будущем; отрицательное значение возвращает прошлую дату; значение 0 (ноль) возвращает start_date. Смещение дня усекается до целого числа. | ||||||||||||||||||||||||||||||
Arg3 | Необязательный | Variant | Выходные — указывает дни недели, которые являются выходными и не считаются рабочими днями. Weekend — это число или строка выходных, указывающая время выходных. Числовые значения выходных указывают на следующие выходные дни.
|
||||||||||||||||||||||||||||||
Arg4 | Необязательный | Variant | Праздники — необязательный набор из одной или нескольких дат, которые должны быть исключены из календаря рабочего дня. Праздники — это диапазон ячеек, содержащих даты или константу массива последовательного значения, представляющего эти даты. Порядок дат или серийных значений в праздники может быть произвольным. |
Возвращаемое значение
Double
Замечания
Если start_date выходит за пределы диапазона для текущего базового значения даты, WorkDay_Intl возвращает #NUM! значение ошибки.
Если какая-либо дата в праздники выходит за пределы диапазона для текущего базового значения даты, WorkDay_Intl возвращает #NUM! значение ошибки.
Если start_date плюс смещение дня возвращает недопустимую дату, WorkDay_Intl возвращает #NUM! значение ошибки.
Если строка выходных данных имеет недопустимую длину или содержит недопустимые символы, WorkDay_Intl возвращает #VALUE! значение ошибки.
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
Функция Weekday
Возвращает значение переменной Variant (Integer), отображающее дни недели.
Синтаксис
Weekday(date, [ firstdayofweek ])
Синтаксис функции Weekday состоит из таких именованных аргументов:
Part | Описание |
---|---|
дата | Обязательный аргумент. Переменная, числовое выражение, строковое выражение или любое выражение, отображающее дату. Если аргумент date содержит Null, возвращается значение Null. |
первый_день_недели | Необязательный аргумент. Константа, задающая первый день недели. Если она не указана, им является vbSunday. |
Settings
Аргумент первый_день_недели может принимать следующие значения:
Константа | Значение | Описание |
---|---|---|
vbUseSystem | 0 | Используются параметры API NLS. |
vbSunday | 1 | Воскресенье (по умолчанию) |
vbMonday | 2 | Понедельник |
vbTuesday | 3 | Вторник |
vbWednesday | 4 | Среда |
vbThursday | 5 | Четверг |
vbFriday | 6 | Пятница |
vbSaturday | 7 | Суббота |
Возвращаемые значения
Функция Weekday возвращает такие значения:
Константа | Значение | Описание |
---|---|---|
vbSunday | 1 | Воскресенье |
vbMonday | 2 | Понедельник |
vbTuesday | 3 | Вторник |
vbWednesday | 4 | Среда |
vbThursday | 5 | Четверг |
vbFriday | 6 | Пятница |
vbSaturday | 7 | Суббота |
Замечания
Если свойство Calendar имеет значение григорианский, возвращаемое целое число представляет григорианский день недели для аргумента date.
Если задан календарь хиджра, возвращаемое целое число означает день недели по календарю хиджра, соответствующий аргументу date. Для дат по календарю хиджра числовым аргументом является любое числовое выражение, представляющее дату или время с 1 января 100 года (2 августа 718 года по грегорианскому календарю) по 4 марта 9666 года (31 декабря 9999 года по грегорианскому календарю).
Пример
В этом примере функция Weekday возвращает день недели по указанной дате.
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
VBA Excel. Расчет рабочего времени
Расчет рабочего времени за период, ограниченный двумя датами, в течение одного года с помощью кода VBA Excel. Функция для расчета рабочего времени.
Календарь рабочего времени
Для расчета рабочего времени по двум датам нам понадобится производственный мини-календарь на год, состоящий из двух строк:
Создавать такой календарь вручную, не считая протяжку дат, довольно долго и нудно. Поэтому мы создадим производственный мини-календарь программно.
Для создания календаря рабочего времени из кода VBA Excel сначала следует запустить процедуру DaysOfYear, которая заполнит строку дат:
Для создания строки дат потребуется указать только два параметра: год и ячейку, с которой начинается эта строка.
Процедура DaysOfYear запускается из редактора VBA Excel и работает около минуты. Ускорить ее можно, используя массив, который заполняется датами и затем значения его элементов вставляются в диапазон дат.
В конце процедуры диапазону дат присваивается имя, по которому мы будем обращаться к нему в дальнейшем.
Заполнение строки часов
Допустим, нам нужен календарь с пятидневной 40-часовой рабочей неделей, в котором необходимо указать 8 часов для будничных дней и 0 часов — для выходных.
Заполняем строку рабочего времени из кода VBA Excel с помощью процедуры WorkingTimeDay, которая в ячейки строки времени под ячейками с субботой и воскресеньем вставляет 0, а под ячейками с буднями — 8:
Источник
Name already in use
VBA-Docs / api / Excel.WorksheetFunction.WorkDay.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
Copy raw contents
Copy raw contents
WorksheetFunction.WorkDay method (Excel)
Returns a number that represents a date that is the indicated number of working days before or after a date (the starting date). Working days exclude weekends and any dates identified as holidays. Use WorkDay to exclude weekends or holidays when you calculate invoice due dates, expected delivery times, or the number of days of work performed.
expression.WorkDay (Arg1, Arg2, Arg3)
expression A variable that represents a WorksheetFunction object.
Name | Required/Optional | Data type | Description |
---|---|---|---|
Arg1 | Required | Variant | Start_date — a date that represents the start date. |
Arg2 | Required | Variant | Days — the number of nonweekend and nonholiday days before or after start_date. A positive value for days yields a future date; a negative value yields a past date. |
Arg3 | Optional | Variant | Holidays — an optional list of one or more dates to exclude from the working calendar, such as state and federal holidays and floating holidays. The list can be either a range of cells that contain the dates or an array constant of the serial numbers that represent the dates. |
Double
[!IMPORTANT] Dates should be entered by using the DATE function, or as results of other formulas or functions. For example, use DATE(2008,5,23) for the 23rd day of May, 2008. Problems can occur if dates are entered as text .
Microsoft Excel stores dates as sequential serial numbers so they can be used in calculations. By default, January 1, 1900 is serial number 1, and January 1, 2008 is serial number 39448 because it is 39,448 days after January 1, 1900. Microsoft Excel for the Macintosh uses a different date system as its default.
[!NOTE] Visual Basic for Applications (VBA) calculates serial dates differently than Excel. In VBA, serial number 1 is December 31, 1899, rather than January 1, 1900.
If any argument is not a valid date, WorkDay returns the #VALUE! error value.
If start_date plus days yields an invalid date, WorkDay returns the #NUM! error value.
If days is not an integer, it is truncated.
Источник