Базовый курс. Занятие №3

Приступайте к третьему занятию базового курса.

ps. На этой странице не нужно отчитываться о выполнении ДЗ.

комментариев 6 на “Базовый курс. Занятие №3”

  1. Юрий Сартинский 29.09.2012 в 12:58
    &НаСервереБезКонтекста
    Функция СекундВДне()
        Возврат 60 * 60 * 24;
    КонецФункции // ПоменятьМестамиПараметры()

    &НаСервереБезКонтекста
    Функция МесяцевВГоду()
        Возврат 12;
    КонецФункции // МесяцевВГоду()

    &НаСервереБезКонтекста
    Функция ДнейВНеделе()
        Возврат 7;
    КонецФункции

    &НаСервереБезКонтекста
    Функция ПраздничныеДниМесяца(Праздники,Отбор)
        Возврат Праздники.НайтиСтроки(Отбор);
    КонецФункции // МесяцевВГоду()

    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
       
        // кэш для хранения параметров праздников
        // храним номер месяца в году и номер дня в месяце
        Праздники = Новый ТаблицаЗначений;
        Праздники.Колонки.Добавить("Месяц");
        Праздники.Колонки.Добавить("День");
       
        Строка = Праздники.Добавить();
        Строка.Месяц = 1;
        Строка.День = 1;
       
        Строка = Праздники.Добавить();
        Строка.Месяц = 2;
        Строка.День = 23;
       
        Строка = Праздники.Добавить();
        Строка.Месяц = 3;
        Строка.День = 8;
       
        ЛетАнализа = 10;
        МесяцевВГоду = МесяцевВГоду();
        ДнейВНеделе = ДнейВНеделе();
       
        Отбор = Новый Структура;
           
        НачальныйГод = НачалоГода(ТекущаяДата());
        КонечныйГод = ДобавитьМесяц(НачалоГода(ТекущаяДата()),МесяцевВГоду * ЛетАнализа);
        ТекущийГод = НачальныйГод;
       
        СекундВДне = СекундВДне();
       
        Пока ТекущийГод <= КонечныйГод Цикл
           
            // вначале количество рабочих дней полагаем равным общему числу дней в году
            // потом вычитаем выходные и праздники
            РабочихДней = ДеньГода(Дата(Год(ТекущийГод),Месяц(КонецГода(ТекущийГод)),День(КонецГода(ТекущийГод)))) -
                          ДеньГода(Дата(Год(ТекущийГод),Месяц(ТекущийГод),День(ТекущийГод))) + 1;
           
            ТекущийМесяц = ТекущийГод;
            ПоследнийМесяц = НачалоМесяца(КонецГода(ТекущийГод));
                   
            Пока ТекущийМесяц <= ПоследнийМесяц Цикл
               
                // дни и признак праздничного месяца
                Отбор.Вставить("Месяц",Месяц(ТекущийМесяц));
                ДниПраздников = ПраздничныеДниМесяца(Праздники,Отбор);
                ЭтоПраздничныйМесяц = ДниПраздников.Количество();
               
                // посчитаем субботы, воскресенья каждого месяца
                ВоскресеньеМесяца = ТекущийМесяц + (ДнейВНеделе - ДеньНедели(ТекущийМесяц)) * СекундВДне;
                СубботаМесяца = ВоскресеньеМесяца - СекундВДне;
               
                Пока Месяц(ВоскресеньеМесяца) = Месяц(ТекущийМесяц) Цикл
                   
                    РабочихДней = РабочихДней - 1;
                   
                    Если Месяц(СубботаМесяца) = Месяц(ТекущийМесяц) Тогда
                        РабочихДней = РабочихДней - 1;
                    КонецЕсли;
                   
                    ВоскресеньеМесяца = ВоскресеньеМесяца + ДнейВНеделе * СекундВДне;
                    СубботаМесяца = СубботаМесяца + ДнейВНеделе * СекундВДне;
                   
                КонецЦикла;
               
                Если Месяц(СубботаМесяца) = Месяц(ТекущийМесяц) Тогда
                    РабочихДней = РабочихДней - 1;
                КонецЕсли;
               
                // разберемся с праздниками
                Если ЭтоПраздничныйМесяц Тогда
                   
                    Для каждого Праздник Из ДниПраздников Цикл
                        // праздник не приходится на выходные
                        Если ДеньНедели(Дата(Год(ТекущийМесяц),Праздник.Месяц,Праздник.День)) < ДнейВНеделе - 1  Тогда
                            РабочихДней = РабочихДней - 1;
                        КонецЕсли;
                       
                    КонецЦикла;
                   
                КонецЕсли;
               
                // наращиваем месяц
                ТекущийМесяц = ДобавитьМесяц(ТекущийМесяц,1);
               
            КонецЦикла;
           
            Сообщить("В " + Год(ТекущийГод) + "-м году " + РабочихДней + " рабочих дней.",СтатусСообщения.Информация);
           
            // наращиваем год
            ТекущийГод = ТекущийМесяц;
           
        КонецЦикла;  
       
    КонецПроцедуры

    Результат:
    В 2 022-м году 258 рабочих дней.
    В 2 021-м году 258 рабочих дней.
    В 2 020-м году 261 рабочих дней.
    В 2 019-м году 259 рабочих дней.
    В 2 018-м году 258 рабочих дней.
    В 2 017-м году 258 рабочих дней.
    В 2 016-м году 258 рабочих дней.
    В 2 015-м году 259 рабочих дней.
    В 2 014-м году 260 рабочих дней.
    В 2 013-м году 259 рабочих дней.
    В 2 012-м году 259 рабочих дней.

  2. &НаСервереБезКонтекста
    Процедура ИсполнитьВолю()
       
        КонецКалендаря = ТекущаяДата()+(60*60*24*365*10);
        ОдинДень =  60*60*24;
        ДатаОтсчета= ТекущаяДата();
        КоличествоРабочихДней = 0;
        ТекущийГод = Год(ДатаОтсчета);
        ПрошлыйГод = ТекущийГод;
        РабочиеДниВГоду = Новый Массив;
        РабочиеДниВГоду.Добавить();
        СчетчикЛет = 0;
       
        Пока ДатаОтсчета < КонецКалендаря Цикл
            ТекущийГод = Год(ДатаОтсчета);
            ДеньНед = ДеньНедели(ДатаОтсчета);
            Если (ДеньНед >= 6) ИЛИ (ДатаОтсчета = Дата(Год(ДатаОтсчета),1,1) ИЛИ ДатаОтсчета = Дата(Год(ДатаОтсчета),2,23) ИЛИ ДатаОтсчета=Дата(Год(ДатаОтсчета),5,8))  Тогда
                ДатаОтсчета = ДатаОтсчета + ОдинДень ;
                Продолжить;
           
            КонецЕсли;
            Если ТекущийГод=ПрошлыйГод Тогда
                КоличествоРабочихДней = КоличествоРабочихДней + 1;
                РабочиеДниВГоду.Вставить(СчетчикЛет,КоличествоРабочихДней);
            ИначеЕсли ТекущийГод > ПрошлыйГод Тогда
                Сообщить ("В "+ Формат(ПрошлыйГод,"ЧГ=0") + " году рабочих дней: " + КоличествоРабочихДней);
                ПрошлыйГод=ТекущийГод;
                СчетчикЛет=СчетчикЛет + 1;
                КоличествоРабочихДней = 1;
                РабочиеДниВГоду.Добавить();
                РабочиеДниВГоду.Вставить(СчетчикЛет,КоличествоРабочихДней);    
            КонецЕсли;
           
            ДатаОтсчета = ДатаОтсчета + ОдинДень;
               
        КонецЦикла;
            КонецПроцедуры
    &НаКлиенте
    Процедура Щелк(Команда)
        ИсполнитьВолю();
    КонецПроцедуры
  3. &НаКлиенте
    Процедура ВычислитьКоличествоРабочихДней(Команда)
       
        ГодНачалоОтсчета = Год(ТекущаяДата());
        ГодОкончанияОтсчета = ГодНачалоОтсчета + 10;
        Для СчетчикЛет = ГодНачалоОтсчета По ГодОкончанияОтсчета Цикл
       
            Праздники = Новый Массив;
            Праздники.Добавить(Дата(СчетчикЛет, 01, 01));
            Праздники.Добавить(Дата(СчетчикЛет, 02, 23));
            Праздники.Добавить(Дата(СчетчикЛет, 03, 08));

            РабочихДней = 0;
            Для СчетчикМесяцев = 1 По 12 Цикл
                КонецМесяца = День(КонецМесяца(Дата(СчетчикЛет, СчетчикМесяцев,01)));
                Для СчетчкДней = 1 По КонецМесяца Цикл
                    ТекДата =Дата(СчетчикЛет, СчетчикМесяцев, СчетчкДней);
                    ТекДеньНедели = ДеньНедели(ТекДата);
                    Если (ТекДеньНедели <> 6 И ТекДеньНедели <> 7) И Праздники.Найти(ТекДата) = Неопределено Тогда
                        РабочихДней = РабочихДней + 1;
                    КонецЕсли;
                КонецЦикла;
            КонецЦикла;
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = Строка(СчетчикЛет) + " год - " + РабочихДней + " рабочих дней";
            Сообщение.Сообщить();
        КонецЦикла;
       
    КонецПроцедуры