Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Excel
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.05.2010, 13:58   #1
Mint86
Пользователь
 
Аватар для Mint86
 
Регистрация: 17.07.2008
Сообщений: 81
По умолчанию Аналог функции ЧИСТРАБДНИ

Коллеги, нужен макрос (или формула если это возможно) аналог функции ЧИСТРАБДНИ из надстройки "Пакет анализа". Здесь описание данной функции.
Mint86 вне форума Ответить с цитированием
Старый 12.05.2010, 15:58   #2
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

тестируйте,вроди бы работает

Код:


Private Sub CommandButton1_Click()

f = What_Rab("1.05.2010", "29.05.2010")
f 1= What_Wyh("1.05.2010", "29.05.2010")
End Sub
Function What_Rab(date_st As Date, date_en As Date) As Integer
  Dim rez, rezult As String
  Dim dd As Integer, poz As Integer, MyWeekDay As Integer, Period As Double
  Period = (Format(date_en, "#")) - (Format(date_st, "#"))+ 1
   Dim d As Double
   Dim Md As Long: Dim mm As Long: Dim n As Long
    MyWeekDay = Weekday(DateSerial(Year(date_st), Month(date_st), Day(date_st)), vbMonday)
 For n = MyWeekDay To Period + MyWeekDay - 1
   mm = n: rez = ""
 Do While mm >= 7
      Md = mm Mod 7
      mm = Int(mm / 7)
      rez = Md & rez
     Loop
 rezu = mm & rez
poz = (Mid(rezu, Len(rezu), 1))
 Select Case poz
 Case 0, 6
  dd = dd + 1
 End Select
Next
What_Rab = Period - dd
End Function



Function What_Wyh(date_st As Date, date_en As Date) As Integer
  Dim rez, rezult As String
  Dim dd As Integer, poz As Integer, MyWeekDay As Integer, Period As Double
  Period = (Format(date_en, "#")) - (Format(date_st, "#"))+ 1
   Dim d As Double
   Dim Md As Long: Dim mm As Long: Dim n As Long
    MyWeekDay = Weekday(DateSerial(Year(date_st), Month(date_st), Day(date_st)), vbMonday)
 For n = MyWeekDay To Period + MyWeekDay - 1
   mm = n: rez = ""
 Do While mm >= 7
      Md = mm Mod 7
      mm = Int(mm / 7)
      rez = Md & rez
     Loop
 rezu = mm & rez
poz = (Mid(rezu, Len(rezu), 1))
 Select Case poz
 Case 0, 6
  dd = dd + 1
 End Select
Next
What_Wyh = dd
End Function
Строку подкорректировал Period = (Format(date_en, "#")) - (Format(date_st, "#"))+ 1
Анализ,обработка данных Недорого

Последний раз редактировалось doober; 12.05.2010 в 16:05.
doober вне форума Ответить с цитированием
Старый 12.05.2010, 16:40   #3
Mint86
Пользователь
 
Аватар для Mint86
 
Регистрация: 17.07.2008
Сообщений: 81
По умолчанию

Работает, но надо бы добавить возможность учета и праздничных дней...
Mint86 вне форума Ответить с цитированием
Старый 12.05.2010, 17:48   #4
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Раставте правильно праздники
Код:
 Dim Holi As Collection
 
 Sub Holi_Add()
Set Holi = New Collection
Holi.Add "03.05.2010"
Holi.Add "10.05.2010"
'дальше сами
End Sub
Function Holiday(date_st As Date, date_en As Date) As Integer
  Holiday = 0
  Dim dd As Integer, poz As Integer, MyWeekDay As Integer, Period As Double
    Period = (Format(date_en - date_st, "#"))
    For n = 0 To Period
   Dim g
    
For Each g In Holi

If CDate(g) = date_st + n Then
Holiday = Holiday + 1
End If
Next g

  Next
End Function

Private Sub CommandButton1_Click()

f = What_Rab("1.05.2010", "29.05.2010")
f1 = What_Wyh("1.05.2010", "29.05.2010")
End Sub
Function What_Rab(date_st As Date, date_en As Date) As Integer
 Holi_Add

  Dim rez, rezult As String
  Dim dd As Integer, poz As Integer, MyWeekDay As Integer, Period As Double
    Period = (Format(date_en - date_st, "#")) + 1
  
  Period = (Format(date_en - date_st, "#")) + 1
   Dim d As Double
   Dim Md As Long: Dim mm As Long: Dim n As Long
    MyWeekDay = Weekday(DateSerial(Year(date_st), Month(date_st), Day(date_st)), vbMonday)
 For n = MyWeekDay To Period + MyWeekDay - 1
   mm = n: rez = ""
 Do While mm >= 7
      Md = mm Mod 7
      mm = Int(mm / 7)
      rez = Md & rez
     Loop
 rezu = mm & rez
poz = (Mid(rezu, Len(rezu), 1))
 Select Case poz
 Case 0, 6
  dd = dd + 1
 End Select
Next
What_Rab = Period - dd - Holiday(date_st, date_en)
End Function



Function What_Wyh(date_st As Date, date_en As Date) As Integer
 Holi_Add
  Dim rez, rezult As String
  Dim dd As Integer, poz As Integer, MyWeekDay As Integer, Period As Double
  Period = (Format(date_en - date_st, "#")) + 1
   Dim d As Double
   Dim Md As Long: Dim mm As Long: Dim n As Long
    MyWeekDay = Weekday(DateSerial(Year(date_st), Month(date_st), Day(date_st)), vbMonday)
 For n = MyWeekDay To Period + MyWeekDay - 1
   mm = n: rez = ""
 Do While mm >= 7
      Md = mm Mod 7
      mm = Int(mm / 7)
      rez = Md & rez
     Loop
 rezu = mm & rez
poz = (Mid(rezu, Len(rezu), 1))
 Select Case poz
 Case 0, 6
  dd = dd + 1
 End Select
Next
What_Wyh = dd + Holiday(date_st, date_en)
End Function
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 12.05.2010, 19:24   #5
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

или вот формула для определения количества выходных:
Код:
=ЦЕЛОЕ((B1-A1+1)/7-(ДЕНЬНЕД(B1;2)<ДЕНЬНЕД(A1;2))*1)*2+(ДЕНЬНЕД(A1;2)<6)*(ДЕНЬНЕД(B1;2)<ДЕНЬНЕД(A1;2))*2+(ДЕНЬНЕД(A1;2)>5)*(8-ДЕНЬНЕД(A1;2))+(ДЕНЬНЕД(B1;2)>5)*(ДЕНЬНЕД(B1;2)-5)+СУММПРОИЗВ((праздники>=A1)*(праздники<=B1-(ДЕНЬНЕД(B1;2)-5)*(ДЕНЬНЕД(B1;2)>5)))
понятно, рабочих будет "всех" минус "выходных".
Подойдет, как для расчетов, так и для тестирования функции, которую doober написал. Интересно сколько будет отличий в определении количества этих самых дней.
именованый диапазон "праздники" - надо бы дополнить и поправить под местное законодательство...
Вложения
Тип файла: rar Книга328.rar (4.0 Кб, 24 просмотров)
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 12.05.2010, 19:49   #6
doober
Старожил
 
Аватар для doober
 
Регистрация: 02.05.2009
Сообщений: 3,907
По умолчанию

Да .С праздниками просквозил.Надо так
Код:
 Sub Holi_Add()
Set Holi = New Collection
Holi.Add "01.05.2010"
Holi.Add "02.05.2010"
Holi.Add "9.05.2010"
'дальше сами
End Sub
Анализ,обработка данных Недорого
doober вне форума Ответить с цитированием
Старый 12.05.2010, 22:10   #7
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

я у себя уже ошибку нашел:
=ЦЕЛОЕ((B1-A1+1)/7-(ДЕНЬНЕД(B1;2)<ДЕНЬНЕД(A1;2))*1)*2. ..
=ЦЕЛОЕ((B1-A1+1)/7-(ДЕНЬНЕД(B1;2)<=ДЕНЬНЕД(A1;2))*1)*2...
doober, с 25 апр. по 9 мая - у нас разные результаты.
у меня 7 выходных, 8 рабочих.
у тебя ровно наоборот: 8 выходных, 7 рабочих. Т.к. функции независимые - значит в обоих по ошибке.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Старый 13.05.2010, 06:54   #8
Mint86
Пользователь
 
Аватар для Mint86
 
Регистрация: 17.07.2008
Сообщений: 81
По умолчанию

IgorGO, формула почему-то дает с 01.05.2010 по 31.05.2010 гг. 8 выходных без праздников. А макрос doober 10 выходных. Правильно 10 выходных (ручной подсчет) или для проверки с использованием функции чистрабдни =ДЕНЬ(ДАТА(2010;5;31))-ЧИСТРАБДНИ(ДАТА(2010;5;1);ДАТА(2010 ;5;31))

doober, а можешь изменить код чтобы праздничные дни брались из диапазона ячеек?
Mint86 вне форума Ответить с цитированием
Старый 13.05.2010, 07:04   #9
Mint86
Пользователь
 
Аватар для Mint86
 
Регистрация: 17.07.2008
Сообщений: 81
По умолчанию

doober, в коде надо сделать проверку на день недели праздничного дня. Иначе с 01.05.2010 по 31.05.2010 с праздниками
Holi.Add "01.05.2010"
Holi.Add "02.05.2010"
Holi.Add "9.05.2010"
получается что выходных дней 13 а на самом деле 02.05.2010 года уже выходной его в расчет брать не надо.

Проверка сделана с помощью той же функции чистрабдни и вручную.
Mint86 вне форума Ответить с цитированием
Старый 13.05.2010, 10:37   #10
IgorGO
Новичок
СтарожилДжуниор
 
Аватар для IgorGO
 
Регистрация: 05.02.2008
Сообщений: 9,487
По умолчанию

согласен, опять ошибка.
запишите в С1 вот это:
Код:
=СУММПРОИЗВ((ДЕНЬНЕД(A1+СТРОКА(ДВССЫЛ("1:"&B1-A1+1))-1;2)>5)*1)+СУММПРОИЗВ((праздники>=A1)*(праздники<=B1-(ДЕНЬНЕД(B1;2)-5)*(ДЕНЬНЕД(B1;2)>5)))
у данной формулы, по сравнению с предыдущей, есть несколько преимуществ:
1. правильно считает
2. намного короче (это очень существенно для меня лично)
3. простой алгоритм
и один недостаток:
та формула была сделана на логике, и подсчет осуществлялся за счет математических формул, а эта на тупом переборе всех дат входящих в интервал с проверкой - а не суббота ли или воскресенье данная дата.
Программисты - это люди, решающие проблемы, о существовании которых Вы не подозревали, методами, которых Вы не понимаете
IgorGO вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Аналог функции ЧИСТВНДОХ Mint86 Microsoft Office Excel 7 13.05.2010 08:41
аналог функции case redfield Microsoft Office Excel 3 05.05.2010 12:25
Аналог этой функции на C killer12rus Помощь студентам 1 20.03.2010 15:23
Аналог функции ИЛИ (OR) на VBA Andrey3055 Microsoft Office Excel 4 03.11.2009 13:47
Аналог функции WriteProcessMemory KleoY Win Api 10 31.03.2009 01:17