Продвинутый курс. Домашнее задание №17

Эта запись посвящена второму потоку продвинутого курса по программированию.
Заключительное задание по расчету.

Для выполнения рекомендуется изучить следующие главы 3-го блока.
Глава 5. Перерасчеты
Глава 6. Диаграмма Ганта

К сожалению, у Вас недостаточно прав для просмотра этой записи. Если Вы еще не залогинены на сайте
залогиньтесь.

Если не активировали токен — посмотрите видео-инструкцию (видео N5)

Если вы залогинены, у Вас активирован токен доступа, но вы все равно видите эту запись —
напишите нам на e-mail поддержки.

комментариев 16 на “Продвинутый курс. Домашнее задание №17”

  1.                 Задание выполнил.
                    В плане видов расчета ОсновныеНачисления добавил предопределенный вид расчета Отпуск с зависимостью по базе от вида расчета Оклад. У видов расчета Оклад и БольничныйЛист добавил Отпуск в вытесняющие и ведущие виды расчета. У перечисления СпособыРасчета добавил значение Отпуск, установил это значение для вида расчет  Отпуск.
                    Для учета количества рабочих дней в регистр сведений ГрафикиРаботы добавил ресурс Дни, который заполнил значением 1 для рабочих дней по соответствующему графику (доработал обработку ЗаполнениеГрафика).
    Внес изменения в функции общего модуля РасчетЗП для расчета отпуска. В функции ПолучитьДанныеДляРасчета
    <code>

                    Если ИмяРегистра = “ОсновныеНачисления” Тогда
                                   Запрос.Текст = “ВЫБРАТЬ
                                   |             ОсновныеНачисления.НомерСтроки,
                                   |             ОсновныеНачисления.ВидРасчета.СпособРасчета Способ,
                                   |             ОсновныеНачисления.Размер,
                                   |             ОсновныеНачисления.ПериодДействияНачало,
                                   |             ОсновныеНачисления.ПериодДействияКонец”;
                                   Если Параметры.ДанныеГрафика Тогда
                                                   Запрос.Текст = Запрос.Текст + ”
                                                   |             ,ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеПериодДействия, 0) КАК План,
                                                   |                ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ДниФактическийПериодДействия, 0) КАК ДниФакт,
                                                   |                ЕСТЬNULL(ОсновныеНачисленияДанныеГрафика.ЗначениеФактическийПериодДействия, 0) КАК Факт”;
                                   КонецЕсли;
                                  
                                   Если Параметры.База Тогда
                                                   Запрос.Текст = Запрос.Текст + ”
                                   |             ,ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.РезультатБаза, 0) + ЕСТЬNULL(ОсновныеНачисленияБазаДополнительныеНачисления.РезультатБаза, 0) КАК База
                                   |             ,ЕСТЬNULL(ОсновныеНачисленияБазаОсновныеНачисления.ОтработанныеДниБаза, 0) КАК ОтработанныеДниБаза”;
                                   КонецЕсли;

    </code>
    В функции РассчитатьЗаписиРегистраРасчета:
    <code>
    Процедура РассчитатьЗаписиРегистраРасчета(Выборка, Набор, Отказ)
     
                    Поиск = Новый Структура(“НомерСтроки”);
                    Для каждого Запись Из Набор Цикл
                   
                                   Поиск.НомерСтроки = Запись.НомерСтроки;
                                   Выборка.Сбросить();
                                   Если Выборка.НайтиСледующий(Поиск) Тогда
                                  
                                                   Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремени Тогда
                                                                   Результат = Выборка.Размер*Выборка.Факт;
                                                   ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.ПоБольничномуЛисту Тогда
                                                                   Результат = Выборка.Размер*Выборка.Факт/3;
                                                   ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Процентом Тогда
                                                                   Результат = Выборка.Размер*Выборка.База/100;
                                                   ИначеЕсли Выборка.Способ = Перечисления.СпособыРасчета.Отпуск Тогда
                                                                   Если Выборка.ОтработанныеДниБаза = 0 Тогда
                                                                                  Результат = 0;
                                                                   Иначе
                                                                                  ДниОтпуска = Окр((Выборка.ПериодДействияКонец – Выборка.ПериодДействияНачало) / (24*3600), 2);
                                                                                  Результат = ДниОтпуска*Выборка.База/Выборка.ОтработанныеДниБаза;
                                                                   КонецЕсли;
                                                   КонецЕсли;
                                                  
                                                   Запись.Результат = Результат*?(Запись.Сторно, -1, 1);
                                                  
                                                   Если Выборка.Способ = Перечисления.СпособыРасчета.ПоОтработанномуВремени Тогда
                                                                   Запись.ОтработанныеДни = Выборка.ДниФакт*?(Запись.Сторно, -1, 1);
                                                   КонецЕсли;
                                  
                                   КонецЕсли;
                   
                    КонецЦикла;
    </code>
                    Для просмотра и редактирования начислений в документе НачислениеЗаработнойПлаты добавил в табличную часть Начисления  документа реквизиты Результат (тип Число) и РучнаяКорректировка (тип Булево). В регистры расчетов ОсновныеНачисления и ДополнительныеНачисления также добавил реквизит РучнаяКорректировка (тип Булево).
    При изменении в документе реквизита результат, реквизит РучнаяКорректировка устанавливается в значение Истина. При проведении документа ресурс Результат и реквизит РучнаяКорректировка в регистрах расчета заполняются соответствующими данными из документа. Записи регистров с реквизитом РучнаяКорректировка равным Истина не рассчитываются – в соответствующих процедурах и функциях общего модуля РасчетЗП в запросах добавил условие вида «…И (НЕ ОсновныеНачисления.РучнаяКорректировка)» . При открытии документа, реквизиты Результат и РучнаяКорректировка табличной части Начисления заполняются из движений регистров расчета:
    <code>
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
                    ЗаполнитьТаблицуНачислений();
    КонецПроцедуры
     
    &НаСервере
    Процедура ЗаполнитьТаблицуНачислений()
                    ДокОбъект = ДанныеФормыВЗначение(Объект, Тип(“ДокументОбъект.НачислениеЗаработнойПлаты”));
                    Запрос = Новый Запрос;
                    Запрос.Текст =
                                   “ВЫБРАТЬ
                                   |             ОсновныеНачисления.НомерСтроки,
                                   |             ОсновныеНачисления.ВидРасчета,
                                   |             СУММА(ОсновныеНачисления.Результат) КАК Результат,
                                   |             ОсновныеНачисления.РучнаяКорректировка
                                   |ИЗ
                                   |             РегистрРасчета.ОсновныеНачисления КАК ОсновныеНачисления
                                   |ГДЕ
                                   |             ОсновныеНачисления.Регистратор = &Ссылка
                                   |             И ОсновныеНачисления.Активность
                                   |
                                   |СГРУППИРОВАТЬ ПО
                                   |             ОсновныеНачисления.НомерСтроки,
                                   |             ОсновныеНачисления.ВидРасчета,
                                   |             ОсновныеНачисления.РучнаяКорректировка
                                   |
                                   |ОБЪЕДИНИТЬ ВСЕ
                                   |
                                   |ВЫБРАТЬ
                                   |             ДополнительныеНачисления.НомерСтроки,
                                   |             ДополнительныеНачисления.ВидРасчета,
                                   |             СУММА(ДополнительныеНачисления.Результат),
                                   |             ДополнительныеНачисления.РучнаяКорректировка
                                   |ИЗ
                                   |             РегистрРасчета.ДополнительныеНачисления КАК ДополнительныеНачисления
                                   |ГДЕ
                                   |             ДополнительныеНачисления.Регистратор = &Ссылка
                                   |             И ДополнительныеНачисления.Активность
                                   |
                                   |СГРУППИРОВАТЬ ПО
                                   |             ДополнительныеНачисления.НомерСтроки,
                                   |             ДополнительныеНачисления.ВидРасчета,
                                   |             ДополнительныеНачисления.РучнаяКорректировка”;
     
                    Запрос.УстановитьПараметр(“Ссылка”, ДокОбъект.Ссылка);
                    Результат = Запрос.Выполнить();
                    ВыборкаДетальныеЗаписи = Результат.Выбрать();
                    Поиск = Новый Структура(“НомерСтроки”);
                    Для каждого ТекущаяСтрока Из ДокОбъект.Начисления Цикл
                                   Поиск.НомерСтроки = ТекущаяСтрока.НомерСтроки;
                                   ВыборкаДетальныеЗаписи.Сбросить();
                                   Если ВыборкаДетальныеЗаписи.НайтиСледующий(Поиск) Тогда
                                                   ТекущаяСтрока.Результат = ВыборкаДетальныеЗаписи.Результат;
                                                   ТекущаяСтрока.РучнаяКорректировка = ВыборкаДетальныеЗаписи.РучнаяКорректировка;
                                   КонецЕсли;
                    КонецЦикла;
                    ЗначениеВДанныеФормы(ДокОбъект, Объект);
    КонецПроцедуры
    </code>
     
                    Создал отчет НачисленияСотрудникам аналогично приведенному в материалах курса. Возникли проблемы с реализацией пересчета начислений при редактировании пользователем интервалов. Рассмотрел приведенное Вами решение.

  2. Задание выполнил.
    Т.к. среднедневной заработок зависит от количества отработанных дней (а учет времени до этого был в часах, и  количество часов в одном дне может быть и не равно 8), то в регистр расчета ОсновныеНачисления ввел еще один реквизит ВидВремени (тип – ПеречислениеСсылка.ВидВремени) и связал с новым измерением регистра сведений ГрафикиРаботы  ВидВремени, и новый ресурс  ОтработаноДней. Для всех начислений плана видов расчета Основные начисления по умолчанию назначается вид времени – ПоЧасам, для Оклада (на этапе первичного формироварния записей) вводится дополнительная запись по ВидВремени=ПоДням. Т.е по Окладу идут две записи: по часам (которая расчитывается как раньше, и вторая – по дням ( Результа не рассчитывается и равен 0, а ОтработаноДней заполняется фактическим периодом действия по дневному графику).
    График записи по виду расчета Отпуск =ПоДням.  Для расчета среднедневного заработка берем базу по Результат и делим на базу ОтработаноДней (которая и является фактическим периодом действия оклада в базовом для отпуска периоде). Дальше, среднедневной заработок умножаем на фактический период действия Отпуска.
    Механизм реализации расчета и отрображения результата расчета в документе такой же как в эталонном решении. Реквзит регистра расчета НомерСтрокиДокумента позволяет легко избавится от  “лишних” записей по Окладу и отобразить количество отработанных дней в соотв. строке документа.
    Диаграмма Ганта съела всю печень. До конца не  победил, подсмотрел в Вашем решении.
     

  3. Решение заданий 13-17 брать из первого потока или будут выложены?

    • Решения скачивайте из записей 1-го потока.

  4. Задание выполнил.
    По первой части особых сложностей не возникло. А вот в процессе реализации отчета в виде диаграммы Ганта пришлось обращаться к эталонному решению.

  5. 1.Добавил в перечисление “СпособРасчета” новое значение “ПоСреднему”, создал новый вид расчёта “Отпуск” в ПВР “ОсновныеНачисления”, период базы = период действия, указал ему категорию, базу, способ расчёта и у тех ВР которые он вытесняет (оклад и больничный), настроил вытеснение. В документе “НачислениеЗП” сам указываю для строк движения регистра по ВР= “Отпуск” начало и окончание базового периода действия (3 календарных мес.).
    Т.к. необходимо что-бы работа по расчёту отпуска всегда была  однотипной и  нужно что-=бы не проиходило чрезмерного усложнения алгоритма расчёта сделал следующее: создал константу “ГрафикОтпуска” и если при азполнении документа “НачислениеЗП” ВР “Отпуск” назначат другой график – выдаст ошибку при сохранении по несоответствию графиков (имхо, так правильнее чем без предупреждений подменять на значение из константы). В регистр “ОсновныеНачисления” добавил новый реквизит “РезультатДней” – Ч2.0 – без этого наш вид расчёта становится неоправданным усложением универсальных алгоритмов а с реквизитом – много проще и быстрее сам расчёт но появляется немного избыточной инф., поэтому решил в прользу скорости. Сначало доработал общий модуль для расчёта реквизита “РезультатДней”, перепровёл документы “НачисолениеЗП” (и что-бы проверить работу изменений и что-бы реквизит “РезультатДней” стал непустой).Добавил необходимые изменения в универсальные алгоритмы для расчёта ВР “Отпуск”, отладил до работоспособности.
    2.В табличные части документа “НачислниеЗП” долбавил реквизиты Результат и Результат2 типа Ч15.2 Результат “положил” на форму, Результат2 – невидим пользователю. Далее механизм работы такой: при выполнении проведения по окончанию расчёта ВР провожу чтение движений и переношу результат в документ в реквизит Результат2 и если предыдущее значение реквизита “Результат” совпадало с предыдущим значением “Результат2” то и в “Результат”, если по внесению в корректироки в “Результат2” и возможно в  “Результат” значения реквизитоав не совпадают – вношу флажок “сохр”,  исправляю значение, по итогам обхода движений если флажок взведён – сохраняю весь модифицированный набор. Для оптимизации поиска соответсвия записи из регистра номеру строки документа добавил в документ “НомерСтроки” типа Ч4.0 в свои 4 регистра расчёта. Внёс соответствующие изменения а процедуру мроведения и перепровёл документы.
    3.Отчёт сделал – это несложно, контрольнового периода тоже несложное, но пока делал обработку изменения интервала чуть голову не сломал (на изменение времени потратил больше чем на всё остальное), для 2 и далее корректировки не находил документа (документ доставал из расшифровки значения интервала в обработчике события “ДиаграммаПриОкончанииРедактированияИнтервала”)…. вынужден был подсмотреть в решении – действительно есть такая проблемма…

  6. Это последнее задание? Когда финал и что будет из сюрпризов? ))

    • Это было последнее задание.
      Финал начнем в ближайшие дни.
      О бонусах расскажем позже.

  7. Задание выполнено.

    1. В перечисление СпособыРасчета добавил значение РасчетПоСреднему. В ПВР ОсновныеНачисления добавил вид расчета ОплачиваемыйОтпуск со способом расчета РасчетПоСреднему, база – Оклад. Настроил вытеснение – ОплачиваемыйОтпуск вытесняет Оклад и НачислениеПоБольничномуЛисту. В документ НачислениеЗП добавил в ТЧ Начисления реквизиты БазовыйПериодНачало и БазовыйПериодКонец (тип Дата), Результат (тип Число) и ИсправленоВручную (тип Булево). Внес изменения в универсальные алгоритмы расчета. В форме документа добавил кнопку Рассчитать, при нажатии на которую выполняется расчет “по канонам” и в ТЧ в поле Результат по каждой строке помещаются рассчитанные значения. Пользователь может вручную изменить значение результата на любое другое, в этом случае в ДействияПриИзмененииРезультат() признак ИсправленоВручную устанавливается в Истина. В ОбработкеПроведения() рассчитанные значения из ТЧ просто переписываются в РР.

    2. С диаграммой Ганта пришлось изрядно повозиться, и внимательно посмотреть уроки из соответствующей главы. Причем затруднения возникли не с самой диаграммой, а с перерасчетом в результате пользовательских корректировок интервалов начислений.
    Создал отчет НачисленияСотрудникам в виде диаграммы Ганта. Построил запрос к данным РР ОсновныеНачисления.ФактическийПериодДействия. Как и требуется в условии отчет выводит информацию по видам расчетов и их периодам действия в разрезе подразделений и сотрудников. Пользователь может корректировать интервалы, при этом в процедуре ДиаграммаПриОкончанииРедактированияИнтервала() происходит проверка – если после внесенных пользователем изменений начало и конец интервала для оклада находятся в разных месяцах, выдается сообщение об ошибке и действие отменяется. Если же проверка допустимости изменения интервалов прошла успешно, то получаем необходимые значения:
    [code]
    ДокРегистратор = Интервал.Значение.Расшифровка;
    ВидРасчета = Интервал.Значение.Серия.Значение;
    Сотрудник = Интервал.Значение.Точка.Значение;
    Подразделение = Интервал.Значение.Точка.родитель.Значение;
    ДатаНачала = Интервал.Начало;
    ДатаОкончания = Интервал.Конец.
    [/code]
    В серверной процедуре (которой передаю эти параметры) получаю документ-регистратор и в нужной строке ТЧ Начисления исправляю согласно внесенным изменениям дату начала и/или дату окончания для ВР. Перерасчитываю измененую строку и провожу документ, при этом в РР записываются измененые записи. Решение получилось какое-то не четкое, жду эталонное, чтобы свериться.

    • Решение можете взять от предыдущего потока продвинутого курса.

  8. Выполнил.
    1.Добавил в перечисление СпособыРасчета значение Отпуск, и в ПВР ОсновныеНачисления – ВР Отпуск.  Во всех остальных ВР из ОсновныеНачисления добавил Отпуск в вытесняющие ВР.
    2.В РР ОсновныеНачисления добавил ресурс, который заполняется отработанными днями, полученными из ВТ ДанныеГрафика через ЗначениеФПД. Ресурс заполняется при расчете записей регистра для способа ПоОтработанномуВремени.
    3.Скорректировал проведение документа НачислениеЗП, указав для ВР Отпуск в качестве базового периода 3 предыдущих месяца от начала месяца периода регистрации.  Подправил универсальный алгоритм расчета, добавив в него обработку способа расчета Отпуск.
    4.Для просмотра рассчитанной ЗП в форме документа была добавлена кнопка. По нажатию получаю ДокументОбъект из основного реквизита формы,  заполняю набор записей РР ОсновныеНачисления из соотв. ТЧ документа, вызываю процедуру общего модуля РассчитатьРегистрРасчета, выгружаю колонки с ресурсами в одноименные поля ТЧ документа и очищаю движения по РР.
    5.Создал отчет в виде диаграммы Ганта. При построении диаграммы во время обхода выборки свойство Значение.Расшифровка заполнялось структурой типа (Регистратор,НомерСтроки),
    а свойство Интервал.Расшифровка – структурой типа (ПериодДействияНачало, ПериодДействияКонец). Т.к. у Значения может быть несколько интервалов (т.е. для данной строки регистратора были вытеснения), 
    то при редактировании одного из них, обхожу коллекцию Интервал.Значение и вычисляю МинПериодДействияНачало и МаксПериодДействияКонец и заполняю ими поля ДатаНачала, ДатаОкончания  соотв. строки ДокументОбъекта и перепровожу документ. При выходе редактируемого интервала за границы указанного периода отменяю редактирование.

  9. ДЗ выполнил.
    Для реализации первой части задания – добавил новый способ расчета в перечисление и вид расчета в план видов расчета ОсновныеНачисления. Настроил вытеснение.Изменил документ Начисление ЗП – добавил кнопку Расчет (для заполнения значений в форме) по которой в модуле объекта делаю расчет данных и заполняю документ, а при проведении просто заполняются движения уже расчитанными данными. Также изменил алгоритмы в общем модуле.
    Для реализации второй части создал отчет с диаграммой ганта и добился отображения данных, а вот с пересчетом результата при изменении диаграммы возникли затруднения.

  10. Поскольку для расчета отпускных требуется определить количество отработанных дней, а оклад рассчитывался по часовому графику, создал еще один тип графика «Пятидневка дневной» и заполнил его проставив в рабочих днях значение 1. Добавил новое значение «Отпускные» в перечисление  «Способы расчета».
    Так как отпуск вытесняет и оклад, и оплату по больничному листу то добавлять его нужно в ПВР «Основные начисления», также, поскольку для его расчета потребуется данные базы, то у ПВР «Основные начисления» установил зависимость от базы по периоду действия. Настроил для отпуска, что базовым для него является оклад по часам, а ведущими оклад по часам и больничные. Настроил вытеснение оклада и больничного отпуском.
    Создал константу «График для расчета отпуска» и заполнил ее значение типом графика «Пятидневка дневной».
    Создал документ «Начисление отпускных» с реквизитами ПериодРегистрации, Сотрудник, Подразделение, Сторно, Результат, ДатаНачала и ДатаОкончания. В обработке проведения документа добавлял запись в регистр расчета «Основные начисления», заполнял ПериодДействияНачало и ПериодДействияКонец из реквизитов документа ДатаНачала и ДатаОкончания. БазовыйПериодНачало  и БазовыйПериодКонец расчетным путем 3 предшествующих месяца..
    Далее если результат не равнялся нулю, то вызывал процедуру общего модуля РассчитатьРегистрРасчета и присваивал реквизиту документа Результат значение Результат из регистра, после чего записывал документ командой Записать.
    Модифицировал процедуру расчета РассчитатьРегистрРасчета, при этом если с получением базы, т.е. сумм окладов за 3 предыдущих месяца проблем никаких нет, то для получения количества отработанных дней пришлось создавать отдельный запрос, поскольку здесь основные сложности заключаются в том, что для расчета оклада используется часовой график, а для расчета отпуска дневной. Схема запроса для получения данных по количеству отработанных дней следующая. Я обращался к таблице ФактическийПериодДействия с фильтром по виду расчета оклад по часом, сотруднику и подразделению, а также ПериодДействия МЕЖДУ &ДатаНачало И &ДатаКонца при этом в качестве параметров ДатаНачало и ДатаКонца я передавал БазовыйПериодНачало и БазовыйПериодНачало отпуска. К этой таблице я левым соединением подсоединял регистр сведений «Графики работы»  с условием связи вида ГрафикиРаботы.Дата МЕЖДУ ОсновныеНачисленияФактическийПериодДействия.ПериодДействияНачало И ОсновныеНачисленияФактическийПериодДействия.ПериодДействияКонец). Суммируя ресурс регистра «Значение» я получал данные по количеству отработанных дней за базовый период отпуска.
    Далее я столкнулся с еще одной проблемкой, которую объяснить до конца не смог. Проблема заключается в следующем. Количество дней отпуска вначале я планировал получать, обращаясь к данным графика для вида расчета отпуск используя поле  ЗначениеПериодДействия, но оказалось, что в нем содержится значение 21, это общее количество рабочих дней по графику в апреле. Это не совсем  понятно поскольку при записи в регистр я устанавливал, что ПериодДействияНачало равен началу отпуска (у меня 06.04.2011), а ПериодДействияКонец соответственно концу отпуска (у меня 16.04.2011) и по логике ЗначениеПериодДействия должен быть равен 11. Ладно, это еще можно объяснить, возможно ЗначениеФактическийПериодДействия содержит нужные мне данные, но обратившись к значению этого поля я увидел, что оно принимает значение Null. Вот это мне уже совсем не понятно, тем более, что в аналогичной ситуации для больничного ЗначениеФактическийПериодДействия содержит количество часов именно за период болезни который задается также через ПериодДействияНачало и ПериодДействияКонец. Евгений, помогите разобраться. Выкрутился я подсчитывая разность дат между ПериодДействияНачало и ПериодДействияКонец и получая количество календарных дней отпуска.
    При решении второй части задания вывод диаграммы не вызвал затруднений. А для того, чтобы при изменении интервала была возможность изменить конкретную запись регистра расчета, необходимо было через параметр Интервал процедуры ПриОкончанииРедактированияИнтервала передать ссылку на Регистратор и номер строки записи. Эту задачу ршил следующим образом при выводе диаграммы я ссылку на регистратор запоминал в свойстве Интервала Расшифровка, а номер строки в свойсвте Текст. В первой части поцедуры ПриОкончанииРедактированияИнтервала, я реализовал проверку на то, что конец интервала должен принадлежать тому ж периоду расчета регистра расчета, что и начало интервала. Для получения начала и конца расчетного периода написал отдельную функцию, которая в зависимости от периодичности регистра расчета возвращала границы расчетного периода по дате начала интервала. Вторая часть процедуры заключалась в создании набора записей регистра расчета, установке отбора по значению регистратора, чтение записей, перебор записей в цикле и для той записи номер строки которой совпадает с номером строки из свойства текст интервала изменение ПериодДействияНачало и ПериодДействияКонец на Начало и Конец из интервала. И в заключение запись набора записей обязательно с параметром Замещать установленным в значение Истина и вызов процедуры общего модуля РассчитатьРегистрРасчета с передачей ему в качестве параметра набора записей.
    Уфф.. На этом все.
    Поскольку для расчета отпускных требуется определить количество отработанных дней, а оклад рассчитывался по часовому графику, создал еще один тип графика «Пятидневка дневной» и заполнил его проставив в рабочих днях значение 1. Добавил новое значение «Отпускные» в перечисление  «Способы расчета».
    Так как отпуск вытесняет и оклад, и оплату по больничному листу то добавлять его нужно в ПВР «Основные начисления», также, поскольку для его расчета потребуется данные базы, то у ПВР «Основные начисления» установил зависимость от базы по периоду действия. Настроил для отпуска, что базовым для него является оклад по часам, а ведущими оклад по часам и больничные. Настроил вытеснение оклада и больничного отпуском.
    Создал константу «График для расчета отпуска» и заполнил ее значение типом графика «Пятидневка дневной».Создал документ «Начисление отпускных» с реквизитами ПериодРегистрации, Сотрудник, Подразделение, Сторно, Результат, ДатаНачала и ДатаОкончания. В обработке проведения документа добавлял запись в регистр расчета «Основные начисления», заполнял ПериодДействияНачало и ПериодДействияКонец из реквизитов документа ДатаНачала и ДатаОкончания. БазовыйПериодНачало  и БазовыйПериодКонец расчетным путем 3 предшествующих месяца. Далее если результат не равнялся нулю, то вызывал процедуру общего модуля РассчитатьРегистрРасчета и присваивал реквизиту документа Результат значение Результат из регистра, после чего записывал документ командой Записать.
    Модифицировал процедуру расчета РассчитатьРегистрРасчета, при этом если с получением базы, т.е. сумм окладов за 3 предыдущих месяца проблем никаких нет, то для получения количества отработанных дней пришлось создавать отдельный запрос, поскольку здесь основные сложности заключаются в том, что для расчета оклада используется часовой график, а для расчета отпуска дневной. Схема запроса для получения данных по количеству отработанных дней следующая. Я обращался к таблице ФактическийПериодДействия с фильтром по виду расчета оклад по часом, сотруднику и подразделению, а также ПериодДействия МЕЖДУ &ДатаНачало И &ДатаКонца при этом в качестве параметров ДатаНачало и ДатаКонца я передавал БазовыйПериодНачало и БазовыйПериодНачало отпуска. К этой таблице я левым соединением подсоединял регистр сведений «Графики работы»  с условием связи вида ГрафикиРаботы. Дата МЕЖДУ ОсновныеНачисленияФактическийПериодДействия.ПериодДействияНачало И ОсновныеНачисленияФактическийПериодДействия.ПериодДействияКонец). Суммируя ресурс регистра «Значение» я получал данные по количеству отработанных дней за базовый период отпуска.
    Далее я столкнулся с еще одной проблемкой, которую объяснить до конца не смог. Проблема заключается в следующем. Количество дней отпуска вначале я планировал получать, обращаясь к данным графика для вида расчета отпуск используя поле  ЗначениеПериодДействия, но оказалось, что в нем содержится значение 21, это общее количество рабочих дней по графику в апреле. Это не совсем  понятно поскольку при записи в регистр я устанавливал, что ПериодДействияНачало равен началу отпуска (у меня 06.04.2011), а ПериодДействияКонец соответственно концу отпуска (у меня 16.04.2011) и по логике ЗначениеПериодДействия должен быть равен 11. Ладно, это еще можно объяснить, возможно ЗначениеФактическийПериодДействия содержит нужные мне данные, но обратившись к значению этого поля я увидел, что оно принимает значение Null. Вот это мне уже совсем не понятно, тем более, что в аналогичной ситуации для больничного ЗначениеФактическийПериодДействия содержит количество часов именно за период болезни который задается также через ПериодДействияНачало и ПериодДействияКонец. Евгений, помогите разобраться. Выкрутился я подсчитывая разность дат между ПериодДействияНачало и ПериодДействияКонец и получая количество календарных дней отпуска.
    При решении второй части задания вывод диаграммы не вызвал затруднений. А для того, чтобы при изменении интервала была возможность изменить конкретную запись регистра расчета, необходимо было через параметр Интервал процедуры ПриОкончанииРедактированияИнтервала передать ссылку на Регистратор и номер строки записи. Эту задачу решил следующим образом при выводе диаграммы я ссылку на регистратор запоминал в свойстве Интервала Расшифровка, а номер строки в свойсвте Текст. В первой части поцедуры ПриОкончанииРедактированияИнтервала, я реализовал проверку на то, что конец интервала должен принадлежать тому ж периоду расчета регистра расчета, что и начало интервала. Для получения начала и конца расчетного периода написал отдельную функцию, которая в зависимости от периодичности регистра расчета возвращала границы расчетного периода по дате начала интервала.
    Вторая часть процедуры заключалась в создании набора записей регистра расчета, установке отбора по значению регистратора, чтение записей, перебор записей в цикле и для той записи номер строки которой совпадает с номером строки из свойства текст интервала изменение ПериодДействияНачало и ПериодДействияКонец на Начало и Конец из интервала. И в заключение запись набора записей обязательно с параметром Замещать установленным в значение Истина и вызов процедуры общего модуля РассчитатьРегистрРасчета с передачей ему в качестве параметра набора записей.
    Уфф. На этом все.

    • 1. Количество отработанных дней проще, быстрее и правильнее нужно получать следующим образом:
      – При расчете видов расчета, входящих в норму времени (в нашем случае – оклад), нужно записывать в специальный ресурс регистра расчета количество отработанных дней.
      Можно воспользоваться простой арифметикой: 1 день = 8 часов.
      Далее, получать количество отработанных дней, из таблицы базы.
      2.
      > используя поле ЗначениеПериодДействия
      В поле содержится именно плановое значение из данных графика.
      Фактическое значение должно действительно содержаться в ЗначениеФактическийПериодДействия.
      Но у Вас в этом поле значение NULL.
      Проверьте, что Отпуск в этот период не вытесняет никакой вид расчета и что в указанный период действия есть рабочие дни (именно по графику, указанному в записи отпуска).
      Присылайте базу на ящик мастер-группы, будем разбираться.

      • 1. >Можно воспользоваться простой арифметикой: 1 день = 8 часов.
        Я сначала хотел использовать эту арифметику и получать данные из регистра расчета, вообще не меняя его структуру. Но меня остановило то, что не всегда равенство 1 день = 8 часов будет выполняться, а если не полный рабочий день например 6 часов, тогда как?  С тем, что сохранять количество рабочих дней в отдельном ресурсе регистра расчетов я согласен, что будет быстрее, но и у моего решения есть плюс: не придется хранить в регистре то значение, которое можно получить расчетным путем.
        2. Данные в графике за период отпуска есть. Отпуск действительно вытесняет оклад по часам. И получается, что в этом случае для него не будет заполнено ЗначениеФактическийПериодДействия, почему так?  И как тогда получать значение фактического периода действия для отпуска.
        Базу отправил.
         

        • >Я сначала хотел использовать эту арифметику и получать данные из регистра расчета, вообще не меняя его структуру
          Думаю, что не получиться, без изменения структуры.
          >Но меня остановило то, что не всегда равенство 1 день = 8 часов будет выполняться, а если не полный рабочий день например 6 часов, тогда как?
          Можно в регистре, описывающем график хранить еще один ресурс – рабочий день или нет.
          И в моей реализации (использую специальный ресурс регистра расчета) количество отработанных дней можно получить количество отработанных дней с помощью таблицы данных графика.
          >но и у моего решения есть плюс: не придется хранить в регистре то значение, которое можно получить расчетным путем
          Далеко не факт, что это плюс.
          Вообще регистры, это избыточная информация (исключение – регистры сведений). Они и создаются, чтобы хранить рассчитанные данные.
          Ведь даже данные об остатках можно получить без использования регистров (помним задание 13*).
          Еще один момент – количество отработанных дней на практике будет требоваться во многих алгоритмах, поэтому правильно, чтобы оно было посчитано.
          >Базу отправил.
          Будем разбираться.