Конфигурирование в системе 1С:Предприятие 8.0 Решение задач расчета зарплаты и учета персонала
Введение
Настоящий курс является продолжением курса «Введение в конфигурирование в системе «1С:Предприятие 8.0». Основные объекты».
Для успешного прохождения курса требуются знание основных объектов и механизмов системы «1С:Предприятие 8.0».
В данном курсе рассматриваются только механизмы и объекты системы «1С:Предприятие 8.0», предназначенные для автоматизации расчетных задач.
Основной целью учебного курса и данных методических материалов является освоение программы как инструмента по созданию собственных оригинальных конфигураций, развитие практических навыков по конфигурированию.
При подготовке сквозного примера, который лег в основу учебного курса, мы осознанно отошли от типовых конфигураций, поставляемых с программными продуктами фирмы «1С». Упростив задачу учета, мы стремимся пройти по всем этапам конфигурирования, добиваясь главной цели - получить навыки самостоятельной работы по созданию решений, связанных со сложными периодическими расчетами.
Постановка задачи
Поставим задачу для конфигурирования. Необходимо на базе конфигурации от предыдущего курса «Введение в конфигурирование в системе «1С:Предприятие 8.0». Основные объекты» организовать простейший расчет зарплаты сотрудников организации.
Для этого нужно:
- Определиться с перечнем используемых в организации
начислений, удержаний и выплат. Обязательно нужно
использовать начисления Оклад, ПремияПроцентом, Отпуск (с
расчетом среднего заработка за три предыдущих месяца),
удержание Штраф и выплату Выплата.
- Организовать возможность хранения информации о видах
расчета и результатах расчета, а также о периодах действия и
периодах регистрации записей расчетов.
- Ввод информации о расчетах в регистр должен осуществляться
при помощи специальных документов. В базе данных должна
быть информация за несколько расчетных периодов.
- Реализовать возможность расчета зависимых от отработанного
времени видов расчета с использованием различных графиков
работы.
- Организовать возможность ввода информации «задним числом»
с последующим формированием сторно-записей.
- Организовать возможность сторнирования и исправления
данных с помощью специальных корректирующих документов.
- Организовать возможность регламентного ввода долгосрочных
начислений и удержаний.
- Реализовать возможность планирования событий начисления
зарплаты с автоматическим контролем времени выполнения
событий.
- Реализовать возможность одновременной работы пользователей
программы в разных расчетных периодах.
- Организовать возможность перерасчета записей (например,
премии) при изменении состояния ведущих записей (оклада), а
также ввода сторнирующих и корректирующих записей в
текущем периоде при изменении расчетной информации в
«закрытых» периодах,
- Организовать возможность формирования совокупности
отчетов о расчетах сотрудников.
- Организовать возможность распределения зарплаты по разным
разрезам учета.
Решение задачи

Объекты, используемые в расчетных задачах. Общие сведения
Сначала попытаемся представить, как можно было бы решить задачу, используя уже известные нам объекты 8.0 (справочники, документы, регистры сведений и т.д.).
Очевидно, сначала мы бы создали список начислений и удержаний (например, справочник «Начисления и удержания»). Для ввода начислений и удержаний создали бы специальный документ «Ввод начислений и удержаний». При проведении документа (в модуле документа) написали бы алгоритмы для расчета начислений и удержаний. Результат расчета сохраняли бы в специальном регистре накопления (в одном из его ресурсов). При построении отчетов использовали бы выборку по регистру накопления. Представим сказанное в виде схемы:
Итак, решение очевидно, но удобно ли будет пользоваться такой конфигурацией? Рассмотрим ситуацию: сотруднику помимо оклада начисляется, например, доплата за вредность, доплата за сложность, премия процентом. Эти начисления зависят от оклада. При изменении оклада надо будет каким-то образом пересчитывать результаты всех зависимых расчетов, а для этого очевидно перепроводить все документы, которыми были введены эти начисления, причем в определенной последовательности: сначала документ, которым вводился оклад, затем остальные. В случае же исправления расчетов прошлых периодов необходимо организовывать довольно сложный механизм сторнирования. Все это достаточно сложно реализовать на простых регистрах накопления и документах. Таких проблем может возникнуть очень много.
Конфигурирование в системе " 1С:Предприятие 8.0". Решение расчетных задач
Поэтому разработчики системы «1С:Предприятие 8.0» решили облегчить задачу пользователям и программистам и создали ряд специализированных объектов, которые очень удобно использовать при ведении сложных периодических расчетов, в том числе с пересчетом «задним числом», организации сложной выборки данных, организации взаимного влияния расчетных записей и т.д. Рассмотрим данные объекты.
Представим, что в рассмотренной задаче мы преобразовали справочник «Начисления и удержания» в очень похожий объект и назвали его планом видов расчета (перед этим добавив «справочнику» ряд важных свойств - например, предопределенные табличные части (вытесняющие, ведущие и базовые виды расчета), возможность ввода в конфигураторе предопределенных видов расчета и др.). Элементы плана видов расчета называют видами расчетов.
Также представим, что регистр накопления «Зарплата» мы
преобразовали в похожий объект и назвали его регистром расчета
(перед этим также добавив «регистру накопления» ряд важных
свойств (полей), например, период регистрации, период действия,
базовый период, фактический период действия (нечто похожее на
подчиненный справочник), вид расчета (тип
ПланВидовРасчетаСсылка...), перерасчеты и др.).
Все эти новые свойства «плана видов расчета» и «регистра расчета» обеспечивают возможность реализации расчетной задачи практически любой сложности гораздо меньшими усилиями.
Назовем рассмотренную схему Решением 1. Потому что в системе «1С:Предприятие 8.0» существует возможность реализовать поставленную задачу еще одним способом (назовем это Решением 2).
10
В документе реквизитам типа «СправочникСсылка...» изменили тип на «ПланВвдовРасчетаСсылка...». Документ при проведении вводит в регистр записи.
Решение задачи
Специфика Решения 2 состоит в том, что и планов видов расчета, и регистров расчета в системе «1С:Предприятие 8.0» может быть много (их количество не ограничено).
Различающиеся по структуре учета начисления и удержания отражаются в разных регистрах расчета.
При этом каждый регистр расчета связан со «своим» планом видов расчета. Свойства объектов обеспечивают взаимное влияние записей
раЗНЫХ регистров расчета. План видов расчета Начисления и удержания!

Принципиальная разница между решениями в том, что в первом случае, когда в одном регистре расчета ведется учет разных по своей структуре начислений и удержаний, для каких-то из них регистр расчета будет «избыточен» по своим возможностям. Во втором решении таких проблем нет.
Рассмотрим каждое из рассмотренных решений задачи подробнее.
11
Решение 1. Один план видов расчета и один регистр расчета
Планы видов расчета. План видов расчета ВсеВидыРасчета
Планы видов расчета предназначены для описания множеств однотипных видов расчета. Под видами расчета подразумеваются начисления, удержания и выплаты. Виды расчета являются элементами плана видов расчета.
Замечание. План видов расчета чем-то напоминает совокупность всех видов расчета версии 7.7. Однако Виды расчета версии 7.7 это объекты конфигурации, а виды расчета версии 8.0 - это данные, объекты базы данных. Отличий между видами расчетов версий 7.7 и 8.0 много, рассмотрим их по ходу решения задачи...
Рассмотрим объект план видов расчета на примере плана видов расчета «ВсеВидыРасчета».
Основные свойства плана видов расчета
Создадим новый план видов расчета и зададим его основные свойства:
- Имя: «ВсеВидыРасчета»,
- Реквизиты: «Тип» (тип
«ПеречислениеСсылка.ТипыВидовРасчета»).
Параллельно создадим новое перечисление «ТипыВидовРасчета».
Перечисление ТипыВидовРасчета
Определим три значения перечисления:

Замечание. К Начислениям будем относить виды расчета Оклад, ПремияПроцентом и Отпуск, к Удержаниям Штраф, а к Выплатам Выплата (этот вид расчета не относится ни к начислениям, ни к удержаниям).
Расчетные свойства плана видов расчета
На закладке Расчет уточняются три свойства плана видов расчета:
Используют ли виды расчета плана видов расчета период действия. Если предполагается, что хотя бы один вид расчета в
13
Конфигурирование в системе "1С: Предприятие 8.0". Решение расчетных задач
плане будет обладать свойством действовать какой-то период времени, т.е. будет отражать то или иное начисление (или удержание) за работу (услуги или др.) в определенный период времени, то признак необходимо установить. Например, начисления фиксированной суммой в этом смысле не отражают оплату работы в определенные дни, а оклад, наоборот, начисляется за работу на протяжении какого-то отрезка времени.
- Используют ли виды расчета плана видов расчета расчетную
базу. Признак зависимости от базы считается установленным,
если выбран переключатель, отличный от Не зависит. Признак
зависимости от базы устанавливается, если предполагается, что
хотя бы один вид расчета в плане будет иметь расчетную базу.
Например, премия процентом имеет расчетную базу - базой
являются те виды расчетов, от которых будет браться процент.
При этом существует возможность установить зависимость от
базы как Зависимость по периоду действия или Зависимость по
периоду регистрации. Отличие этих понятий друг от друга
состоит в том, что признак Зависит по периоду действия
предполагает, что в дальнейшем при определении расчетной
базы для записи регистра расчета будут учитываться только те
записи, у которых Период действия попадает в базовый период.
Признак Зависит по периоду регистрации предполагает, что в
дальнейшем при определении расчетной базы для записи
регистра расчета будут учитываться только те записи, у которых
Период регистрации попадает в базовый период. Понятия
Период действия и Период регистрации (а также Базовый
период) рассмотрим чуть позже.
- Если установлен признак Зависимость от базы отличный от Не
зависит, то уточняются базовые планы видов расчета (те планы
видов расчета, которые будут содержать виды расчета,
попадающие в расчетные базы видов расчета текущего плана).
Установим признаки как показано на картинке.

14
Решение задачи
Формы плана видов расчета
Планы видов расчета могут иметь формы: формы списка, формы выбора и формы вида расчета.

И ФормуВидаРасчета.
Создадим Форму Списка.

На форме вида расчета разместим командную панель с закладками Основное и Виды расчета. Через меню «Форма» - «Размещение данных» поместим на закладке Основное реквизит Тип, а также поля Код и Наименование.
На закладке Виды расчета разместим предопределенные табличные части плана видов расчета и флажок Базовый период как период действия как отображено на картинке.
Предопределенные табличные части плана видов расчета
Планы видов расчета содержат следующие предопределенные табличные части:
Базовые виды расчета,
15
- Вытесняющие виды расчета,
- Ведущие виды расчета.
Базовые виды расчета
В табличной части Базовые виды расчета указываются виды расчета, которые определяют состав расчетной базы текущего вида расчета (например, для «ПремияПроцентом» базовым видом расчета является «Оклад»).
Доступность этой табличной части определяется признаком Зависимость от базы если зависимость от базы в плане видов расчета не определена, то понятие базовые виды расчетов теряет смысл.
Если в конфигурации задано несколько Планов видов расчета, то в качестве базовых можно указать и виды расчета из других планов видов расчета (этот момент мы рассмотрим позже).
Вытесняющие виды расчета
В табличной части Вытесняющие виды расчета указываются виды расчета, которые обладают способностью «вытеснять» текущий вид расчета. Вытесняющими являются такие расчеты, которые взаимно исключают друг друга по периоду действия и система должна гарантировать, что ввод одного из них приведет к исключению другого. Например, Оклад будет вытесняться видом расчета Отпуск, т.к. формально нельзя одновременно работать и быть в отпуске. В результате ввода в регистр расчета учетных записей с конкурирующими за период действия видами расчета, складывается некоторый итоговый период действия каждой учетной записи (фактический период действия).
Вытесняться могут только виды расчета, принадлежащие одному плану видов расчета.
Доступность этой табличной части определяется признаком Использует период действия если период действия в плане видов расчета не используется, то понятие вытесняющие виды расчетов теряет смысл.
Понятие «вытеснение» рассмотрим позже.
Ведущие виды расчета
В табличной части Ведущие виды расчета указываются виды расчета, при вводе (иди изменении) которых результат текущего вида расчета должен быть пересчитан (например, «Оклад» является ведущим видом расчета для «ПремияПроцентом»).
16
Решение задачи
В процессе перерасчета также задействуется специальный объект (подчиненный объект регистра расчета) Перерасчет (его рассмотрим позже).
Если в конфигурации задано несколько планов видов расчета, то в качестве ведущих можно указать и виды расчета из других планов видов расчета (этот момент мы рассмотрим позже).
Предопределенные виды расчета
Важной чертой плана видов расчетов является возможность задавать предопределенные виды расчета на стадии разработки конфигурации.
Предопределенные данные вводятся в отдельном окне, вызываемом по кнопке «Предопределенные» на закладке Прочее (еще для вызова предопределенных видов расчета можно пользоваться кнопкой «Действия» или через контекстное меню из дерева конфигурации. Также есть соответствующая гиперссылка в палитре свойств). Эти виды расчета не могут быть удалены пользователями в режиме исполнения.

17
Создайте следующие предопределенные виды расчета и определите их свойства:
Конфигурирование в системе " 1С: Предприятие 8.0". Решение расчетных задач
Окно редактирования предопределенного вида расчета выглядит так:

Заполним всем предопределенным видам расчета табличную часть Базовые виды расчета следующими данными:

Остальные табличные части заполним позже.
Виды расчета - объекты информационной базы
Откройте план видов расчета «ВсеВидыРасчета» в режиме «С:Предприятие».
Вы увидите список записей, каждую из которых принято называть видом расчета.
Вид расчета это объект данных, хранимый в информационной базе (так же как и элемент справочника, счет в плане счетов и т.д.).
Замечание. Можно создавать в режиме исполнения новые виды расчета (в 7.7 такого не было).
Создадим в режиме исполнения новый вид расчета «Премия к юбилею».
18

Решение задачи
Обратите внимание на отличие пиктограмм предопределенных и введенных пользователем видов расчета. Пиктограммы предопределенных видов расчета (как и пиктограммы любых предопределенных элементов) отличаются жирной точкой в правом
нижнем углу.
Замечание. В режиме исполнения можно отредактировать предопределенные табличные части (базовые, ведущие и вытесняющие), добавив туда новые значения. При этом значения, заданные в конфигураторе удалить нельзя.
Регистры расчета
Объекты регистры расчета служат для накопления информации о периодических расчетах.
Свойства регистра расчета
Создадим новый регистр расчетов «РасчетыВсе». Основные свойства:
- Имя: «РасчетыВсе»,
- Вид расчета: «ВсеВидыРасчета». Это свойство
определяет связь регистра расчетов с планом видов
расчета. Регистр расчета может быть связан только с
одним планом видов расчета (кстати, план видов расчета
может быть связан с несколькими регистрами расчета).
Эта привязка фактически определяет тип поля
«ВидРасчета» регистра расчета как
«ПланВидовРасчетаСсылка.ВсеВидыРасчета».
19
Полный набор свойств записи регистра расчета посмотрите в Синтаксис -Помощнике:

Периодичность: Месячный. Это свойство определяет период, с которым регистрируются движения регистра и в пределах которого движения могут влиять друг на друга по периоду действия (для регистров, поддерживающих период действия).

Период действия: установить флажок. Флажок
устанавливаем, т.к. в регистре расчета будут храниться
записи с «Окладом». Этот флажок (свойство) определяет
доступность свойств записи регистра расчета:
ПериодДействия, ПериодДействияНачало,
ПериодДействияОкончание, а также доступность свойства График регистра расчета.
Базовый период: установить флажок. Флажок устанавливаем, т.к. в регистре расчета будут храниться записи с «ПремиейПроцентом». Этот флажок (свойство)
20
Решение задачи
определяет доступность свойств записи регистра расчета: БазовыйПериодНачало, БазовыйПериодОкончание.
Разберемся подробней со следующими свойствами записи регистра расчета:
- ПериодРегистрации,
- ПериодДействияНачало,
- ПериодДействияОкончание,
- ПериодДействия,
- БазовыйПериодНачало,
- БазовыйПериодОкончание.
Период регистрации
Под периодом регистрации подразумевается дата, соответствующая периоду, в котором текущая запись была введена в регистр расчета.
Период регистрации - это дата, которая принимает дискретные значения в зависимости от периодичности регистра расчета. В нашем случае, т.к. регистр помесячный, то дата всегда начало какого-нибудь месяца.
Определяется период регистрации в момент ввода информации в регистр из документа-регистратора.
Период действия: ПериодДействияНачало,
ПериодДействияОкончание. Свойство ПериодДействия
Каждая запись регистра расчета характеризуется понятием период действия записи. Период действия записи определяется свойствами записи (точнее свойствами объекта РегистрРасчетаЗапись.о) ПериодДействияНачало и ПериодДействияОкончание.
ПериодДействияНачало - это дата начала периода действия записи. ПериодДействияОкончание - это дата окончания периода действия.
Существует еще одно свойство объекта РегистрРасчетаЗапись.о -ПериодДействия.
Замечание. Тут не должно возникнуть путаницы. Понятие «период действия», определяемое свойствами ПериодДействияНачало и ПериодДействияОкончание объекта РегистрРасчетаЗапись.о и свойство ПериодДействия объекта РегистрРасчетаЗапись.о - это разные вещи.
Свойство ПериодДействия - это дата, которая принимает дискретные
значения в зависимости от периодичности регистра расчета. Значение
свойства ПериодДействия приводится к началу периода (в нашем
случае месяца) от даты ПериодДействияНачало.
ПериодДействияНачало может и не совпадать со значением свойства ПериодДействия (например, когда запись действует с 10.01.03 по
21
20.01.03, ЛериодДействияНачало будет равен 10.01.03, а ПериодДействия - 01.01.03).
Период действия записи (задаваемый датой начала и датой окончания) может не совпадать с фактическим периодом действия, который в общем случае является набором нескольких непересекающихся временных интервалов (это рассмотрим позже в разделе ФактическийПериодДействия). Период действия записи, задаваемый датой начала и датой окончания можно еще назвать планируемым периодом действия (запись стремится занять этот интервал).
Замечание. В 7.7 период действия имел тип «период журнала расчетов», а в 8.0 это дата.
Базовый период
Базовый период это интервал дат, определяемый свойствами БазовыйПериодНачало и БазовыйПериодОкончание, в котором лежат записи регистра расчета, входящие в состав расчетной базы текущей записи регистра расчета.
БазовыйПериодНачало - дата начала базового периода записи регистра.
БазовыйПериодОкончание - дата окончания базового периода записи регистра.
В качестве примера базового периода действия можно привести базовый период вида расчета «Отпуск», который, как правило, представляет собой интервал дат, лежащий в трех месяцах, предшествующих месяцу, в котором Отпуск был зарегистрирован.
Представим рассмотренные понятия в виде схемы на примере «Отпуска», введенного в апреле и действующего с 10.04 по 20.05.
22
Решение задачи
Замечание 1. На представленной схеме следует внимательней
отнестись к понятиям «период действия» и «ПериодДействия». Под
«периодом действия» понимается период действия начисления или
удержания, в примере начисление отпуск действует с 10.04 по 20.05.
«ПериодДействия» это свойство объекта
РегистрРасчетаЗапись.имя. Это свойство всегда определяется свойством «ПериодДействияНачало» и всегда совпадает с датой начала периода, в котором лежит «ПериодДействияНачало».
Частичное попадание записей регистра расчета в базовый период
На представленной выше схеме рассмотрен достаточно простой пример, в котором базовый период кратен периоду регистра расчета (в нашем случае месяц). Рассмотрим случай, когда, базовый период не кратен периоду регистра расчета. Например, существует какая-нибудь "особая" премия (действующая в мае), которая имеет базовый период с 15.04.2003 по 15.04.2003 (для примера также можно привести следующие варианты базовых периодов: 2 последних недели, первая и последняя неделя предыдущего месяца, два последних дня, понедельники, и т.д.). При получении базы система должна сложить результаты всех записей, попавших в этот период.
Очевидно, что может возникнуть ситуация, когда записи будут лежать в рассмотренном базовом периоде не полностью, а «частично» Конечно, речь идет только о тех записях, которые содержат виды расчета, заданные в плане видов расчета в качестве базовых для данной премии. Для определенности предположим, что «особая» премия в качестве базового вида расчета содержит «Оклад».
Попасть в базовый период записи могут «по периоду регистрации» или «по периоду действия».
Рассмотрим первый случай, когда записи попадают в базовый период по периоду регистрации. В этом случае в плане видов расчета,
23
Конфигурирование в системе "1 С: Предприятие ^0"'. Решение расчетных задач
связанном с регистром расчета, должен быть установлен признак «Зависит по периоду регистрации».
Напомним, что период регистрации - это всегда конкретная дата, соответствующая началу периода регистра расчета. Если период регистрации (т.е. конкретная дата) не попадает в базовый период, то эта запись не будет учтена при расчете базы. То есть, если установлена зависимость базы по периоду регистрации, то «частичных» результатов не будет: или запись будет целиком учтена, или целиком не учтена.
В нашем случае в базовый период «особой» премии не попадет ни одна запись, поскольку период с 15.04.2003 по 15.04.2003 не охватывает ни одну дату начала периода регистра расчета.
Представим рассмотренные понятия в виде схемы.

Рассмотрим второй случай, когда записи попадают в базовый период по периоду действия. В этом случае в плане видов расчета, связанном с регистром расчета, должен быть установлен признак «Зависит по периоду действия».
Напомним, что период действия - это интервал дат, определяемый свойствами ПериодДействияНачало и ПериодДействияОкончание.
Если какая-то запись целиком попадает в базовый интервал, то сложностей нет - берем ее результат целиком.
Если же какая-то запись попадает в базовый интервал только частично, то неправомерно брать ее результат целиком. В то же время совсем ее не учитывать тоже нельзя. Значит нужно как-то определить, какая часть результата должна быть взята при расчете базы. Чтобы придать «дискретность» таким результатам существует понятие «График».
График - это непериодический регистр сведений, который задает «веса» для каждого дня (а может быть даже для каждого часа). Например, в графике указаны продолжительности каждого дня в часах - пн-чт - 8 часов, пт-7 часов, сб-вс - 0 часов. Если регистр расчета поддерживает период действия (основан на соответствующем плане видов расчета), то ему обязательно должен быть указан график (свойство Трафик регистра расчета мы рассмотрим ниже).
24
Решение задачи
Используя сведения графика, можно посчитать, какая часть всего результата «базовой записи» приходится на каждый день, и взять только те дни, который попали в базовый период.
Например, сумма по окладу в апреле была 1000 руб. Если базовый период майской «особой» премии определен с 15.04.2003 по 15.04.2003, то от суммы по окладу будет взята только часть результата (45.45 = 1000/22, где 22 - количество рабочих дней по пятидневке).
Представим рассмотренные понятия в виде схемы.

Замечание. На данной схеме предполагается, что период действия оклада совпадает с фактическим периодом действия (понятие фактический период действия рассмотрим ниже).
Свойство График регистра расчета
Разберемся со свойством График регистра расчета. Перед тем, как устанавливать это свойство нам придется создать, как минимум, еще один объект - регистр сведений «Графики работы».
Это связано с тем, что свойство График регистра расчета представляет собой ссылку на регистр сведений, в котором описывается временная схема исходных данных, участвующих в расчете.
График следует указывать для тех расчетов, которые зависят от исходных данных, распределенных в пределах периода действия по определенному правилу. Например, это может быть график учета рабочего времени организации с разбивкой по дням или часам, учет лекционных часов с разбивкой по часам и т.д.
В нашем случае для реализации возможности создания и заполнения в режиме исполнения произвольного количества любых графиков, создадим справочник «ГрафикиРаботы» и регистр сведений «ГрафикиРаботы».
25
Конфигурирование в системе " 1С: Предприятие 8.0". Решение расчетных задач
Справочник «ГрафикиРаботы»
Создадим справочник «ГрафикиРаботы». В данный справочник будем заносить названия и типы графиков работы, используемых в организации. Кроме того, реализуем возможность автоматического заполнения графиков работы с учетом выходных дней прямо из формы элемента справочника.
Основные свойства справочника:
Имя «ГрафикиРаботы», Реквизиты:
о ТипГрафика тип
«ПеречислениеСсылка.ТипыРабочихГрафиков». Создадим перечисление «ТипыРабочихГрафиков» со значениями:

Формы:
о ВыходныеДни типа Строка длиной 7 символов. Сюда будем записывать порядковые номера выходных дней недели.
о ФормаСписка

26
Решение задачи
Рассмотрим подробно процесс создания элементов диалога.
- Вставим в форму элемента реквизиты Код, Наименование,
ТипГрафика.
- Создадим на закладке Реквизиты новый реквизит с именем
Календарь и определим его тип:
«РегистрСведенийСписок.ГрафикиРаботы».
Создадим новый регистр сведений «ГрафикиРаботы». В регистре сведений будем хранить информацию о датах календарей и значениях на дату. В качестве значений будем указывать 1 (единицу), что будет показывать, что день является рабочим. Свойства регистра сведений определим позже.
- Вставим элемент управления Табличное поле и зададим ему
имя ТабличноеПолеКалендаря. Свяжем Табличное поле с реквизитом
Календарь. В разделе свойств Использование табличного поля
установите флажок Только просмотр.
- Вставим элемент управления Поле списка с именем
ДниНедели. На закладке Использование поставим флажок
Отображать пометку. Тип значения поле списка СписокЗначений.
Будем заполнять список значений перечнем дней недели и напротив выходных дней будем ставить пометку.
27
Замечание. СписокЗначений - это объект, который можно представить себе как таблицу вида:
Конфигурирование в системе "1С:Предприятие 8.0". Решение расчетных задач
Заполнять список будем в момент открытия формы. Поэтому назначим обработчик события формы ПриОткрытии и в модуле формы поместим следующее:
Процедура ПриОткрытии()
ТекущийДень = НачалоНедели(ТекущаяДата()); // начнем с понедельника сДлинаСуток = 86400; // в секундах Для Сч = 1 По 7 Цикл
НазваниеДняНедели = Формат(ТекущийДень,"ДФ=дддд");
ДниНедели.Добавить(Строка(ДеньНедели(ТекущийДень)),Врег(Лев(НазваниеДняН едели, 1 ))+Сред(Название ДняНедели,2));
ТекущийДень = ТекущийДень + сДлинаСуток; КонецЦикла;
// расставляем пометки для выходных дней графика Для Сч = 1 По СтрДлина(ВыходныеДни) Цикл
ДниНедели.НайтиПоЗначению(Сред(ВыходныеДни,Сч,1)).Пометка =
Истина;
КонецЦикла;
//выставляем отбор в списке дней календаря (регистр сведений):
// отбираем дни нашего графика
Календарь.Отбор.ГрафикРаботы.Значение = Ссылка;
Календарь.Отбор.ГрафикРаботы.Использование = Истина;
// отбираем дни текущего месяца
УстановитьОтборВКалендаре(НачалоМесяца(ТекущаяДата()), КонецМесяца(ТекущаяДата()));
КонецПроцедуры
Процедура
УстановитъОтборВКалендаре(ДатаНачалаИнтервалаКалендаря,ДатаОкончанияИнтервалаК алендаря)
Календарь. Отбор. Дата.ЗначениеС = ДатаНачалаИнтервалаКалендаря; Календарь.Отбор.Дата.ЗначениеПо = ДатаОкончанияИнтервалаКалендаря;
Если обЗначениеНеЗаполнено(ДатаНачалаИнтервалаКалендаря) и
обЗначениеНеЗаполнено(ДатаОкончанияИнтервалаКалендаря) Тогда
Календарь.Отбор.Дата.Использование = Ложь; Иначе Если обЗначениеНеЗаполнено(ДатаНачалаИнтервалаКалендаря) Тогда
Календарь.Отбор.Дата.ВидСравнения =
ВидСравнения.МеньшеИлиРавно;
ИначеЕсли обЗначениеНеЗаполнено(ДатаОкончанияИнтервалаКалендаря)
Тогда
Календарь.Отбор.Дата.ВидСравнения =
ВидСравнення.БольшеИлиРавно;
Иначе
28
Решение задачи
Календарь.Отбор.Дата.ВидСравнения ВидСравнения.ИнтервалВключаяГраницы;
КонецЕсли;
Календарь.Отбор.Дата.Использование = Истина; КонецЕсли; КонецПроцедуры
Комментарии.
Заполняем список с пометками названиями дней недели, начиная с понедельника. В качестве значения указываем порядковый номер дня недели, а в качестве представления - представление даны в формате "ДФ=дддд" (такой формат означает представление даты в виде строкового названия дня недели).
Замечание. Обратите особое внимание на то, что для перехода на следующую дату к текущей дате необходимо прибавить 86400 секунд (60*60*24), т.к., если к дате прибавлять число, то это число воспринимается как число секунд.
После заполнения списка датами, устанавливаем пометки. Признаки пометок хранятся в реквизите ВыходныеДни (тип Строка длиной 7) в виде номера дня недели, который является выходным. Поэтому анализируем строку ВыходныеДни, и отмечаем в списке значения, соответствующие выходным, пометками.
Затем через реквизит Календарь (тип
РегистрСведений.ГрафикиРаботы.Ссылка) обращаемся к регистру сведений ГрафикиРаботы и устанавливаем отбор в регистре по текущему элементу справочника ГрафикиРаботы. Напомним, что в регистре хранятся даты и значения по всем возможным календарям, созданным в справочнике ГрафикиРаботы, поэтому и необходимо установить отбор. В качестве интервала просмотра выбираем даты начала и окончания текущего месяца.
Механизм установки отбора в регистре сведений ГрафикиРаботы по
интервалу дат реализован в процедуре
УстановитъОтборВКалендаре(). Мы будем вызывать алгоритм установки отбора по интервалу дат из нескольких мест модуля, поэтому и выделяем этот процесс в отдельную процедуру. В процедуре УстановитьОтборВКалендаре() производим анализ заполненности значений начала и окончания интервала дат. В зависимости от варианта, выбираем тот или иной вид сравнения для установки отбора.
Кроме того, в процедуре УстановитъОтборВКалендаре() задействуется функция обЗначениеНеЗаполнено(). Данная функция является универсальным средством для анализа заполненности переданного значения. Вставим функцию обЗначениеНеЗаполнено() в общий модуль СтандартныеПроцедуры
Функция обЗначениеНеЗаполнено(Значение) Экспорт
шрование в системе " 1С:ПЈедприятие^8.0". Решение^асчетных задач
Результат = Ложь;
ТипЗначения = ТипЗнч(Значение);
// Сначала примитивные типы
Если Значение = Неопределено Тогда
Результат = Истина; ИначеЕсли Значение = NULL Тогда
Результат = Истина; ИначеЕсли ТипЗначения = Тип("Строка") Тогда
Если СокрЛП(Значение) = "" Тогда Результат = Истина;
КонецЕсли; ИначеЕсли ГипЗначения = Тип("Число") Тогда
Если Значение = 0 Тогда
Результат = Истина;
КонецЕсли; ИначеЕсли ТипЗначения = Тип("Дата") Тогда
Если Значение = Дата('00010101') Тогда Результат = Истина;
КонецЕсли; ИначеЕсли ГипЗначения = Тип("Булево") Тогда
Результат = Ложь; // Булево будем считать не пустым // Для остальных будем считать значение пустым, если оно равно // дефолтному значению своего типа Иначе
Если Значение = Новый(ТипЗначения) Тогда Результат = Истина;
КонецЕсли; КонецЕсли;
Возврат Результат; КонецФункцнн
Комментарии.
В данной функции проверяется, заполнено ли передаваемое в функцию значение или нет. Производится анализ всех примитивных и отличных от примитивных типов данных.
Создадим программный код, связывающий значения поля списка Дни недели с реквизитом справочника ВыходныеДни. Для этого назначим обработчик события При изменении флажка элемента управления ДниНедели и создадим в модуле формы процедуру ДниНеделиПриИзмененииПометки():
Процедура ДниНеделиПриИзмененииПометки(Элемент)
30
Решение задачи
ЭлементСписка = Элемент. ТекущаяСтрока; Если ЭлементСписка.Пометка Тогда
Если Найти(ВыходныеДни,ЭлементСписка.Значение) = 0 Тогда ВыходныеДни = ВыходныеДни+ЭлементСписка.Значение
КонецЕсли; Иначе
ВыходныеДни=СтрЗаменить(ВыходныеДни,ЭлементСписка.Значение,""); КонецЕсли; КонецПроцедуры
Комментарии.
Добираемся до текущей строки списка значений и, если в текущей строке списка установлена пометка, добавляем в реквизит «ВыходныеДни» номер соответствующего дня недели. Если пометка не установлена, то и в реквизите «ВыходныеДни» удаляем ссылку на соответствующий день недели.
- Вставим элемент управления Командная панель с именем
КоманднаяПанельКалендаря. В качестве источника действий укажем
элемент управления ТабличноеПолеКалендаря.
- На панели КоманднаяПанельКалендаря создадим две
кнопки:
о «Интервал», действие:
ИзменитъИнтервалПоказаКалендаръ. При
нажатии на эту кнопку будет открываться диалог, в котором будем уточнять интервал просмотра записей в табличном поле, связанном с регистром сведений ГрафикиРаботы.
о «Заполнить», действие:
КоманднаяПанельКалендаряЗаполнить. При
нажатии на эту кнопку будем производить заполнение календаря за указанный интервал дат.
7. В модуль формы вставим соответствующие процедуры-
обработчики событий:
о ИзменитьИнтервалПоказаКалендаря()
Процедура ИзменитьИнтервалПоказаКалендаря()
ИнтервалПоказа = Новый НастройкаПериода(); ИнтервалПоказа.ДатаНачала = Календарь.Отбор.Дата.ЗначениеС;
ИнтервалПоказа.ДатаОкончания = Календарь.Отбор.Дата.ЗначениеПо; ИнтервалПоказа.ВариантНачала = ВариантГраницыИнтервала.КонкретнаяДата; ИнтервалПоказа.ВариантОкончания = ВариантГраницыИнтервала.КонкретнаяДата; Если ИнтервалПоказа.Редактировать() Тогда
УстановитьОтборВКалендаре(ИнтервалПоказа.ПолучитьДатуНачала(),ИнтервалПо
каза.ПолучитьДатуОкончания());
31
Конфигурирование системе "1С:Предприятие 8.0". Решение расчетных задач
КонецЕслн; КонецПр» цедуры
Комментарии.
Сначала готовим объект для выбора интервала (создаем объект НастройкаПериода), затем вызываем диалог для выбора интервала (ИнтервалПоказа.РедактироватъО) и обращаемся к процедуре УстановитьОтборВКалендаре() для установки назначенного отбора по датам в регистре расчетов ГрафикиРаботы.
о КоманднаяПанелъКалендаряЗаполнитъ()
Процедура КоманднаяПанельКалендаряЗаполнить(Кнопка) ЕслиЭтоНовый() Тогда
Предупреждение("Перед заполнением график необходимо записать!");
Возврат; КонещЕсли;
ИнтервалПоказа = Новый НастройкаПериода(); ИнтервалПоказа.ДатаНачала = Календарь.Отбор.Дата.ЗначениеС; ИнтервалПоказа.ДатаОкончания = Календарь.Отбор.Дата.ЗначениеПо; ИнтервалПоказа.ВариантНачала = ВариантГраницыИнтервала.КонкретнаяДата; ИнтервалПоказа.ВариантОкончания = ВариантГраницыИнтервала.КонкретнаяДата; // Вызываем диалог для выбора интервала Если ИнтервалПоказа.Редактировать() Тогда
ЗалолнитьКалендарьЗаИнтервал(ИнтервалПоказа); Иначе
Воз врат; КонецЕсли; КонецПроцедуры
Комментарии.
В данной процедуре проверяем, записан ли текущий элемент
справочника, (должен быть записан). Затем еще раз уточняем интервал
выбора даг (вызываем диалог для выбора интервала) и, если интервал
дат установлен, вызываем процедуру
ЗаполнитъКалендаръЗаИнтервал(ИнтервалПоказа), в которой и
заполняем регистр сведений «ГрафикиРаботы» в соответствии с
назначенными условиями. Процедуру
ЗаполнитьКалендаръЗаИнтервал() рассмотрим ниже.
8. Процедуру ЗаполнитьКалендарьЗаИнтервал() разместим в модуле объекта (поставим в строку объявления процедуры ключевое слово Экспорт, чтобы процедура заполнения календарей была доступна не только из модуля объекта):
Процедура ЗаполнитьКалендарьЗаИнтервал(Интервал) Экспорт сДлинаСуток = 86400; // в секундах
32
Решение задачи
ДатаНачалаИнтервала = Интервал,ПолучитьДатуНачала(); ДатаОкончанияИнтервала = Интервал.ПолучитьДатуОкончания(); ТекущийДень = ДатаНачалаИнтервала;
НаборЗаписейКалендарь РегистрыСведений.ГрафикиРаботы.СоздатьНаборЗаписей();
НаборЗаписейКалендарь.Отбор.ГрафикРаботы.Значение = Ссылка; НаборЗаписейКалендарь.Отбор.ГрафикРаботы.Использование = Истина; НаборЗаписейКалендарь.Прочитать();
ЗаписейВНаборе = НаборЗаписейКалендарь.Количество()-1;
Для инд = 0 по ЗаписейВНаборе Цикл
ДеньКалендаря = НаборЗаписейКалендарь[инд];
Если ДеньКалендаря.Дата ДатаНачалаИнтервала Тогда
Продолжить ИначеЕсли ДеньКалендаря.Дата = ТекущийДень Тогда
Если ДеньЯвляетсяРабочим(ТекущийДень) Тогда
ДеньКалендаря.Значение = 1;
Иначе
ДеньКалендаря.Значение = 0;
КонецЕсли;
ТекущийДень = ТекущийДень + сДлинаСуток; Иначе
Пока ТекущийДень
Мин(ДеньКалендаря.Дата,ДатаОкончанияИнтервала) Цикл
НовыйДень = НаборЗаписейКалендарь. Добавить(); НовыйДень.ГрафикРаботы = Ссылка; НовыйДень.Дата = ТекущийДень; Если ДеньЯвляетсяРабочим(ТекущийДень) Тогда
НовыйДень.Значение =
1;
Иначе
НовыйДень. Значение =
0;
КонецЕсли;
ТекущийДень = ТекущийДень + сДлинаСуток; КонецЦикла;
Если ДеньКалендаря.Дата ДатаОкончанияИнтервала Тогда
Прервать ИначеЕсли ДеньЯвляетсяРабочим(ТекущийДень) Тогда
ДеньКалендаря.Значение =
1;
Иначе
33
ДеньКалендаря.Значение =
0;
КонецЕсли;
ТекущийДень = ТекущийДень + сДлинаСуток; КонецЕсли;
КонецЦикла;// по записям набора Пока ТекущийДень ДатаОкончанияИнтервала Цикл
НовыйДень = НаборЗаписейКалендарь.Добавить();
НовыйДень.ГрафикРаботы = Ссылка;
Если ДеньЯвляетсяРабочим(ТекущийДень) Тогда
НовыйДень.Значение = 1;
Иначе
НовыйДень.Значение = 0;
КонецЕсли;
НовыйДень.Дата = ТекущийДень;
ТекущийДень = ТекущийДень + сДлинаСуток; КонецЦикла;
НаборЗаписейКалендарь.Записать(); КонецПроцедуры
Функция ДеньЯвляетсяРабочим(ПроверяемаяДата)
Возврат ?(Найти(ВыходныеДни,Строка(ДеньНедели(ПроверяемаяДата))) 0,Ложь,Истина);
КонецФункции
Комментарии.
Создаем новый набор записей в регистре сведений «ГрафикиРаботы» и заполняем реквизиты «Дата» и «Значение» в соответствии с установленным в форме интервалом (в реквизит Значение устанавливаем 1, которая будет показывать, что день является рабочим). Выходные дни устанавливаем в соответствии со значением реквизита «ВыходныеДни» справочника «ГрафикиРаботы».
Регистр сведений «ГрафикиРаботы»
Назначим основные свойства регистра:
- Имя «ГрафикиРаботы»,
- Периодичность: непериодический. Определяем свойство
именно так, т.к. мы не будем хранить в регистре историю
изменения значений, а будем определять временную
(ударение на «у») схему,
- Режим записи: независимый (для заполнения графика не
будем использовать никаких специальных документов).
Измерения:
34
Решение задачи ТИП
Ресурсы:
о «ГрафикРаботы»
«СправочникСсылка.ГрафикиРаботы». о «Дата» типа Дата.
о «Значение» типа Число длиной 5, точностью 2.
Запустите конфигурацию в режиме исполнения, создайте новый график Основной график типа Пятидневка и заполните график за весь 2003 год.

Связь Регистра расчетов с графиком работы
Теперь мы можем назначить свойству График значение регистра сведений «ГрафикиРаботы».
Кроме этого необходимо заполнить свойства:
- Значение графика: в качестве значения указывается
ресурс регистра сведений «Значение»,
- Дата графика: в качестве значения указывается измерение
регистра сведений «День».
Замечание. Все свойства регистра расчета, касающиеся графика, доступны, только когда установлен признак Период действия.
35
Конфигурирование в системе "1С:Предприятие 8.0". Решение расчетных задач
Измерения, ресурсы и реквизиты регистра расчетов
Разберемся с остальными свойствами регистра расчета. Измерения:
- «Подразделение» тип
«СправочникСсылка.Подразделения»;
- «Должность» тип «СправочникСсылка.Должности»;
- «Сотрудник» тип «СправочникСсылка.ФизическиеЛица»;
Ресурсы:
«Результат» тип Число длиной 10 разрядов точностью 2;
Реквизиты:
«График» тип данных
«СправочникСсылка.ГрафикиРаботы». В разделе свойств Расчет данного реквизита заполним поле Связь с графиком значением «ГрафикРаботы» как показано на рисунке.

Как видно на рисунке, существует возможность связать реквизит регистра расчетов с одним из измерений ресурса сведений, который выступает в качестве графика для данного регистра расчета. Такая связь понадобится в дальнейшем, например, для корректного получения с помощью метода ПолучитьДанныеГрафика() регистра расчета количества отработанных по графику дней. Дело в том, что в регистре сведений «ГрафикиРаботы» хранятся все возможные графики работы, а в реквизит «График» регистра расчетов будет записываться ссылка на конкретный график работы. Соответственно метод
36
Решение задачи
ПолучитьДанныеГрафика() будет автоматически вычислять количество отработанных дней по указанному в реквизите «График»
значению.
«ПараметрРасчета» тип Число длиной 10 точностью 2.
Формы регистра расчетов
Создадим форму списка регистра расчета.

Работа с планами видов расчета и регистрами расчета из встроенного языка
Для работы с планами видов расчета и регистрами расчета используют следующие объекты встроенного языка.
37
Конфигурирование в системе " 1С:Предприятие 8.0". Решение расчетных задач

Представим основные свойства и методы данных объектов в виде таблиц.
38
Решение задачи
Запись видов расчета в регистр расчета. Документ «НачислениеЗарплатыВсей»
Разберемся с тем, каким образом вводить записи в регистр расчета.
Для ввода информации в регистр расчета чаще всего используются
документы.
Создадим документ «НачислениеЗарплатыВсей». Основные свойства:
Имя: «НачислениеЗарплатыВсей». Реквизиты:
о «ПериодРегистрации» тип Дата. Табличные части:
о Список
- «Сотрудник»: тип
«СправочникСсылка. Физические Лица»,
- «Подразделение»: тип
«СправочникСсылка.Подразделения»,
- «Должность»: тип
«СправочникСсылка.Должности»,
- «График»: тип
«СправочникСсылка.ГрафикиРаботы»,
- «ВидРасчета»: тип
«ПланВидовРасчетаСсылка.ВсеВидыРасчета
»,
- «ДатаНачала»: тип Дата,
- «ДатаОкончания»: тип Дата,
- «Размер»: тип Число длина 10 точность 2,
- «Сторно»: тип Булево.
Формы:
о ФормаСписка,
о ФормаДокумента.
49
Конфигурирование в системе "1С:Предприятие 8.0". Решение расчетных задач
В форме документа используем возможность переключения даты в поле Период регистрации с помощью кнопок регулирования (на картинке обведены).
В свойствам поля ввода назначим обработчик события Регулирование. В процедуре ПериодРегистрацииРегулирование запишем следующее.
Процедура ПериодРегистрацииРегулирование(Элемент, Направление,
СтандартнаяОбработка)

// Вставить содержимое обработчика. СтандартнаяОбработка=Ложь; Если Направление = 1 Тогда
ПериодРегистрации = КонецМесяца(ПериодРегистрации)+1; Иначе
ЛериодРегистрации = НачалоМееяца(ПериодРегистрации-1);
КонецЕсли;
КонецПроцедуры
В данной процедуре реализовано переключение дат сразу на месяц вперед или назад. Кроме того, в алгоритме учитывается, что дата периода регистрации в нашем случае всегда будет началом какого-нибудь месяца.
Для облегчения работы с табличной частью формы назначим обработчик события ПриИзменении поля ввода Сотрудник. В приведенном ниже модуле реализовано следующее: при выборе физического лица программа проверит, работает ли в данный момент сотрудник в организации (если не работает, выдаст предупреждение); если сотрудник работает в одном месте, то автоматически заполнятся поля Подразделение и Должность; если работает в нескольких местах - будет выдано диалоговое окно с перечнем мест работы и, после выбора места работы, заполнятся поля Подразделение и Должность.
Процедура СписокСотрудникПриИзменении(Элемент) Запрос = Новый Запрос("
50
Выбрать Сотрудник.Наименование, Подразделение, Должность
Из РегистрСведений.Сотрудники.СрезПоследних(парамДата, Сотрудник = парамСотрудник)
Где Состояние = парамСостояние
I");
Запрос.УстановитьПараметр("парамДата", Дата);
Запрос.УстановитьПараметр("парамСотрудник", Элемент,Значение);
Запрос.УстановитьПараметр("парамСостояние", Перечисления.СостоянияФизлица.Работает);
МестаРаботы = Запрос.Выполнить().Выгрузить(); Если МестаРаботы.Количество()=0 Тогда
Предупреждение(""+Элемент.3начение+" не работает в организации " +Константы.НазваниеОрганизации);
ИначеЕсли МестаРаботы.Количество()=1 Тогда
Подразд = МестаРаботы[0] .Подразделение; ЭлементыФормы.Список.ТекущиеДанные.Подразделение = Подразд;
ЭлементыФормы.Список.ТекущиеДанные.Должность =
МестаРаботы[0].Должность;
Иначе
ВыбраннаяСтрока = МестаРаботы.ВыбратьСтроку("Выберите место работы");
Если ВыбраннаяСтрока о НЕОПРЕДЕЛЕНО Тогда
ЭлементыФормы.Список.ТекущиеДанные.Подразделение =
ВыбраннаяСтрока.Подразделение;
ЭлементыФормы.Список.ТекущиеДанные.Должность =
ВыбраннаяСтрока.Должность;
КонецЕсли; КонецЕсли; КонецПроцедуры
Назначим обработчик события ПриИзменении поля ввода ВидРасчета (поле ввода находится внутри списка). В приведенном ниже модуле реализовано следующее: при выборе вида расчета, если выбранный вид расчета имеет имя Оклад, программа посмотрит в регистре сведений «Сотрудники» оклад сотрудника и автоматически заполнит поле Размер.
Процедура СписокВидРасчетаПриИзменении(Элемент) // Вставить содержимое обработчика.
Если Элемент.Значение=ПланыВидовРасчета.ВсеВидыРасчета.Оклад Тогда Запрос = Новый Запрос(" Выбрать Сотрудник, Подразделение, Должность, Оклад, Регистратор
Из РегистрСведений.Сотрудники.СрезПоследнихСшрамДата,
(Сотрудник = парамСотрудник) и (Подразделение = парамПодразделение) и (Должность = парамДолжность))
Конфигурирование в системе " 1С:Предприятие 8.0". Решение расчетных задач
Запрос.УстановитьПараметр("парамДата", Дата);
Запрос.УстановитьПараметр("парамСотрудник",
ЭлементыФормы.Список.ТекущиеДанные.Сотрудник);

Запрос.УстановитьПараметр("парамПодразделение", ЭлементыФормы.Список.ТекущиеДанные.Подразделение);
Запрос.УстановитьПараметр("парамДолжность", ЭлементыФормы.Список.ТекущиеДанные.Должность);
ТЗОклад = Запрос.Вьшолнить().Выгрузить(); Если ТЗОклад.Количество()оО Тогда ОкладВСписок= ТЗОклад[0]. Оклад;
Если ТипЗнч(ОкладВСписок)=Тип("Число") Тогда
ЭлементыФормы.Список.ТекущиеДанные.Размер ОкладВСписо к;
ИначеЕсли ТипЗнч(ОкладВСписок)=Тип("СправочникСсылка.ЕТС") Тогда
ЭлементыФормы.Список.ТекущиеДанные. Размер Число(ОкладВСписок.Наименование);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Также установим следующие свойства документа:
- Проведение: Разрешить,
- Движения: РегистрыРасчетов: «РасчетыВсе»,
В модуле документа поместим процедуру-обработчик события ОбработкаПроведения.
Процедура ОбработкаПроведения(Отказ, РежимПроведения) Для Каждого Строка Из Список Цикл
Движение = Движения.РасчетыВсе.Добавить();
Движение.ПериодРегистрации = ПериодРегистрации; Движение. ПериодДействияНачало = Строка.ДатаНачала; Движение.ПериодДействияОкончание = Строка.ДатаОкончания; Движение.Сотрудник = Строка.Сотрудник; Движение.Подразделение = Строка.Подразделение; Движение.Должность = Строка. Должность; Движение.График = Строка.График; Движение.ВидРасчета = Строка.ВидРасчета; Движение.ПараметрРасчета = Строка.Размер; Движение.Сторно = Строка.Сторно; КонецЦикла;
52
Решение задачи
Движения.РасчетыВсе.Записать();
НаборЗаписей = РегистрыРасчета.РасчетыВсе,СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Значение = Ссылка;
Отбор= НаборЗаписей.Отбор;
//можно и так
/Ютбор= Новый Структура("Регистратор",Ссылка);
Ресурсы = Новый Массив(1);
Ресурсы[0] = "РасчетыВсе.Результат";
Измерения= Новый Структура();
Измерения.Вставить("Подразделение","РасчетыВсе.Подразделение");
Измерения.Вставить(" Должность", "РасчетыВсе.Должность");
Измерения,Вставить("Сотрудник","РасчетыВсе.Сотрудник");
ДанныеБазы =
Регистр ыРасчета.РасчетыВсе.ПолучитьБазу(Отбор,Ресурсы,Измерения);
Отработано =
РегистрыРасчета.РасчетыВсе.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета .ФактическийПериодДействия);
Норма =
РегистрыРасчета.РасчетыВсе.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета
. ПериодДействия);
ОтработаноПоБазе =
Регистр ыРасчета.РасчетыВсе.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета .БазовыйПериод);
Для Каждого Движение Из Движения.РасчетыВсе Цикл
Движение.Результат = РассчитатьНачисленияУдержания(Движение, Движения.РасчетыВсе.Индекс(Движение), ДанныеБазы, Отработано, Норма, ОтработаноПоБазе);
КонецЦикла; КонецПроцедуры
Комментарии.
Добавление записи в регистр расчета выполняется также как и в другие регистры - используются методы Добавить и Записать объекта «РегистрРасчетаНаборЗаписей».
После добавления записей в регистр выполняем самое важное действие - рассчитываем результат. Расчет результата будем проводить в общем модуле ПроцедурыРасчетов в процедуре РассчитатьНачисленияУдержания (это мы рассмотрим ниже).
Важно! В случае, если для целей расчета результатов записей регистра расчета нам необходимо получение итогов по базовым записям (или нужен фактический период действия), прежде чем выполнять расчет результатов таких записей, этот набор записей обязательно нужно записать.
Перед вызовом процедуры РассчитатъНачисленияУдержания проводится подготовительный этап, а именно:
53
Конфигурирование в системе "1 С:Предприятие 8.0"- Решение расчетных задач
определяются данные расчетной базы. Для этого
вспользуется метод регистра расчета ПолучитьБазу
(Отбор, Ресурсы, Измерения, Разрезы).
Метод возвращает расчетную базу для записей регистра,
подчиненных заданному регистратору (в нашем случае
конкретному документу «Начисление зарплаты всей»). В
результате работы метода возвращается
ТаблицаЗначений, каждая строка которой содержит автоматически просуммированные результаты расчетов, входящих в базу.
Замечание 1. Обратите внимание на типы данных параметров данного метода (см. описание процедуры в Синтаксис-Помощнике).
Для примера рассмотрим тип данных параметра Отбор.
Параметр может быть задан двумя типами: Структура или Отбор. Если параметр имеет тип Структура, то представляет собой фильтр для записей регистра, по которому будет получена база. Имена элементов структуры должны быть или словом "Регистратор" и/или совпадать с именами измерений регистра расчета. Значения элементов структуры представляют собственно значения отбора. Должно присутствовать как минимум условие на регистратор.
Если параметр имеет тип Отбор, то представляет отбор, по которому будет получена база. В отборе должен быть использован как минимум элемент отбора по регистратору. Все элементы отбора должны устанавливать условие с вариантом сравнения "равно". Именно такой вариант реализован в процедуре ОбработкаПроведения.
Использование данного параметра необходимо, чтобы отобрать из регистра расчетов те записи, для которых нужно будет получить данные базы.
Замечание 2. В качестве базовых регистров (из ресурсов которых рассчитывается база) могут выступать несколько регистров расчета (этот вариант рассмотрим позже).
Замечание 3. Состав базы каждого вида расчета определяется в предопределенной табличной части базовые виды расчета.
Замечание 4. Обязательно посмотрите внешний вид этой таблицы в режиме отладки.
определяется количество отработанных сотрудником дней. Для этого используется метод регистра расчета ПолучитъДанныеГрафика(Отбор, Вид периода). Этот метод получает данные из графика (связанного с регистром расчета) для движений по заданному
54
Решение задачи
регистратору. В качестве второго параметра метода указывается фактический период действия записи (понятие Фактический период действия и отличие его от просто Периода действия рассмотрим чуть позже). В этом случае методом возвращаются данные графика, собранные по фактическому периоду действия. Метод возвращает данные в виде таблицы значений. Число строк таблицы значений совпадает с числом записей движений по данному регистратору. Таблица значений содержит две колонки - номер записи и полученные данные календаря.
- определяется норма дней, которую сотрудник должен
отработать в рассматриваемом периоде. Для этого также
используется метод регистра расчета
ПолучитьДанныеГрафика(Отбор, Вид периода). В
качестве второго параметра метода указывается период
действия записи. В этом случае методом возвращаются
данные графика по периоду действия. В нашем случае,
т.к. регистр расчета имеет месячную периодичность,
суммируются данные графика за весь месяц, в котором
действует запись регистра расчета.
- определяется количество отработанных дней по базе.
Для этого опять же используется метод регистра расчета
ПолучитъДанныеГрафика(Отбор, Вид периода). В
качестве второго параметра метода указывается базовый
период записи. В этом случае методом возвращаются
данные графика по базовому периоду - суммируются
данные графика за базовый период (например, для
Отпуска, который мы рассмотрим позже, будут
просуммированы данные графика за три месяца,
предшествующие периоду регистрации).
Расчет результатов начислений, удержаний, выплат
После проведенной подготовки все данные передаются в процедуру РассчитатъНачисленияУдержания. Здесь размещаются алгоритмы расчета всех начислений, удержаний и выплат.
Функция РассчитатьНачисленияУдержания(СтрокаДвижений, Индекс, ДанныеБазы, Отработано, Норма, ОтработаноПоБазе) Экспорт
Если СтрокаДвижений.ВидРасчета = ПланыВидовРасчета.ВсеВидыРасчета. Оклад Тогда
//1
НормаДней = Норма[Индекс].Значение; Если НормаДней = 0 Тогда
Сообщить("Расчет оплаты по окладу: Нет рабочих дней в заданном периоде", СтатусСообщения.Информация);
Возврат 0;
Иначе
Если СтрокаДвижений.Сторно Тогда
Возврат-СтрокаДвижений.ПараметрРасчета;
Иначе
Возврат СтрокаДвижений.ПараметрРасчета *
Отработано [Индекс] .Значение/НормаДней * ?(СтрокаДвижений.Сторно,-1,1);
КонецЕсли; КонецЕсли;
ИначеЕсли СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета,ВсеВидыРасчета.ПремияПроцентом Тогда //2
Если СтрокаДвижений.Сторно Тогда
Возврат-СтрокаДвижений.ПараметрРасчета; Иначе
Возврат ДанныеБазы[Индекс],Результат*СтрокаДвижений.ПараметрРасчета/100;
КонецЕсли;
ИначеЕсли СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета.ВсеВидыРасчета.Отпуск Тогда //3
ОтработаноДней = ОтработаноПоБазе [Индекс]. Значение; Если ОтработаноДней = 0 Тогда
Сообщить("Расчет отпуска: Нет рабочих дней в базовом периоде", СтатусСообщения.Информация);
Возврат 0;
Иначе
Возврат ДанныеБазы[Индекс].Результат/ОтработаноДней * Отработано [Индекс] .Значение * ?(СтрокаДвижений.Сторно,-1,1);
КонецЕсли;
ИначеЕсли СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета.ВсеВидыРасчета.ШтрафСуммой ИЛИ //4
СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета.ВсеВидыРасчета.Выплата Тогда
//5
Возврат СтрокаДвижений.ПараметрРасчета; КонецЕсли; Возврат 0; КонецФункции
Комментарии.
//1: Расчет Оклада. Алгоритм расчета: плановый оклад умножается на фактически отработанное количество дней и делится на норму дней в периоде. Так и делаем. Из таблицы значений, в которой находятся нормы часов, по номеру строки, соответствующему номеру записи в регистре расчета из колонки Значение получаем нужную сумму. Аналогично из таблицы значений, в которой содержатся отработанные
56
Решение задачи
дни, получаем количество отработанных дней. Плановый Оклад содержится в реквизите документа-регистратора ПараметрРасчета. Расчетная база и Отработанные по базе дни не используются.
//2; Расчет ПремииПроцентом. Берем данные базы, умножаем на ПараметрРасчета (в данном случае процент премии, задается в документе-регистраторе) и делим на 100. Сторнирование рассмотрим позже. При этом понятия Отработанное количество дней, Норма и Отработано по базе не используются
//3: Расчет Отпуска. Данные базы делим на отработанное количество дней по базе и умножаем на количество дней отпуска (здесь количеством дней отпуска является параметр фактически отработано дней). Норма и ПараметрРасчета не используются.
//4: Расчет ШтрафаСуммой. Это настолько простой расчет, что используется только ПараметрРасчета что указываем в документе-регистраторе, то и попадет в результат.
//5: Расчет Выплаты. То же самое, что и алгоритм для ШтрафаСуммой. Результат берется из ПараметраРасчета.
Замечание. На примере алгоритмов расчета ясно просматривается избыточность регистра расчетов. Практически во всех алгоритмах некоторые расчетные параметры не используются. Это говорит о том, что структуру регистра надо как-то оптимизировать. Например, создав несколько разных по своей структуре регистров расчета... Но об этом речь пойдет дальше.
После проведения документа в регистре расчета «РасчетыВсе» появятся записи:
57
Попробуем создать в режиме исполнения следующий документ.

Конфигурирование в системе " 1С:Предприятие 8.0". Решение расчетных задач
Обратим внимание на то, что результат Премии процентом оказался нерассчитанным.
Важное замечание! Если одним документом рассчитываются зависимые по базе записи (например, Оючад и ПремияПроцентом, в состав базы которой попадает оклад), то прежде, чем рассчитать зависимую от базы запись, нужно рассчитать запись, попадающую в эту базу и записать (!) результат в регистр расчета. Таким образом, в общем случае в процессе проведения документа будет произведено несколько процедур записи в регистр расчета.
В нашем случае перед расчетом премии мы не выполнили запись результата оклада, поэтому и получили нулевой результат (пустую базу) для премии.
Алгоритм переделывать не будем, записи, зависимые по базе, будем вводить различными документами.
Создадим в режиме исполнения следующий набор документов. Расчеты за январь (Период регистрации - 1 января). Документ для ввода окладов:

После проведения документа в регистре расчета «РасчетыВсе» появятся записи (двойной щелчок по строке открывает документ-регистратор):
58
Решение задачи

Документ для ввода премий процентом:
Документ для ввода штрафа:
Документ для ввода выплат;
59
Конфигурирование в системе "1С предприятие 8.0". Решение расчетных задач

Если в регистре расчета поставить курсор на поле Сотрудник и нажать кнопку «Отбор по текущему значению», то останутся записи только по одному сотруднику (можно назначить и более сложный отбор кнопкой «Отбор и сортировка»).

Документ для ввода премий:
60
Расчеты за февраль (Период регистрации - 1 февраля). Документ для ввода окладов:

Решение задачи
Вытесняющие расчеты. Вид расчета «Отпуск»
Ранее мы упоминали о существовании в плане видов расчета предопределенной табличной части Вытесняющие виды расчета. Вытесняющие виды расчета определяются в плане видов расчета, а работают в регистре расчета. Рассмотрим свойство вытеснения подробней.
Вытесняющими являются такие расчеты, которые взаимно исключают друг друга по периоду действия и система должна гарантировать, что ввод одного из них приведет к исключению другого. В нашем случае вид расчета «Оклад» будет вытесняться видом расчета «Отпуск», т.к. нельзя одновременно работать и быть в отпуске.
Реализуем вытеснение «Оклада» «Отпуском». Для начала заполним табличную часть Вытесняющие виды расчета вида расчета «Оклад» в плане видов расчета «ВсеВидыРасчета» следующим образом:

«Оклад» вытесняется «Отпуском».
Реализуем механизм ввода «Отпуска» в регистр расчета «РасчетыВсе». Вспомним, что «Отпуск» имеет расчетную базу и эта расчетная база лежит в базовом периоде, который представляет собой три месяца, предшествующие периоду действия.
61
Доработаем модуль документа «НачислениеЗарплатыВсей». В процедуре ОбработкаПроведения после строки:
Движение.ПериодДействияОкончание = Строка. ДатаОкончания;
вставим строки:
Если Строка.ВидРасчета = ПланыВидовРасчета.ВсеВидыРасчета.Отпуск
Тогда
Движение.БазовыйПериодНачало
ДобавитьМесяцСДвижение.ПериодДействия, -3);
Движение.БазовыйПериодОкончание
Движение.ПериодДенствия-1;
КонецЕсли;
Создадим и проведем документ «НачислениеЗарплатыВсей» (определим Отпуск с 01.02.2003 по 10.02.2003), в качестве графика выберем Неосновной график (соответственно создадим в справочнике «ГрафикиРаботы» новый элемент и определим тип неосновного графика - Шестидневка):

После проведения этого документа автоматически сработало вытеснение. Хотя, если посмотреть регистр расчета «РасчетыВсе», никаких изменений мы не найдем.
Посмотрим с помощью запроса, что получилось в регистре расчета после ввода «Отпуска» (используем отчет «Знакомство с запросом»):
Выбрать
из
РегистрРасчегаРасчетыВсе

62
Решение задачи
Действительно, изменений нет. Потому что механизм вытеснения проявился не в изменении таблицы регистра расчета, а в изменении состава записей таблицы Фактического периода действия.
Фактический период действия. Запрос к таблице ФактическийПериодДействия
Фактический (итоговый) период действия - это тот период, который сложился за счет правил вытеснения видов расчета, определяемых списками вытесняющих видов расчета плана видов расчета данного регистра расчета.
Можно представлять Фактический период действия как таблицу, «подчиненную» регистру расчетов.
Посмотрим с помощью запроса как выглядит таблица Фактического периода действия.
Выбрать *
из
РегистрРасчета.РасчетыВсе.ФактическийПериодДействия
63
В процессе вытеснения таблица Фактический период действия заполняется строками, каждая из которых представляет собой реальный период действия, лежащий до или после периода действия вытесняющего вида расчета (а если одну «длинную» запись вытеснили две «короткие», то у нее может быть и три записи в таблице фактического периода действия). При этом не происходит изменения ни текущего набора записей, ни наборов записей других регистраторов. Данные, попадающие в таблицу фактического периода действия, вводятся на основании уже имеющихся данных, поэтому являются вторичными данными. Отобразим сказанное на схеме.
Конфигурирование в системе " 1С:Предприятие 8.0". Решение расчетных задач

Этот фактический период действия относится к Оплате по окладу.
Представим результат вытеснения Оклада видом расчета Отпуск, действующим с 01.02.2003 по 10.02.2003 в виде схемы.

Замечание. В 7.7 не было понятия «фактический (итоговый) период действия» и поэтому работа механизма вытеснения проявлялась в том, что при вводе движений одними документами производилось необратимое искажение движений других документов.
Представим основные свойства данных объектов в виде таблицы
64
Для работы с Фактическим периодом действия из встроенного языка используются следующие объекты:
". Решение расчетных задач
Теперь перепроведем документ, которым начислялся «Оклад» в феврале. При этом произойдет перерасчет результата «Оклада».
Посмотрим, что получилось в регистре расчетов - результат «Оплаты
по окладу» изменился. Дело в том, что в алгоритме расчета «Оклада»
заложено, что отработанное время считается от фактического периода
действия (так работает метод ПолучитьДанныеГрафика (Отбор,
ВидПериодаРегистраРасчета. ФактическийПериодДействия),
кстати, метод ПолучитьБазуО также опирается на фактический период действия).
Замечание. На уровне системы исключаются циклические вытеснения. Например, если задать в плане видов расчета, что «Отпуск» вытесняет «Оклад», и, в тоже время, что «Оклад» вытесняет «Отпуск», и попытаться сохранить изменения, то система выдаст предупреждение:

Механизм сторнирования. Работа механизма вытеснения при регистрации записей с периодом действия меньшим, чем период регистрации
Рассмотрим ситуацию, когда расчеты, конкурирующие за период действия, вводятся задним числом. Например, когда отпуск, в котором сотрудник был в январе, вводится в феврале, притом, что за январь сотруднику полностью оплатили оплату по окладу. В этом случае в феврале, помимо записи, соответствующей отпуску, должна появиться сторно-запись, отменяющая часть январского оклада за период, в котором сотрудник был в отпуске.
Реализуем такую ситуацию в нашей конфигурации. Доработаем документ «НачислениеЗарплатыВсей». В модуле документа перед строкой
Движения.РасчетыВсе,Записать();
добавим строку:
Доп = Двнжения.РасчетыВсе.ПолучитьДополнение();
66
Решение задачи
В системе «1 (^Предприятие 8.0» для автоматического получения сторно-записей используется метод ПолучитъДополнение() набора записей. Этот метод опирается на фактический период действия. Метод получает дополнение к текущему набору записей в виде таблицы значений со структурой, повторяющей структуру набора записей (дополнение - это дополнительные записи, имеющие признак сторно). Такие сторно-записи формируются на основании периодов действия записей регистра расчета и правил конкуренции за период действия, задаваемых списками вытесняемых видов расчета в плане видов расчета регистра.
Создадим для сотрудника Петрова документ по вводу отпуска с 10.01.2003 по 20.01.2003 как показано ниже:

Поставим в отладчике точку останова на строке
Доп = Движения.РасчетыВсе.ПолучитьДополнение();
Проведем документ. Посмотрим в режиме отладки таблицу значений, которая возвращается методом ПолучитъДополнение() (напомним, что содержимое таблиц значений очень удобно просматривать с помощью
67
отладчика).
йййЈйЗ»^2г:饣:5:Шя;^^
Данная таблица значений содержит данные, повторяющие структуру набора записей регистра расчета.
Для ввода сторно-записей нужно перебрать строки рассмотренной таблицы значений и ввести информацию из них в регистр расчета.
Добавим после строки
Доп = Движения.РасчетыВсе.ПолучитьДополнение();
следующее:
Для Каждого Строка Из Доп Цикл
Движение = Движения.РасчетыВсе.Добавить();
Движение.ПериодРегистрации = Строка.ПериодРегистрации;
Движение.ПериодДействияНачало = Строка.ПериодДействияНачало;
Движение.ПериодДействияОкончание =
Строка.ПериодДенствияОкончание;
Движение.БазовыйПериодНачало = Строка.БазовыйПериодНачало; Движение.БазовыйПериодОкончание = Строка.БазовыйПериодОкончание; Движение.Сотрудник = Строка.Сотрудник; Движение.ВидРасчета = Строка.ВидРасчета; Движение.Подразделение = Строка.Подразделение; Движение. Должность = Строка. Должность; Движение.График = Строка.График; Движение.ПараметрРасчета = СтрокаПараметрРасчета; Движение.Сторно = Строка.Сторно; КонецЦикла;
Решение задачи
В регистре расчетов должно получиться примерно следующее.

Замечание. Заметим, что ввод сторно-записей мы сделали сами (произвольно), напомним, что в 7.7 в подобных ситуациях сторно-записи вводились автоматически.
Решение задачи
Перерасчеты. Ведущие виды расчетов
Перерасчетами называют подчиненные объекты регистра, которые позволяют задать правила взаимного влияния движений регистров.
Замечание. Для простоты восприятия можно представлять Перерасчеты как таблицы, в которых хранятся данные о требуемых перерасчетах. Данные о перерасчетах не являются записями регистра расчета.
Замечание. Для одного регистра расчета могут поддерживаться несколько перерасчетов разной структуры, которые могут решать разные задачи.
Создадим новый перерасчет и назовем его «Перерасчет». В дереве конфигурации определим измерения перерасчета:
- «Подразделение»,
- «Должность»,
- «Сотрудник».

Связь измерений перерасчета с измерениями регистра и данными базовых регистров
В окне свойств измерений «Перерасчета» на закладке Связь в свойстве Измерение регистра указывается основное измерение текущего регистра, которое следует пересчитать при изменении данных базовых регистров, указанных в свойстве Данные базовых регистров. Базовым регистром определим этот же регистр расчетов («РасчетыВсе»).
В нашем случае при изменении «Оклада» (из базового регистра расчета) будет формироваться перерасчет суммы «ПремииПроцентом» по сотруднику, работающему в подразделении на должности.
69
Конфигурирование в системе " 1 С: Предприятие 8.0". Решение расчетных задач

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

Заполним предопределенную табличную часть Ведущие виды расчета вида расчета «ПремияПроцентом» в плане видов расчета «ВсеВидыРасчета» следующим образом:

70
Решение задачи
Теперь при изменении записи регистра расчетов, содержащей «Оклад» (естественно, запись должна попадать в базовый период «ПремииПроцентом»), таблица «Перерасчета» будет заполняться строками, каждая из которых будет представлять собой набор сведений о виде расчета и документе-регистраторе записи регистра расчета, которую нужно пересчитать. Также в таблице будут присутствовать измерения перерасчета.
При регистрации перерасчетов не будет происходить изменения ни текущего набора записей, ни наборов записей других регистраторов.
Помимо автоматической регистрации перерасчетов существует возможность их программной регистрации (т.е. в таблицу Перерасчета можно вводить записи и самим из программного кода).
Чтобы обработать таблицу перерасчета, нужно программно выполнить ряд действий, связанных, например, с чтением из таблицы перерасчета информации о перерасчетах, перепроведением (точнее «частичным» перепроведением) документа-регистратора пересчитываемой записи, вводом документов-перерасчетов, очисткой (корректировкой) перерасчета, отказом от перерасчета и т.д.
Замечание. Нужно понять, что принцип работы перерасчетов в системе «1С:Предприятие 8.0» является «уведомительным». Т.е. мы сами в процессе конфигурирования будем решать, заниматься ли нам вводом корректирующих записей или перерасчетом ресурсов затронутых перерасчетами учетных записей, а можем просто «не обращать внимания» на сведения, которые предоставляет нам система в таблице перерасчета, то есть отказаться от пересмотра результатов расчета. Напомним, что в версии 7.7 разработчик конфигурации не мог управлять процессом перерасчета записей журнала расчетов (он мог лишь создавать или не создавать правила перерасчета).
Для работы с перерасчетами из встроенного языка используются следующие объекты:
71
Сонфигурирование в системе "1С: Предприятие 8.0". Решение расчетных задач

Представим объекты Перерасчетов в виде таблицы.
72
Решение задачи
Для того, чтобы использовать «Перерасчет» в нашей конфигурации, =у придется создать ряд новых объектов и внести изменения в существующие алгоритмы:
создадим обработку, в которой будет проверяться «актуальность» расчетов (при изменении «Оклада» в обработке должны будут отображаться те записи регистра расчета, которые необходимо будет пересчитать - т.е. «ПремииПроцентом»),
создадим константу «Дата запрета редактирования». Эта константа будет определять «закрытие» периода. Записи регистра расчета с периодом регистрации меньше (или равно) «Даты запрета редактирования» редактировать будет нельзя. Записи регистра расчета с периодом регистрации меньше (или равно) «Даты запрета редактирования» будут считаться архивными, их нельзя будет редактировать. Для пересчета таких записей будем создавать новый документ-перерасчет, внесем изменения в модуль документа «Начис л ениеЗарпл атыВ сей».
Константа «Дата запрета редактирования»
Создадим константу с именем «ДатаЗапретаРедактирования» типа Дата.
Вставим новую константу в форму констант.
Обработка «Перерасчет зарплаты»
Создадим обработку «Перерасчет зарплаты». Основные свойства.
Имя: «ПерерасчетЗарплаты»
о Табличные части: ДокументыПерерасчета. Реквизиты табличной части:
- «Документ»: тип ДокументСсылка,
- «Пометка»: тип Булево.
Формы: Форма.
Вставим в диалог Формы табличное поле и свяжем его с табличной частью отчета ДокументыПерерасчета.
Используем еще одну возможность системы «1С:Предприятие 8.0», для реализации которой в 7.7 потребовалось бы немало потрудиться.
Попробуем отобразить в колонке Документ (типа ДокументСсылка) табличного поля флажок, в котором можно поставить пометку. Причем этот флажок свяжем с данными - с реквизитом табличной части Пометка.
75
В результате дальнейших действий должно получиться так:

Удалим все колонки из табличного поля. Через меню «Форма»-«Размещение данных» вставим в табличное поле колонку Документ как поле ввода.

В окне свойств поля ввода Документ изменим свойство Элемент управления на Флажок (см. картинку ниже). А в свойстве Данные флажка выберем значение Пометка (см. вторую картинку ниже).

На закладке Характеристики окна свойств поля ввода Документ установим свойство Режим редактирования: Непосредственно.
Перейдем к следующим объектам.
Создадим элемент управления Командная панель с кнопками:
- «ПометитъВсе»: действие ПометитьВсе,
- «СнятьПометки»: действие СнятъПометки,
- «ВыполнитъПерерасчет»: действие
ВыполнитъПерерасчет,
- «ОткрытьДокумент»: действие Открыть Документ,
- «ОбновитьПерерасчеты»: действие
ОбновитъПерерасчеты,
76
Решение задачи
Вставим табличное поле СтрокиПерерасчета и определим тип значения: ТаблицаЗначений.
Создадим колонки табличного поля:
Сотрудник: поле ввода
СправочникСсылка.ФизическиеЛица,
Подразделение: поле ввода типа СправочникСсылка.
Подразделения,
Должность: поле ввода типа СправочникСсылка.
Должности,
ВидРасчета: поле ввода типа ПланВидовРасчетаСсылка.
типа

В результате должна получиться примерно такая форма:
В модуле формы запишем процедуры
77
Процедура ПередОгкрытием(Отказ, СтандартнаяОбработка) ЗаполнитьДанныеО;
КонецПроцедуры
Комментарии. Нужно не забыть назначить обработчик события Перед Открытием Формы (в разделе свойств События формы необходимо выбрать событие ПередОткрытием).
Процедура ЗаполнитьДанныеО Экспорт Запрос = Новый Запрос(
"ВЫБРАТЬ РАЗЛИЧНЫЕ
I ИСТИНА КАК Пометка,
1 ОбъектПерерасчета КАК Документ
ИЗ
I РегистрРасчета.РасчетыВсе.Перерасчет
I");
ДокументыПерерасчета.Загрузить(Запрос.Выполнить().Выгрузить()); КонецПрощедуры
Комментарии.
В процедуре Заполнить Данные мы использовали запрос к таблице «Перерасчета». Вообще таблица объекта «Перерасчет» имеет следующий состав полей.

Интересно первое поле в представленном запросе - ИСТИНА КАК Пометка. Это означает, что в результат запроса будет добавлена колонка с названием Пометка, содержащая значения Истина.
Результат запроса выгружается в табличное поле ДокументыПерерас чета.
Для оперативного обновления содержания табличного поля в процедуре «ОбновитьПерерасчеты», связанной с кнопкой «Обновить список» поместим следующее.
Процедура ОбнсвитъПерерасчеты(Кнопка)
ЗаполнитьДанные(); КонецПро цедуры
Назначим обработчик события ПриАктивизацииСтроки у табличного
поля ДокументыПерерасчета. В процедуре
78
Решение задачи
ДокументыПерерасчетаПриАктивизацииСтроки следующее.
запишем
Процедура ДокументыПерерасчетаПриАктивизацииСтроки(Элемент) Если Элемент.ТекущиеДанные = Неопределено Тогда СтрокиПерераечета.ОчиститьО; Возврат; КонецЕсли;
ОбновитьСписокПерерасчетов(Элемент.ТекущиеДанные.Документ); КонецПроцедуры
Процедура ОбновитьСписокПерерасчетов(Документ)
НаборПерерасчета РегистрыРасчета.РасчетыВсе.Перерасчеты.Перерасчет,СоздатьНаборЗаписей();
НаборПерерасчета. Отбор.ОбъектПерерасчета.Значение = Документ;
НаборПерерасчета.Прочитать();
СтрокиПерерасчета.ОчиститьО;
Для Каждого Строка Из НаборПерерасчета Цикл
СтрокаТЗ=СтрокиПерерасчета.Добавить();
СтрокаТЗ.ВидРасчета=Строка.ВидРасчета;
СтрокаТЗ.Подразделение=Строка.Подразделение;
СтрокаТЗ.Должность=Строка.Должность;
СтрокаТЗ.Сотрудник=Строка.Сотрудник; КонецЦикла; КонецПроцедуры
Теперь при установке курсора на какую-либо строку табличного поля ДокументыПерерасчета, табличное поле СтрокиПерерасчета автоматически будет заполняться перерасчетами из набора перерасчетов объекта «Перерасчет», соответствующих документу из табличного поля ДокументыПерерасчета.
В процедуре ОткрытъДокумент, связанной с кнопкой «Открыть документ», запишем алгоритм, позволяющий открыть форму документа, на котором стоит курсор в табличном поле ДокументыПерерасчета.
Процедура ОткрытьДокумент(Кнопка)
Если ЭлементыФормы, ДокументыПерерасчета. ТекущиеДанные
НЕОПРЕДЕЛЕНО Тогда
о
ЭлементыФормы.ДокументыПерерасчета.ТекущиеДанные.Документ.ПолучитьФор му(). Открыть();
КонецЕсли; КонецПроцедуры
В процедуре ПометитьВсе связанной с кнопкой «Пометить все», запишем алгоритм, позволяющий установить флажки во всех строках
79
Конфигурирование в системе "1С:Предприятие 8.0". Решение расчетных задач
табличного поля ДокументыПерерасчета. В процедуре СнятьПометпки связанной с кнопкой «Снять пометки», запишем алгоритм, позволяющий снять все флажки.
Процедура ПометигьВсе(Кнопка)
Для Каждого СтрокаТаблицы Из ДокументыПерерасчета Цикл СтрокаТаблицы.Пометка = Истина;
КонецЦикла; КонецПроцедуры
Процедура СнягьПометки (Кнопка)
Для Каждого СтрокаТаблицы Из ДокументыПерерасчета Цикл СтрокаТаблицы.Пометка = Ложь;
КонецЦикла; КонецПроцеду'ры
Проверим работу формы в режиме исполнения. Выполним следующие действия:
- Откроем форму списка регистра расчета «РасчетыВсе».
Установим отбор по сотруднику Ивановой.
- Найдем строку с февральским окладом Ивановой,
двойным щелчком откроем документ-регистратор и
изменим оклад Ивановой с 760 на 800. Проведем
документ.
При этой система автоматически введет новый перерасчет (фактичеси будет введен сигнал о том, что необходимо пересчитать «ПремикюПроцентом» по данной комбинации измерений перерасчета). Чтобы убедиться в этом, сформируем запрос к таблице «Перерасчета» с помощью» отчета «Знакомство с запросом».
Текст запроса.
ВЫБРАтЬ *=
ИЗ
РегистрРасчетаРасчетыВсе.Перерасчет
3. Откройте обработку ПерерасчетЗарплаты.
Должна получиться примерно такая картинка.
80
Таблица результатов запроса:

Решение задачи
При нажатии на кнопку «Выполнить перерасчет» вызывается процедура ВыполнитъПерерасчет.
Процедура ВыполнитьПерерасчет(Кнопка) Экспорт
Для Каждого СтрокаТаблицы Из ДокументыПерерасчета Цикл Если СтрокаТаблицы.Пометка Тогда
Попытка // если не запрещено редактиование документа - выполним перерасчет
Если СтрокаТаблицы.Документ.ПериодРегистрации Константы.ДатаЗапретаРедактирования.ПолучитьО Тогда
СтрокаТаблицы.Документ.ПолучитьОбъект().Перерассчитать();
Сообщить("Перерасчитан документ " +
СтрокаТаблицы.Документ);
// иначе - введем документ перерасчета
Иначе СтрокаТаблицы.Документ.ПолучитьОбъект().ВвестиПерерассчет();
Сообщить("Введен перерасчет документа " +
СтрокаТаблицы.Документ);
КонецЕсли; Исключение
Сообщить(ОписаниеОшибки());
Сообщить("Документ " + СтрокаТаблицы.Документ+ " не может быть перерасчитан автоматически");
КонецПопытки;
КонецЕсли; КонецЦикла;
КонецПроцедуры
Комментарии.
81
В данной процедуре для каждой отмеченной флажком строки табличного поля ДокументыПерерасчета выполняется попытка:
- пересчитать расчеты (фактически перепровести
документы-регистраторы этих расчетов), которые попали
в «Перерасчет». Это действие выполняется только в
случае, когда дата рассматриваемого документа больше
значения константы «Даты запрета редактирования» (т.е.
период пока не закрыт).
- ввести документы-перерасчеты для расчетов, которые
попали в «Перерасчет». Это действие выполняется в
случае, когда дата документа меньше (равно) значения
константы «Даты запрета редактирования» (т.е. период
закрыт).
Рассмотрим оба этих действия детально. Перерасчет документа
Для выполнения перерасчета документа необходимо поместить в модуль документа «НачислениеЗарплатыВсей» процедуру Пересчитать (с ключевым словом Экспорт).
Текст процедуры следующий.
Процедура Пересчитать() Экспорт НачатьТранзакцию();
НаборПерерасчетов =
РегистрыРасчета.РасчетыВсе.Перерасчеты.Перерасчет.СоздатьНаборЗаписей();
НаборПерерасчетов.Отбор.ОбъектПерерасчета.Значение = Ссылка;
НаборПерерасчетов.Прочитать(); РВсеМенеджер=РегистрыРасчета.РасчетыВсе;
Отбор= Новый СтруктураО;
Отбор .Вставить("Регистратор",Ссылка);
Ресурсы = Новый Массив(1);
Ресурсы[0] = "РасчетыВсе.Результат";
Измерения= Новый Структура();
Измерения.Вставить("Подразделение","РасчетыВсе.Подразделение");
Измерения.Вставить("Должность","РасчетыВсе.Должность");
Измерения.Вставить("Сотрудник","РасчетыВсе.Сотрудник");
ДанныеБазы = РВсеМенеджер.ПолучитьБазу(Отбор,Ресурсы,Измерения);
Отработано =
РВсеМенеджер.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета.Фактический ПериодДействия);
Норма =
РВсеМенедхер.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета.ПериодРегис
трации);
82
Решение задачи
ОтработаноПоБазе =РВсеМенеджер.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета.БазовыйПер
иод);
Движения.РасчетыВсе.Прочитать();
Таблица = Движения.РасчетыВсе.Выгрузить();
СтруктураПоиска = Новый Структура("Подразделение,Должность,Сотрудник");
Для Каждого СтрокаПерерасчета Из НаборПерерасчетов Цикл
СтруктураПоискаЛодразделение = СтрокаПерерасчетаЛодразделение;
СтруктураПоиска. Должность = СтрокаПерерасчета. Должность;
СтруктураПоиска. Сотрудник = СтрокаПерерасчета.Сотрудник;
//СтрокиПерерасчета = Таблица.НайтиСтроки(СтруктураПоиска);
Для Каждого СтрокаРегистра Из ТаблицаЛайтиСтроки(СтруктураПоиска) Цикл
СтрокаРегистра.Результат
РассчитатьНачисленияУдержания(СтрокаРегистра, ТаблицаЛндекс(СтрокаРегистра),
ДанныеБазы, Отработано,Норма, ОтработаноПоБазе);
КонецЦикла; КонецЦикла;
Движения.РасчетыВсе.Загрузить(Таблица); Движения.РасчетыВсе.Записать(); ЗафиксироватьТранзакциюО; КонецПроцедуры
Комментарии.
В процедуре выполняется выборка записей из «Перерасчета», устанавливается отбор по текущему документу, а затем для каждой из оставшихся после отбора записей «Перерасчета» производится поиск соответствующей записи в регистре расчета «РасчетыВсе». По найденной строке производится перерасчет записи (вызывается уже знакомая нам процедура РассчитатъНачисленияУдержания).
Замечание. Процедура выполняется в транзакции (используются методы НачатъТранзакцию(), ЗафиксироватьТранзакциюО). Это необходимо, т.к. мы хотим быть уверены в неизменности данных, прочитанных нами при перерасчете.
Проверим работу алгоритма на практике.
В режиме исполнения выполним следующие действия:
- установим значение константы
«ДатаЗапретаРедактирования»: 01.01.2003.
- Нажмем в обработке «ПерерасчетЗарплаты» кнопку
«Выполнить перерасчет».
В результате в строке сообщений появится примерно следующая информация:
83
«Перерасчитан документ Начисление зарплаты всей 6 от 01.01.2003 00:00:00».
В регнсгре расчета «РасчетыВсе» результат премии изменится.
Ввод документа-перерасчета
Для выполнения перерасчета с вводом документов-перерасчетов
необходимо поместить в модуль документа
«НачислениеЗарплатыВсей» процедуру ВвестиПерерасчет (с
ключевым словом Экспорт).
В процедуре ВвестиПерерасчет выполняется создание нового документа (перерасчета) на основании текущего, поэтому в модуль документа «НачислениеЗарплатыВсеи» также необходимо поместить процедуру ОбработкаЗаполнения.
Текст процедуры ОбработкаЗаполнения следующий.
Процедура. ОбработкаЗаполнения(Основание)
ПериодРегистрации = НачалоМесяца(ТекущаяДата()); Дата= ТекущаяДата();
КонецПроцедуры
Текст процедуры ВвестиПерерасчет следующий.
Процедура ВвеетиПерерасчет() Экспорт НачатьТранзакцию();
НаборПерерасчетов =
РегистрыРасчета.РасчетыВсе.Перерасчеты.Перерасчет.СоздатьНаборЗаписей();
НаборПерерасчетов.Отбор.ОбъектПерерасчета.Значение = Ссылка; НаборПерерасчетов.Прочитать();
ДокументПерерасчета = Документы.НачислениеЗарплатыВсей.СоздатьДокумент(); ДокумешПерерасчета.Заполнить(Ссылка); Запрос = Новый Запрос(
"ВЫБРАТЬ
I*
IИ3
|РегистрРасчета.РасчетыВсе
|где РегистрРасчета.РасчетыВсе.Регистратор=парДокументОбъект
||);
Запрос.УстановитьПараметр(" парДокументОбъект", Ссылка); Таблица =Запрос.Выполнить().Выгрузить();
84
Решение задачи
СтруктураПоиска = Новый Структура("Подразделение,Должность,Сотрудник"); Для Каждого СтрокаПерерасчета Из НаборПерерасчетов Цикл
СтруктураПоиска.Подразделение = СтрокаПерерасчетаЛодразделение;
СтруктураПоиска.Должность = СтрокаПерерасчета.Должность;
СтруктураПоиска.Сотрудник = СтрокаПерерасчета.Сотрудник;
Для Каждого СтрокаРегистра Из Таблица.НайтиСтроки(СтруктураПоиска) Цикл
НоваяСтрока = ДокументПерерасчета.Список.Добавить(); НоваяСтрока. Сотрудник = СтрокаРегистра.Сотрудник; НоваяСтрока.ВидРасчета = СтрокаРегистра.ВидРасчета; НоваяСтрока.Подразделение = СтрокаРегистраЛодразделение; НоваяСтрока.Должность = СтрокаРегистра.Должность; НоваяСтрока.График = СтрокаРегистра.График; НоваяСтрока.ВидРасчета = СтрокаРегистра.ВидРасчета;
НоваяСтрока.ДатаНачала =
СтрокаРегистра ЛериодДействияНачало;
НоваяСтрока.ДатаОкончания =
СтрокаРегистра ЛериодДействияОкончание;
НоваяСтрока.Размер = СтрокаРегистра.Результат; НоваяСтрока. Сторно = Истина;
НоваяСтрока = ДокументПерерасчета.Список.Добавить(); НоваяСтрока. Сотрудник = СтрокаРегистра. Сотрудник; НоваяСтрока.ВидРасчета = СтрокаРегистра.ВидРасчета; НоваяСтрока.Подразделение = СтрокаРегистраЛодразделение; НоваяСтрока.Должность = СтрокаРегистра.Должность; НоваяСтрока.График = СтрокаРегистра.График; НоваяСтрока.ВидРасчета = СтрокаРегистра.ВидРасчета;
НоваяСтрока.ДатаНачала =
СтрокаРегистраЛериодДействияНачало;
НоваяСтрока.ДатаОкончания =
СтрокаРегистра.ПериодДействияОкончание;
НоваяСтрока.Размер = СтрокаРегистра.ПараметрРасчета; КонецЦикла; КонецЦикла;
ДокументПерерасчета.Записать(); ЗафиксироватьТранзакцию();
КонецПроцедуры
Комментарии.
В процедуре выполняется выборка записей из «Перерасчета», устанавливается отбор по текущему документу, устанавливается отбор по текущему документу, а затем для каждой из оставшихся после отбора записей «Перерасчета» производится поиск соответствующей
85
Конфигурирование в системе "1 С'Предприятие 8.0". Решение расчетных задач
У\ РшениеЈасчетнш задач
записи в регистре расчета «РасчетыВсе». По найденной строке выполняется программное создание нового документа-перерасчета. В создаваемом документе заполняются две строки табличной части: первая строка является сторнирующей, в неё помещается текущий результат из регистра расчета со знаком «-» и устанавливается признак Сторно. Во второй строке заполняется только параметр расчета, который в последствии используется для расчета результата новой записи.
Замечание. Процедура выполняется в транзакции.
Проверим работу алгоритма на практике.
В режиме ислолнения выполним следующие действия:
- установим значение константы
«ДатаЗапретаРедактирования»: 01.03.2003.
- Еще раз изменим оклад Ивановой с 800 на 900.
- Нажмем в обработке «ПерерасчетЗарплаты» кнопку
«Выполнить перерасчет».
В результате в строке сообщений появится примерно следующая информация:
«Введен перерасчет документа Начисление зарплаты всей 6 от 01.01.2003 00:00:00».
Откроем форму списка документа
«НачислениеЗарплатыВсей». Откроем последний
(непроведенный) документ.

Проведем данный документ.
В регистре расчета «РасчетыВсе» появятся две новые записи сторнирующая и запись-перерасчет.
86
Решение задачи

Отчет «Расчеты сотрудников»
Создадим отчет, который бы выдавал нам информацию о состоянии расчетов сотрудников (обо всех начислениях, удержаниях, выплатах) на заданную дату.
В результате работы отчета должно получиться примерно следующее.

Создадим новый отчет, определим его основные свойства.
- Имя: «РасчетыСотрудниковВсе»,
- Реквизиты: ДатаОтчета тип Дата,
- Табличные части: Сотрудники. Реквизиты табличной
части:
о «Сотрудник» тип
«СправочникСсылка. Физические Лица»,
Формы: РасчетыСотрудников,
Форма отчета должна выглядеть так.
87

Конфигурирование в системе "1 С:Предприятие 8.0". Решение расчетных задач
Макет: РасчетыСотрудников
В свойствах формы назначим (создадим) у формы обработчик события При открытии. В модуле формы документа в процедуре ПриОткрытии запишем:
Процедура ПриОткрытии()
ДатаОтчета= НачалоМесяца(РабочаяДата); КонецПроцедуры
Дата отчета при открытии всегда будет устанавливаться на начало месяца.
У элемента формы ДатаОтчета назначим обработчик события При изменении. В модуле формы документа в процедуре ДатаОтчетаПриИзменении запишем:
Процедура ДатаОтчетаПриИзменении(Элемент)
ДатаОтчета =НачалоМесяца( ДатаОтчета); КонецПроцедуры
При изменении даты отчета значение реквизита отчета ДатаОтчета всегда будет принимать дискретные значения, соответствующие началу месяца (для данной задачи месяц соответствует периодичности регистра расчета «РасчетыВсе», а начало месяца будет соответствовать периоду регистрации, за который мы и будем формировать отчет).
Решение задачи
В процедуре ОтчетРасчетыСотрудниковВсеНажатие, связанной с кнопкой «Сформировать», напишем.
Процедура КнопкаСформироватьНажатие(Элемент)
ТабДок = Новый ТабличныйДокумент;
ОтчетОбъект.ОтчетРасчетыСотрудниковВсе(ТабДок);
ТабДок. ТолькоПросмотр = Истина;
ТабДок.ОтображатьСетку = Ложь;
ТабДок.ОтображатьЗаголовки = Ложь;
ТабДок.Показать(); КонецПроцедуры
В модуле отчета пометим процедуру ОтчетРасчетыСотрудниковВсе.
Процедура ОтчетРасчетыСотрудниковВсе(ТабДок) Экспорт
Макет = ПолучитьМакет("РасчетыСотрудников");
Запрос = Новый Запрос; ТекстЗапроса = "ВЫБРАТЬ |РасчетыВсе.Подразделение КАК Подразделение, |РасчетыВсе.Должность КАК Должность, |РасчетыВсе.Сотрудник КАК Сотрудник, |РасчетыВсе.ВидРасчета КАК ВидРасчета, |ВЫБОР
|КОГДА ВидРасчета.Тип=Начисления ТОГДА СУММА(РасчетыВсе.Результат)
|КОНЕЦ КАК Начислено, |ВЫБОР
|КОГДА ВидРасчета.Тип=Удержания ТОГДА СУММА(РасчетыВсе.Результат)
|КОНЕЦ КАК Удержано, |ВЫБОР
|КОГДА ВидРасчета.Тип=Выплаты ТОГДА СУММА(РасчетыВсе.Результат)
|КОНЕЦ КАК Выплачено |ИЗ
|РегистрРасчета.РасчетыВсе КАК РасчетыВсе |ГДЕ
|РасчетыВсе.ПериодРегистрации = ДатаОтчета"; Условие=""; Если Сотрудники.Количество() о 0 Тогда
Условие = Условие + " И Сотрудник В Иерархии (СписокСотрудников)";
Запрос.УстановитьПараметр("СписокСотрудников",
Сотрудники.ВыгрузитьКолонкуС'Сотрудник"));
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + Условие;
ТекстЗапроса = ТекстЗапроса +"
89
зирование в системе "1С:Предприятие 8.0"..
|СГРУППИРОВАТЬ ПО
|РасчетыВсе.Подразделение,
|РасчетыВсе.Должность, |РасчетыВсе.Сотрудник, |РасчетыВсе.ВидРасчета
|упорядочить по
|Подразделение,
|Должность,
|Сотрудник
|ИТОГИ СУММА(Начислено),СУММА(Удержано),СУММА(Выплачено) ПО
|Подразделение,
|Должность,
|Сотрудник
|";
Запрос .Текст = ТекстЗапроса; Запрос УстановитьПараметр("ДатаОтчета", ДатаОтчета);
Запрос .УстановитьПараметр("Начисления", Перечисления.ТипыВидовРасчета.Начисление);
Запрос.У становитьПараметрС'Удержания", Перечисления.ТипыВидовРасчета.Удержание);
Запрос .У становитьПараметрС'Выплаты", Перечисления.ТипыВидовРасчета.Выплата); Результат = Запрос.Выподнить();
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок"); ОбластьЗаголовок.Параметры.ДатаОтчета=ДатаОтчета; ОбластьПодразделение = Макет.ПолучитьОбласть("Подразделение"); ОбластьДолжность = Макет.ПолучитьОбласть(" Должность"); ОбластьСотрудник = Макет.ПолучитьОбласть("Сотрудник"); ТабДок.Вывести(ОбластьЗаголовок);
Выбор каПодразделение Результат.ВыбратьСОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаПодразделение.Следующий() Цикл
ОбластьПодразделение.Параметры.Заполнить(ВыборкаПодразделение); ТабДок.Вывести(ОбластьПодразделение);
ВыборкаДолжность ВыборкаПодразделение.Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам);
Пока ВыборкаДолжность.Следующий() Цикл
ОбластьДолжность.Параметры.Заполнить (ВыборкаДолжность);
ТабДок.Вывести(ОбластьДолжность); ВыборкаСотрудник = ВыборкаДолжность.Выбрать(); Пока ВыборкаСотрудник.Следующий() Цикл
ОбластьСотрудник.Параметры.Заполнить(ВыборкаСотрудник); ТабДок.Вывести(ОбластьСотрудник);
Решение задачи
КонецЦикла; КонецЦикла; КонецЦикла; КонецПроцедуры
Комментарии.
В процедуре выполняется запрос к регистру расчета «РасчетыВсе». Запрос похож на то, что мы рассматривали ранее. Особый интерес представляют строки запроса:
|ВЫБОР
|КОГДА ВидРасчета.Тип=Начисления ТОГДА СУММА(РасчетыВсе.Результат)
|КОНЕЦ КАК Начислено, |ВЫБОР
|КОГДА ВидРасчета.Тип=Удержания ТОГДА СУММА(РасчетыВсе.Результат)
|КОНЕЦ КАК Удержано, |ВЫБОР
|КОГДА ВидРасчета.Тип=Выплаты ТОГДА СУММА(РасчетыВсе.Результат)
|КОНЕЦ КАК Выплачено
Означает это следующее: операторы ВЫБОР и КОНЕЦ определяют границы условия, в рамках которого используется конструкция КОГДА...ТОГДА...ИНАЧЕ. Читается это примерно так: добавляем в запрос колонку Начислено и помещаем туда результат расчета только тех видов расчета, которые являются начислениями (при этом используем функцию Сумма, соответственно, т.к. дальше в запросе мы используем группировки, по каждой группировочной строке будет автоматически осуществляться суммирование результатов) и т.д.
Затем результат запроса обрабатывается и используется для заполнения табличного документа.
91
Конфигурирование в системе "1С:Предприятие8,0". Решение расчетных задач
Практикум №1
Командировка
Реализуйте возможность начисления сотрудникам организации оплаты за командировку. Оплату командировочных необходимо производить в зависимости от среднего заработка сотрудника за три предыдущих расчетных периода. С этой целью необходимо выполнить следующее:
Вид расчета Командировка
Создайте в плане видов расчета ВсеВидыРасчета предопределенный вид расчета Командировка. Выполните настройку базы вида расчета Командировка, а также настройку вытеснения таким образом, чтобы вид расчета Командировка вытеснял вид расчета Оклад. Для этого определите базовые и вытесняющие виды расчета следующим образом:
[
Вид расчета
|
Базовые
|
Вытесняющие
|
Командировка
|
Оклад, ПремияПроцентом
|
|
Оклад
|
|
Командировка
|
Документ «Командировка»
Создайте документ Командировка.
Создайте реквизиты документа: ПериодРегистрации, ВидРасчета, График, ДатаНачала, ДатаОкончания, ДнейКомандировки, Сотрудник, Подразделение, Должность. Реквизит ДнейКомандировки должен рассчитываться автоматически при заполнении реквизитов ДатаНачала и ДатаОкончания и отражать количество дней по графику работы Шестидневка за период между датой начала и датой окончания командировки
Необходимо создать в справочнике ГрафикиРаботы график Шестидневка с типом графика Шестидневка и не забыть его заполнить.
Запрос по графику работы
Для получения количества отработанных дней по графику работы Шестидневка можно воспользоваться следующей функцией:
Функция ПолучитьКоличествоРабочихДней(ДН,ДК) КоличРабочихДней=0; Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ
92
Решение задачи
| СУММА(ГрафикиРаботы.Значение) КАК Значение
|ИЗ
| РегистрСведений.ГрафикиРаботы КАК ГрафикиРаботы
|
|ГДЕ
| (ГрафикиРаботы.Дата МЕЖДУ ДатаНачала И ДатаОкончания) И
| ГрафикиРаботы.ГрафикРаботы=График
|";
Запрос.УстановитьПараметрС'ДатаНачала", ДН); Запрос.УстановитьПараметр("ДатаОкончания", ДК); Запрос.УстановитьПараметр("График", График); Результат = Запрос.Выполнить(); Если Результат.Пустой() Тогда
Возврат 0; КонецЕсли;
Выборка= Результат.Выбрать(); Пока Выборка.Следующий() Цикл
КоличРабочихДней=Выборка.Значение; КонецЦикла;
Возврат КоличРабочихДней; КонецФункции
Создайте табличную часть Состав документа и в табличной части документа создайте реквизиты: Месяц типа Дата; ОтработаноДней типа Число; Зарплата типа Число. Создайте на командной панели кнопку «Заполнить строки». При нажатии на кнопку необходимо производить заполнение табличной части следующими данными:
- Колонка Месяц в табличной части должна заполняться
значениями периодов регистрации трех предыдущих расчетных
периодов.
- Колонка ОтработаноДней должна содержать информацию о
фактически отработанных сотрудником днях (по графику
Шестидневка) в соответствующих значениям из колонки Месяц
периодах.
- Колонка Зарплата должна содержать информацию о
заработной плате сотрудника в соответствующих значениям из
колонки Месяц периодах. Зарплата сотрудника должна
рассчитываться как сумма результатов видов расчета,
входящих в расчетную базу для вида расчета «Командировка».
Запросы по базе
При заполнении реквизита ОтработаноДней можно воспользоваться следующей функцией:
93
Функция ОгработаноПоБазе(Период)
//анализ фактического периода действия для Оклада
ЗапросФПД = Новый Запрос("ВЫБРАТЬ
| ФПД.ПериодДействияНачало КАК ФПДН,
| ФПД.ПериодДействияОкончание КАК ФПДО
|ИЗ
| РегистрРасчета.РасчетыВсе.ФактическийПериодДействия КАК ФПД
| ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ
| РегистрРасчета.РасчетыВсе КАК РасчетыВсе
| ПО РасчетыВсе.Регистратор = ФПД.Регистратор и
| РасчетыВсе.НомерСтроки = ФПД.НомерСтроки
|ГДЕ
| РасчетыВсе. ПериодДействия = Период И
| РасчетыВсе.Должность = Должность И
| РасчетыВсе.Подразделение = Подразделение И
| РасчетыВсе.Сотрудник = Сотрудник И
| РасчетыВсе.ВидРасчета = ВидРасчетаОклад");
ЗапросФПД.УстановитьПараметр("Период", Период);
ЗапросФПД.УстановитьПараметр(" Должность", Должность);
ЗапросФПД.УстановитьПараметр("Подразделение", Подразделение);
ЗапросФПД,УстановитьПараметр("Сотрудник", Сотрудник);
ЗапросФПД.УстановитьПараметр("ВидРасчетаОклад", ПланыВидовРасчега.ВсеВидыРасчета. Оклад);
Результат = ЗапросФПД.Выполнить(); Выборка= Результат.Выбрать();
Отработано=0;
Если Выборка.Количество()=0 Тогда
//анализ периода действия для Оклада
ЗапросПД = Новый Запрос();
В параметрах конструктора запроса (см. строку выше) необходимо написать текст запроса для получения периода действия записи регистра расчета «РасчетыВсе», содержащей внд расчета «Оклад», в рассматриваемом расчетном периоде для выбранного
сотрудника.
Результат = ЗапросПД.Выполнить(); Выбор ка= Результат.Выбрать(); Пока Выборка.Следующий() Цикл
Отработано=Отработано+
ПолучитьКоличествоРабочихДней(Выборка.ПДН,Выборка.ПДО);
КонецЦикла; Иначе
Пока Выборка.Следующий() Цикл
94
Решение задачи
Отработано=Отработано+ ПолучитьКоличествоРабочихДней(Выборка.ФПДН,Выборка.ФПДО);
КонецЦикла; КонецЕсли; Возврат Отработано; КонецФункции // ОтработаноПоБазе()
Комментарии.
В данной функции производится вычисление количества отработанных сотрудником дней за указанный период. Вычисление производится с учетом фактически отработанного сотрудником времени. При этом анализируется запись регистра расчетов, содержащая вид расчета Оклад. Сначала рассматривается фактический период действия записи. Если фактический период действия определен, производится вычисление фактически отработанного сотрудником времени по графику Шестидневка по каждой строке таблицы фактического периода действия, а затем накопление полученных результатов. В том случае, если фактический период действия не определялся, производится анализ записи. Также определяется количество отработанных сотрудником дней по графику Шестидневка.
Замечание. Ранее рассматривался метод ПолучитьДанныеГрафика, с помощью которого можно было очень просто получить количество отработанных сотрудником дней. В данной ситуации воспользоваться этим методом затруднительно, т.к. запись в регистр расчета еще не производилась.
При заполнении реквизита Зарплата можно воспользоваться следующей функцией:
Функция ПолучитьДанныеРасчетнойБазы(Период)
ЗапросБ = Новый Запрос("ВЫБРАТЬ
| СУММА(РасчетыВсе.Результат) КАК Результат
|ИЗ
| ПланВидовРасчета.ВсеВидыРаечета.БазовыеВидыРасчета КАК
ВсеВидыРасчетаБазовыеВидыРасчета
| ЛЕВОЕ ВНЕШНЕЕ СОЕДИНЕНИЕ
| РегистрРасчета.РасчетыВсе КАК РасчетыВсе
| ПО РасчетыВсе.ВидРасчета =
ВсеВидыРасчетаБазовыеВидыРасчета.ВидРасчета
|ГДЕ
| РасчетыВсе.ПериодДействия = Период И
| РасчетыВсе.Должность = Должность И
| РасчетыВсе.Подразделение = Подразделение И
| РасчетыВсе.Сотрудник = Сотрудник И
| ВсеВидыРасчетаБазовыеВидыРасчета.Ссылка = Командировка");
ЗапросБ.УстановитьПараметр("Период", Период); ЗапросБ.УстановитьПараметр(" Должность", Должность); ЗапросБ.УстановитьПараметр("Подразделение", Подразделение); ЗапросБ.УстановшъПараметрС'Сотрудник", Сотрудник);
ЗапросБ.УстановитьПараметрС'Командировка", ПланыВидовРасчета.ВсеВидыРасчета.Командировка);
Результат = ЗапросБ.Выполнить(); Если Результат.Пустой() Тогда
Возврат 0; КонецЕсли;
Выборка= Результат,Выбрать(); Пока Выборка,Следующий() Цикл
Зарплата=Выборка.Результат; КонецЦикла; Возврат Зарплата; КонецФункцни // ПолучитьДанныеРасчетнойБазы()
Комментарии.
В данной функции производится суммирование значений ресурса
Результат записей регистра расчета РасчетыВсе, входящих в базу
вида расчета Командировка, за выбранный период для выбранного
сотрудника.
Замечание. Ранее рассматривался метод ПолучитъБазу, с помощью
которого можно было очень просто получить базу для записей
регистра, удовлетворяющих заданному отбору. В данной ситуации
воспользоваться этим методом затруднительно, т.к. запись в
регистр расчета еще не производилась.
Создайте реквизит формы СреднедневнойЗаработок типа Число, а
также элемент управления формы надпись (свойство «Данные»
надписи свяжите с реквизитом формы СреднедневнойЗаработок), в
котором отображайте среднедневной заработок сотрудника за
несколько периодов. Формула для определения среднедневного
заработка должна быть следующая:
СреднедневнойЗаработок = Список.Итог( "Зарплата ")/
Список.Итог(''ОтработаноДней ").
При проведении документа Командировка необходимо вводить вид
расчета Командировка в регистр расчета РасчетыВсе.
В модуле документа Командировка реализуйте алгоритм расчета
результата начисления с учетом среднедневного заработка
сотрудника и количества дней в командировке.
В режиме исполнения назначьте командировку сотрудника Калошину
(Слесарь, Цех 1) с 10 по 20.02.2003г. При этом средний заработок
вычисляйте с учетом данных Января (при необходимости назначьте
Калошину в Январе Оклад, ПремиюПроцентом и Отпуск).
96
Peшeниe задачи
Замечание. В рассмотренной задаче производится попытка "эмулировать" работу функций ПолучитьДанныеГрафика и ПолучитьДанныеРасчетнойБазы. Сложность «ручной» реализации этих методов заставляет задуматься о методической правильности такого подхода. Кроме того, в данном примере для упрощения используется большое количество запросов, что сильно «утяжеляет» решение. Оптимальнее получать все необходимые данные "за один раз", а не "мельчить", создавая сетевой трафик и получая много мелких результатов запроса на клиента (хотя, конечно, всегда найдутся ситуации, когда надо поступать ровно наоборот).
Вывод - старайтесь пользоваться встроенными функциями и не делайте попыток их реализации другими средствами встроенного языка. Помните, что один «большой» запрос гораздо эффективнее нескольких «мелких».
97
Конфигурирование в системе "1 С:Предприятие 8.0". Решение расчетных задач
Решение 2. Несколько планов видов расчета и несколько регистров расчета
Планы видов расчета
Создадим несколько планов видов расчета.
Каждый план видов расчета будет содержать виды расчетов, которые можно объединить вместе по какому-либо присущему всем этим видам расчетам признаку.
Зачем мы это делаем? Чтобы не определять в планах видов расчета лишних свойств, как это было в Решении 1.
Создадим вместо одного четыре плана видов расчета:
- «ОсновныеНачисления»,
- «Премии»,
- «Удержания»,
- «Выплаты».
План видов расчета «ОсновныеНачисления»
Основные свойства:
- Имя: «ОсновныеНачисления»,
- Реквизиты: Тип (тип
«ПеречислениеСсылка.ТипыВидовРасчета»),
- Расчетные свойства:
- Формы: ФормаСписка, ФормаВидаРасчета.
- Предопределенные виды расчета,
Создадим следующие предопределенные виды расчета:
98
Решение задачи
План видов расчета «Премии»
Основные свойства:
- Имя: «Премии».
- Расчетные свойства:
Реквизиты: Тип
«ПеречислениеСсылка.ТипыВидовРасчета»).
- Формы: ФормаСписка, ФормаВидаРасчета.
- Предопределенные виды расчета
(тип

Важно! В свойствах планов видов расчета «ОсновныеНачисления» и «Премии» определим следующие Базовые планы видов расчета.
99
Конфигурироеание в системе " 1С:Предприятие 8.0". Решение расчетных задач
План видов расчета «Удержания»
Основные свойства:
- Имя: «Удержания»,
- Расчетные свойства:
Реквизиты: Тип
«ПеречислениеСсылка.ТипыВидовРасчета»).
Формы: ФормаСписка, ФормаВидаРасчета.
(тип

100
Предопределенные виды расчета
Решение задачи
В свойствах данного плана видов расчета на Базовые планы видов расчета определять не нужно, т.к. план видов расчета Удержания от базы не зависит.
План видов расчета «Выплаты»
Основные свойства:
- Имя: «Выплаты»,
- Расчетные свойства:

Реквизиты: Тип
«ПеречислениеСсылка.ТипыВидовРасчета»).
Формы: ФормаСписка, ФормаВидаРасчета.
(тип
Предопределенные виды расчета

В свойствах данного плана видов расчета Базовые планы видов расчета определять не нужно, т.к. план видов расчета Выплаты от базы не зависит.
101
Конфигурирование в системе " 1С:Предприятие 8.0". Решение расчетных задач
Предопределенные табличные части
Заполним предопределенные табличные части в каждом вновь созданном плане видов расчета (ПВР).
Базовые виды расчета. ПВР ОсновныеНачисления

ПВР Премии
ПВР Удержания Базовых нет.
ПВР Выплаты Базовых нет.
Вытесняющие виды расчета. ПВР ОсновныеНачисления

ПВР Премии Вытесняющих нет.
ПВР Удержания Вытесняющих нет.
ПВР Выплаты 102
Вытесняющих нет.
Замечание. Вытесняющие виды расчета должны быть в рамках одного плана видов расчета.
ПВР Премии

Ведущие виды расчета. ПВР ОсновныеНачисления

ПВР Удержания Ведущих нет.
ПВР Выплаты Ведущих нет.
Регистры расчета
Создадим несколько регистров расчета.
Каждый регистр расчета будет привязан к соответствующему ранее созданному плану видов расчета.
Создадим вместо одного четыре регистра расчета:
- «ОсновныеНачисления»,
- «Премии»,
- «Удержания»,
- «Выплаты».
Замечание. В реальных задачах вовсе не обязательно создавать для каждого плана видов расчета «свой» регистр расчета. С одним и тем же планом видов расчета могут быть связаны несколько регистров расчета.
103
Конфигурирование в системе " 1 С:Предприятие 8.0". Решение расчетных задач
Конфигурирование в системе
Регистр расчета «ОсновныеНачисления»
Основные свойства:
- Имя: «ОсновныеНачисления»,
- Вид расчета (план видов расчета):
«ОсновныеНачисления»,
- Период действия: установлен (это важно и для «Оклада»,
и для «Отпуска»),
- График: «ГрафикиРаботы»,
- Базовый период: имеется (важно для «Отпуска»);
- Периодичность: месяц.
104

Измерения:
о «Подразделение» тип
«СправочникСсылка.Подразделения»;
о «Должность тип СправочникСсылка.Должности»;
о «Сотрудник» тип
«СправочникСсылка.ФизическиеЛица».
Ресурсы:
о «Результат» тип Число длиной 10 точностью 2. Реквизиты:
о «График» тип
«СправочникСсылка.ГрафикиРаботы». Связь с графиком: «ГрафикРаботы».
Решение задачи
о «ПараметрРасчета»
точностью 2. Формы: ФормаСписка.
Перерасчеты: не имеется.
Регистр расчета «Премии»
Основные свойства:
тип Число длиной 10

Премии у нас не зависят от отработанного сотрудником времени, поэтому период действия и график не определяем. А вот базовый период нужен, т.к. имеется «ПремияПроцентом» (а процент берется от базы).
Измерения:
о «Подразделение» тип
«СправочникСсылка.Подразделения»;
о «Должность тип «СправочникСсылка.Должности»;
о «Сотрудник» тип
«СправочникСсылка. Физические Лица».
Ресурсы:
105
о «Результат» тип Число длиной 10 точностью 2. Реквизиты:
о «ПараметрРасчета» тип Число длиной 10
точностью 2. Формы: ФормаСписка.
Перерасчеты: «Перерасчет». Измерения:
о «Подразделение», о «Должность», о «Сотрудник».
Определжм связь измерений «Перерасчета» с измерениями регистра и данными базовых регистров.

106
Базовым регистром является регистр расчета «ОсновныеНачисления».
Регистр расчета Удержания
Основные свойства:
Решение задачи

Удержания не зависят от отработанного сотрудником времени, поэтому период действия и график не определяем. Базовый период также не нужен, т.к. вид расчета «Штраф» вводится суммой.
Измерения:
о «Подразделение» тип
«СправочникСсылка.Подразделения»;
о «Должность» тип
«СправочникСсылка. Должности»;
о «Сотрудник» тип
«СправочникСсылка. Физические Лица».
Ресурсы:
о «Результат» тип Число длиной 10 точностью 2. Реквизиты:
о «ПараметрРасчета» тип Число длиной 10 точностью 2.
Формы: ФормаСписка. Перерасчеты: Отсутствуют.
107
Конфигурирование в системе "1 С:Предприятие 8.0", Решение расчетных задач
Регистр расчета Выплаты
Основные свойства:
Выплаты (как и удержания) не зависят от отработанного сотрудником времени, поэтому период действия и график не определяем. Базовый период также не нужен, т.к. вид расчета «Выплата» вводится суммой.
Измерения:
о «Подразделение» тип
«СправочникСсылка.Подразделения»;
о «Должность» тип
«СправочникСсылка. Должности»;
о «Сотрудник» тип
«СправочникСсылка.ФизическиеЛица».
Ресурсы:
о «Результат» тип Число длиной 10 точностью 2. Реквизиты:
о «ПараметрРасчета» тип Число длиной 10 точностью 2.
Формы: ФормаСписка. Перерасчеты: Отсутствуют.
Документы для ввода записей в регистры расчета
Для ввода записей в регистры расчета создадим несколько новых
документов:
108
«ВводОсновныхНачисленийИУдержаний», «НачислениеПремий»,
Решение задачи
«Выплаты».
Замечание. Количество документов может быть и иным. Вообще количество и функциональность документов определяются не структурой и количеством регистров расчета и планов видов расчета, а скорее составом и функционалом реальных «бумажных» документов, используемых в организации.
Документ «ВводОсновныхНачисленийИУдержаний»
Данный документ будет использоваться для ввода записей в регистр расчета «ОсновныеНачисления» (будут вводиться начисления, определенные в плане видов расчета «ОсновныеНачисления» -«Оклады» и «Отпуска») и в регистр расчета «Удержания» (будут вводиться удержания, определенные в плане видов расчета «Удержания» - «Штрафы»).
Основные свойства:
Имя: «ВводОсновныхНачисленийИУдержаний».
Реквизиты:
о «ПериодРегистрации» тип Дата. Табличные части:
о Начисления
- «Сотрудник»: тип
«СправочникСсылка.ФизическиеЛица»,
- «Подразделение»: тип
«СправочникСсылка.Подразделения»,
- «Должность»: тип
«СправочникСсылка.Должности»,
- «График»: тип
«СправочникСсылка.ГрафикиРаботы»,
- «ВидРасчета»: тип
«ПланВидовРасчетаСсылка.ОсновныеНачис
ления»,
- «ДатаНачала»: тип Дата,
- «ДатаОкончания»: тип Дата,
a «Размер»: тип Число длина 10 точность 2, о Удержания
- «Сотрудник»: тип
«СправочникСсылка.ФизическиеЛица»,
- «Подразделение»: тип
«СправочникСсылка.Подразделения»,
- «Должность»: тип
«СправочникСсылка.Должности»,
- «ВидРасчета»: тип
«ПланВидовРасчетаСсылка.Удержания»,
- «Размер»: тип Число длина 10 точность 2.
109
Конфигурирование в системе "1С-.Предприятие 8.0"'. Решение расчетных задач
р
Формы:
о ФормаСписка, о ФормаДокумента.
Назначим обработчик события При изменении поля ввода Сотрудник в табличном поле Начисления.
Также назначим обработчик события При изменении поля ввода Сотрудник в табличном поле Удержания.
В модуле формы документа заполним соответствующие процедуры-обработчики событий.
Процедура НачисленияСотрудникПриИзменении(Элемент)
СписокСотрудникПриИзменении(Элемент,ЭлементыФормы.Начисления); КонецПроцедуры
Процедура УдержанияСотрудникПриИзменении(Элемент)
СписокСотрудникПриИзменении(Элемент,ЭлементыФормы.Удержания); КонецПроцедуры
Добавим в модуль
СписокСотрудникПриИзменении.
формы
Решение задачи II
Процедура СписокСотрудникПриИзменении(Элемент,Список) Запрос = Новый Запрос(" Выбрать Сотрудник.Наименование, Подразделение, Должность
Решение задачи
Из РегистрСведений.Сотрудники.СрезПоследних(парамДата, Сотрудник = парамСотрудник)
Где Состояние = парамСостояние
I");
Запрос.УстановитьПараметрС'парамДата", Дата); Запрос.УстановитьПараметрС'парамСотрудник", Элемент.Значение);
Запрос.УстановитьПараметр("парамСостояние", Перечисления.СостоянияФизлица.Работает);
МестаРаботы = Запрос.Выполнить().Выгрузить(); Если МестаРаботы.Количество()=0 Тогда
Предупреждение(""+Элемент.3начение+" не работает в организации "+Константы.НазваниеОрганизации);
ИначеЕсли МестаРаботы.Количество()=1 Тогда
Подразд = МестаРаботы[0] .Подразделение;
Список. ТекущиеДанные.Подразделение = Подразд;
Список.ТекущиеДанные.Должность = МестаРаботы[0] .Должность; Иначе
ВыбраннаяСтрока = МестаРаботы.ВыбратьСтрокуС'Выберите место работы");
Если ВыбраннаяСтрока о НЕОПРЕДЕЛЕНО Тогда Подразд = ВыбраннаяСтрока.Подразделение;
Список.ТекущиеДанные.Подразделение =
ВыбраннаяСтрока.Подразделение;
Список.ТекущиеДанные.Должность =
ВыбраннаяСтрока.Должность;
КонецЕсли; КонецЕсли;
КонецПроцедуры
Комментарии.
Процедура такая же, какую мы рассматривали в документе «НачислениеЗарплатыВсей».
Назначим обработчик события При изменении поля ввода ВидРасчета в табличном поле Начисления.
Процедура НачисленияВидРасчетаПриИзменении(Элемент)
Если Элемент.Значение=ПланыВидовРасчета.ОсновныеНачисления.Оклад Тогда Запрос = Новый Запрос(" Выбрать Сотрудник, Подразделение, Должность, Оклад, Регистратор
Из РегистрСведений.Сотрудники.СрезПоследних(парамДата,
(Сотрудник = парамСотрудвик) и (Подразделение = парамПодразделение) и (Должность = парамДолжность))
I");
Запрос.УстановитьПараметр("парамДата", Дата);
111
Запрос.УстановитьПараметрС'парамСотрудник", ЭлементыФормы.Начиспения.ТекущиеДанные.Сотрудник);
Запрос.УстановитьПараметр("парамПодразделение", ЭлементыФормы.Начисления.ТекущиеДанные.Подразделение);
Запрос.УстановитьПараметр("парамДолжность", ЭлементыФормы.Начисления.ТекущиеДанные.Должность);
ТЗОклад = Запрос.Выполнить().Выгрузить(); Если ТЗОклад.Количество()0 Тогда ОкладВСписок= ТЗОклад[0].Оклад;
Если ТипЗнч(ОкладВСписок)=Тип("Число") Тогда
ЭлементыФормы.Начисления.ТекущиеДанные.Размер =
ОкладВСписок;
ИначеЕсли ТипЗнч(ОкладВСписок)=Тип("СправочникСсылка.ЕТС") Тогда
ЭлементыФормы.Начисления.ТекущиеДанные.Размер = Число(ОкладВСписок.Наименование);
КонецЕсли;
КонецЕсли; КонецЕсли; КонецПроцедуры
Комментарии. Процедура такая же, какую мы рассматривали в документе «НачислениеЗарплатыВсей».
- Движения: РегистрыРасчета:
о ОсновныеНачисления, о Удержания
Одновременное создание записей в нескольких регистрах расчета
В ОбработкеПроведения документа реализуем одновременную запись в несколько регистров расчета.
Процедура ОбработкаПроведения(Отказ, РежимПроведения)
//начисления
Для Каждого Строка Из Начисления Цикл
Движение = Движения. ОсновныеНачисления.Добавить();
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.ПериодДействияНачало = Строка.ДатаНачала;
Движение.ПериодДействияОкончание = Строка.ДатаОкончания;
Движение.Сотрудник = Строка.Сотрудник;
Двнжение.Подразделение = Строка.Подразделение;
Движение. Должность = Строка. Должность;
Движение.График = Строка.График;
112
Решение задачи
Движение.ВидРасчета = Строка.ВидРасчета; Движение.ПараметрРасчета = Строка.Размер;
Если Строка.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.Отпуск Тогда
Движение.БазовыйПериодНачало =
ДобавитьМесяц(Движение.ПериодДействия, -3);
Движение.БазовыйПериодОкончание =
Движение.ПериодДействия-1;
КонецЕсли; КонецЦикла; Движения.ОсновныеНачисления.ЗаписатьО;
РегистрМенеджер=РегистрыРасчета.ОсновныеНачисления;
Отбор= Новый Структура("Регистратор",Ссылка);
Ресурсы = Новый Массив( 1);
Ресурсы[0] = "ОсновныеНачисления.Резудьтат,Премии.Результат";
Измерения= Новый Структура();
Измерения.Вставить("Подразделение","ОсновныеНачисления.Подразделение,Прем
ии.Подразделение");
Измерения.Вставить("Должность","ОсновныеНачисления.Должность,Премии.Долж ность");
Измерения.Вставить("Сотрудник","ОсновныеНачисления.Сотрудник,Премии.Сотру
дник");
ДанныеБазы = РегистрМенеджер.ПолучитьБазу(Отбор,Ресурсы,Измерения);
Отработано =
РегистрМенеджер.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета.Фактическ
ийПериодДействия);
Норма =
РегистрМенеджер.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета.ПериодРег
истрации);
ОтработаноПоБазе =
РегистрМенеджер.ПолучитьДанныеГрафика(Отбор,ВидПериодаРегистраРасчета.БазовыйП
ериод);
Для Каждого Движение Из Движения.ОсновныеНачисления Цикл
Движение.Результат = РассчитатьНачисленияУдержания(Движение, Движения.ОсновныеНачисления.Индекс(Движение), ДанныеБазы, Отработано, Норма, ОтработаноПоБазе);
КонецЦикла;
//удержания
Для Каждого Строка Из Удержания Цикл
Движение = Движения.Удержания.Добавить();
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.Сотрудник = Строка. Сотрудник;
Движение.Подразделение = Строка.Подразделение;
Движение.Должность = Строка. Должность;
Движение.ВидРасчета = Строка.ВидРасчета;
Движение.ПараметрРасчета = Строка.Размер; КонецЦикла;
Движения.Удержания.Записать(); Для Каждого Движение Из Движения.Удержания Цикл
Движение.Результат = РассчитатьНачисленияУдержания(Движение, Движения.Удержания.Индекс(Движение), ,,,)'
КонецЦикла; КонецПроцедуры
Комментарии.
Процедура похожа на соответствующую процедуру в документе «Начис л ениеЗарпл атыВ сей».
Отличия в следующем:
сначала вводятся начисления, затем вводятся удержания.
При вводе начислений интересно использование метода ПолучитъБазу. В параметрах метода выполняется обращение не к одному, а к двум регистрам расчета, поскольку расчет «Отпуска» производится с использованием записей регистра расчета «ОсновныеНачисления» и регистра расчета «Премии».
РегистрМенеджер=РегистрыРасчета.ОсновныеНачисления;
Отбор= Новый СтруктураО;
Отбор. Вставить("Регистратор",Ссылка);
Ресурсы = Новый Массив(1);
Ресурсы[0] = "ОеновныеНачисления.Результат,Премии.Результат";
Измерения= Новый СтруктураО;
Измерения.Вставить("Подразделение","ОсновныеНачисления.Подразделение,Прем ии.Подразделение");
Измерения.Вставить(" Должность", "ОсновныеНачисления.Должность,Премии.Долж ность");
Измерения.Вставить("Сотрудник","ОсновныеНачисления.Сотрудник,Премии.Сотру
дник");
ДанныеБазы = РегистрМенеджер.ПолучитьБазу(Отбор,Ресурсы,Измерения);
Проверим работу программы в режиме «1С:Предприятие». Создадим ряд документов по вводу расчетов.
Замечание. Создаваемые документы пока не будем проводить (для корректного проведения нам потребуется поправить алгоритм в функции «РассчитатьНачисленияУдержания»). Документы требуется лишь записать, нажав на кнопку «Записать».
Расчеты за январь (Период регистрации - 1 января).
114
Решение задачи
Документ окладов:
"ВводОсновныхНачисленийИУдержаний" для ввода
Документ «ВводОсновныхНачисленийИУдержаний» для ввода штрафа:
Расчеты за февраль (Период регистрации - 1 февраля).
Документ «ВводОсновныхНачисленийИУдержаний» окладов и штрафа:
для ввода
115

Конфигурирование в системе "1С:Предприятие 8.0". Решение расчетных задач
Документ «НачислениеПремий»
Данный документ будет использоваться для ввода записей в регистр расчета «Премии» (будут вводиться премии).
Основные свойства:
Имя: «НачислениеПремий». Реквизиты:
о «ПериодРегистрации» тип Дата. Табличные части:
о Список
- «Сотрудник»: тип
«СправочникСсылка.ФизическиеЛица»,
- «Подразделение»: тип
«СправочникСсылка.Подразделения»,
- «Должность»: тип
«СправочникСсылка.Должности»,
- «ВидРасчета»: тип
«ПланВидовРасчетаСсылка.Премии»,
- «ДатаНачала»: тип Дата,
- «ДатаОкончания»: тип Дата,
- «Размер»: тип Число длина 10 точность 2,
- «Сторно»: тип Булево.
Формы:
о ФормаСписка, о ФормаДокумента.
116
Решение задачи

Назначим обработчик события При изменении поля ввода Сотрудник в табличном поле Список.
В модуле формы документа заполним процедуру-обработчик события.
Процедура СписокСотрудникПриИзменении(Элемент) Запрос = Новый Запрос(" Выбрать Сотрудник.Наименование, Подразделение, Должность
Из РегистрСведений.Сотрудники.СрезПоследних(парамДата, Сотрудник = парамСотрудник)
Где Состояние = парамСостояние
I");
Запрос.УстановитьПараметр("парамДата", Дата); Запрос.УетановитьПараметр("парамСотрудник", Элемент.Значение);
Запрос.УстановитьПараметр("парамСостояние", Перечисления.СостоянияФизлица.Работает);
МестаРаботы = Запрос.Выполнить().Выгрузить(); Если МестаРаботы.Количество()=0 Тогда
Предупреждение(""+Элемент.3начение+" не работает в организации "+Константы.НазваниеОрганизации);
ИначеЕсли МестаРаботы.Количество()=1 Тогда
Подразд = МестаРаботы [0] .Подразделение; ЭлементыФормы.Список.ТекущиеДанные.Подразделение = Подразд;
ЭлементыФормы.Список.ТекущиеДанные.Должность =
МестаРаботы[0] .Должность;
Иначе
ВыбраннаяСтрока = МестаРаботы.ВыбратьСтроку("Выберите место
работы");
Если ВыбраннаяСтрока о НЕОПРЕДЕЛЕНО Тогда Подразд = ВыбраннаяСтрока.Подразделение;
ЭлементыФормы. Список. ТекущиеДанные.Подразделение =
ВыбраннаяСтрока.Подразделение;
ЭлементыФормы.Список.ТекущиеДанные.Должность =
ВыбраннаяСтрока.Должность;
КонецЕсли;
117
8.0". Решение расчетных задач
КонецЕсди; КонецПро цедуры
Комментарии.
Процедура такая же, как и процедура в документе «НачислениеЗарплатыВсей».
- Проведение: Разрешить,
- Движения: РегистрыРасчета: «Премии»,
В ОбработкеПроведения документа запишем следующее.
Процедура ОбработкаПроведения(Отказ, РежимПроведения) Для Каждого Строка Из Список Цикл
Движение = Движения.Премии.Добавить();
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.БазовыйПериодНачало = Строка.ДатаНачала;
Движение.БазовыйПериодОкончание = Строка.ДатаОкончания;
Движение.Сотрудник = Строка.Сотрудник;
Движение.Подразделение = Строка.Подразделение;
Движение.Должность = Строка. Должность;
Движение.ВидРасчета = Строка.ВидРасчета;
Движение.ПараметрРасчета = Строка.Размер;
Движение. Сторно = Строка. Сторно; КонецЦикла; Движения.Премии.Записать();
РегистрМенеджер=РегистрыРасчета.Премии;
Отбор= Новый Структура("Регистратор",Ссылка);
Ресурсы = Новый Массив(1);
Ресурсы[0] = "ОсновныеНачисления.Результат";
Измерения= Новый Структура();
Измерения.Вставить("Подразделение","ОсновныеНачисления.Подразделение");
Измерения.Вставить(" Должность","ОсновныеНачисления.Должность");
Измерения.Вставить("Сотрудник","ОсновныеНачисления.Сотрудник");
ДанныеБазы = РегистрМенеджер .ПолучитьБазу(Отбор,Ресурсы,Измерения);
Для Каждого Движение Из Движения.Премии Цикл
Движение.Результат = РассчитатьНачисленияУдержания(Движение, Движения.Премии.Индекс(Движение), ДанныеБазы,,,);
КонецЦикла; КонецПроцедуры
Комментарии.
118
Решение задачи
Процедура похожа на соответствующую процедуру в документе «НачислениеЗарплатыВсей».
Отличия в следующем:
в данной процедуре используется только переменная
ДанныеБазы. Понятия ОтработанныеДни, НормаДней и
ОтработанныеПоБазеДни при расчете
«ПремииПроцентом» не используются.
В режиме «1С:Предприятие» создадим ряд документов по вводу премии.
Замечание. Создаваемые документы также пока не будем проводить, а лишь запишем, нажав на кнопку «Записать».
Расчеты за февраль (Период регистрации - 1 февраля).
Расчеты за январь (Период регистрации - 1 января).

Документ Выплаты
Данный документ будет обеспечивать ввод записей в регистр расчета «Выплаты» (будут вводиться выплаты зарплаты).
119
Конфигурирование в системе " 1 С:Предприятие8,0".
Основные свойства:
Имя: «Выплаты». Реквизиты:
о «ПериодРегистрации» тип Дата.
Табличные части:
тип
«СправочникСсылка.ФизическиеЛица»,
«Подразделение»: тип
«СправочникСсылка.Подразделения»,
«Должность»: тип
«СправочникСсылка.Должности»,
«ВидРасчета»: тип
«ПланВидовРасчетаСсылка.Выплаты», «Размер: тип Число длина 10 точность 2.
о Список
«Сотрудник»:
Формы:
о ФормаСписка, о ФормаДокумента.

Назначим обработчик события При изменении поля ввода Сотрудник в табличном поле Список.
В модуле формы документа заполним процедуру-обработчик события.
Процедура СписокСотрудникПриИзменении(Элемент)
// Вставить содержимое обработчика.
Запрос = Новый Запрос("
Выбрать Сотрудник.Наименование, Подразделение, Должность
Из РегистрСведений.Сотрудники.СрезПоследних(парамДата, Сотрудник = парамСотрудник)
Где Состояние = парамСостояние
120
Решение задачи
I");
Запрос. УстановитьПараметр("парамДата", Дата);
Запрос.УстановитьПараметр("парамСотрудник", Элемент.Значение);
Запрос.УстановитьПараметрС'парамСостояние", Перечисления.СостоянияФизлица.Работает);
МестаРаботы = Запрос.Выполнить().Выгрузить(); Если МестаРаботы.Количество()=0 Тогда
Предупреждение(""+Элемент.3начение+" не работает в организации "+Константы.НазваниеОрганизации);
ИначеЕсли МестаРаботы.Количество()=1 Тогда
Подразд = МестаРаботы [0] .Подразделение; ЭлементыФормы.Список.ТекущиеДанные.Подразделение = Подразд;
ЭлементыФормы.Список.ТекущиеДанные.Должность =
МестаРаботы [0] .Должность;
Иначе
ВыбраннаяСтрока = МестаРаботы.ВыбратьСтроку("Выберите место работы");
Если ВыбраннаяСтрока о НЕОПРЕДЕЛЕНО Тогда Подразд = ВыбраннаяСтрока.Подразделение;
ЭлементыФормы.Список.ТекущиеДанные.Подразделение =
ВыбраннаяСтрока.Подразделение;
ЭлементыФормы.Список. ТекущиеДанные.Должность =
ВыбраннаяСтрока.Должность;
КонецЕсли; КонецЕсли; КонецПроцедуры
Комментарии.
Процедура такая же, как и процедура в документе «НачислениеЗарплатыВсей».
- Проведение: Разрешить,
- Движения: РегистрыРасчета: «Выплаты»,
В ОбработкеПроведения документа запишем следующее.
Процедура ОбработкаПроведения(Отказ, РежимПроведения) Для Каждого Строка Из Список Цикл
Движение = Движения.Выплаты.Добавить(); Движение.ПериодРегистрации = ПериодРегистрации; Движение.Сотрудник = Строка.Сотрудник; Движение.Подразделение = СтрокаЛодразделение; Движение.Должность = Строка. Должность; Движение.ВидРасчета = Строка.ВидРасчета;
121
Движение.ПараметрРасчета = Строка.Размер; КонецЦикла;
Движения.Выплаты.ЗаписатьО; Для Каждого Движение Из Движения.Выплаты Цикл
Движение.Результат = РассчитатьНачисленияУдержания(Движение, Движения.Выпплаты.Ивдекс(Движение),,,,);
Коне цЦикла; КонецПроцедуры
Комментарии.
Процедура похожа на соответствующую процедуру в документе «НачислениеЗарплатыВсей».
Отличия в следующем:
в данной процедуре переменные ДанныеБазы,
ОтработанныеДни, НормаДней и
ОтработанныеПоБазеДни не используются.
В режиме «1С:Предприятие» создадим ряд документов по вводу выплат.
Замечание. Создаваемые документы проводить не будем, но запишем их, нажав на кнопку «Записать».
Введем только выплаты за январь (Период регистрации - 1 января).

Расчет результатов начислений, удержаний, выплат по нескольким регистрам расчета
Для корректного расчета результатов в процедуру РассчитатъНачисленияУдержания необходимо внести изменения. А
именно, необходимо добавить в соответствующих местах названия
122
Решение задачи
новых регистров расчета (добавленные строки выделены жирным шрифтом).
Функция РассчитатьНачисленияУдержания(СтрокаДвижений, Индекс, ДанныеБазы, Отработано, Норма, ОтработаноПоБазе) Экспорт
Если (СтрокаДвижений.ВидРасчета = ПланыВидовРасчета.ВсеВидыРасчета.Оклад)
Или (СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета.ОсновныеНачисления.Оклад) Тогда
НормаДней = Норма[Индекс].Значение; Если НормаДней = 0 Тогда
Сообщить("Расчет оплаты по окладу: Нет рабочих дней в заданном периоде", СтатусСообщения.Информация);
Возврат 0; Иначе
Если СтрокаДвижений.Сторно Тогда
Возврат -СтрокаДвижений.ПараметрРасчета; Иначе
Возврат СтрокаДвижений.ПараметрРасчета *
Отработано [Индекс] .Значение/НормаДней * ?(СтрокаДвижений. Сторно,-1,1);
КонецЕсли; КонецЕсли;
ИначеЕсли (СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета.ВсеВидыРасчета.ПремияПроцентом) или
(СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета.Премии.ПремияПроцентом)Тогда
Если СтрокаДвижений.Сторно Тогда
Возврат-СтрокаДвижений.ПараметрРасчета; Иначе
Возврат
ДанныеБазы[Индекс].Результат*СтрокаДвижений.ПараметрРасчета/100;
КонецЕсли;
ИначеЕсли (СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета.ВсеВидыРасчета.Отпуск) или
(СтрокаДвижений.ВидРасчета =
ПланыВидовРасчета.ОсновныеНачисления.Отпуск) Тогда
Отработано Дней = ОтработаноПоБазе [Индекс] .Значение; Если ОтработаноДней = 0 Тогда
Сообщить("Расчет отпуска: Нет рабочих дней в базовом периоде", СтатусСообщения.Информация);
Возврат 0; Иначе
Возврат ДанныеБазы[Индекс].Результат/Отработано Дней * Отработано [Индекс]. Значение * ?(СтрокаДвижений.Сторно,-1,1);
КонецЕсли;
123
Конфигурирование в системе 1С:Предприятие 8.0 . Решение расчетных задач
ИначеЕсли (СтрокаДвижений.ВидРасчета
ПланыВидовРасчета.ВсеВидыРасчета.ШтрафСуммой) ИЛИ
(СтрокаДвижений.ВидРасчета ПланыВидовРасчета.ВсеВидыРасчета.Выплата) или
(СтрокаДвижений.ВидРасчета ПланыВидовРасчета.Удержания.ШтрафСуммой) ИЛИ
(СтрокаДвижений.ВидРасчета ПланыВидовРасчета.Выплаты.Вьшлата) Тогда
Возврат СтрокаДвижений.ПараметрРасчета; КонецЕсли; Возврат 0; КонецФункции
В режиме «1С:Предприятие» проведем ранее созданные и записанные документы.
Замечание. Для быстрого проведения документов можно воспользоваться возможностью пакетного проведения документов (меню «Операции» - «Проведение документов...»).
Посмотрите на результаты расчетов в регистрах расчета «ОсновныеНачисления», «Премии», «Удержания» и «Выплаты».
Вытеснение видов расчета из разных регистров расчета
Рассмотрим, как работает вытеснение видов расчета при использовании нескольких регистров расчета.
Проведем документ «ВводОсновныхНачисленийИУдержаний» для ввода «Отпуска».

Перепроведем документ, которым начислялся «Оклад» в феврале.
Внимание! Документ, который ввел в феврале премию (в регистре расчета «Премии») пока перепроводить не нужно!
124
Посмотрим, что получилось в регистре расчетов «ОсновныеНачисления» - результат «Оплаты по окладу» изменился.

Перерасчет записей регистра расчета. Взаимное влияние записей разных регистров расчета
Изменим несколько строк в обработке «Перерасчет зарплаты» (строки, которые нужно изменить выделены жирным курсивом).
Процедура ЗаполнитьДанныеО Экспорт Запрос = Новый Запрос(
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| ИСТИНА КАК Пометка,
| ОбъектПерерасчета КАК Документ
|ИЗ
| РегистрРасчета.РасчетыВсе.Перерасчет
| РегистрРасчета.Премии.Перерасчет
I");
ДокументыПерерасчета.Загрузить(Запрос.Выполнить().Выгрузить()); КонецПроцедуры
Процедура ОбновитьСписокПерерасчетов(Документ)
//НаборПерерасчета РегистрыРасчета.РасчетыВсе.Перерасчеты.Перерасчет.СоздатьНаборЗаписей();
НаборПерерасчета РегистрыРасчета.Премии.Перерасчеты.Перерасчет.СоздатьНаборЗаписей();
НаборПерерасчета.Отбор.ОбъектПерерасчета.Значение = Документ;
НаборПерерасчета.Прочитать();
СтрокиПерерасчета.Очистить();
Для Каждого Строка Из НаборПерерасчета Цикл
СтрокаТЗ=СтрокиПерерасчета.Добавить();
СтрокаТЗ.ВидРасчета=Строка,ВидРасчета;
СтрокаТЗ.Подразделение=Строка.Подразделение;
СтрокаТЗ.Должность=Строка.Должность;
СтрокаТЗ.Сотрудник=Строка.Сотрудник;
125
КонецЦикла; КонецПроцедуры
В модуль документа «Начисление премий» добавим процедуры Перерассчитать, ОбработкаЗаполнения и ВвестиПерерасчет:
Процедура Перерассчитать() Экспорт НачатьТранзакциюО;
НаборПерераечетов =
РегистрыРасчета.Премии.Перерасчеты.Перерасчет.СоздатьНаборЗаписей();
НаборПерераечетов.Отбор.ОбъектПерерасчета.Значение = Ссылка;
НаборПерерасчетов,Прочитать();
Отбор= Новый Структура();
Отбор.Вставить("Регистратор",Ссылка);
Ресурсы = Новый Массив( 1);
Ресурсы[0] = "ОсновныеНачисления.Результат";
Измерения= Новый Структура();
Измерения.Вставить("Подразделение","ОсновныеНачисления.Подразделение");
Измерения.Вставить(" Должность","ОсновныеНачисления.Должность");
Измерения.Вставить("Сотрудник","ОсновныеНачисления.Сотрудник");
ДанныеБазы = РегистрыРасчета.Премии.ПолучитьБазу(Отбор,Ресурсы,Измерения);
Движения.Премии.Прочитать();
Таблица = Движения.Премии.Выгрузить();
СтруктураПоиска = Новый Структура("Подразделение,Должность,Сотрудник");
Для Каждого СтрокаПерерасчета Из НаборПерераечетов Цикл
СтруктураПоиска.Подразделение = СтрокаПерерасчета.Подразделение;
СтруктураПоиска.Должность = СтрокаПерерасчета.Должность;
СтруктураПоиска. Сотрудник = СтрокаПерерасчета.Сотрудник;
Для Каждого СтрокаРегистра Из Таблица.НайтиСтроки(СтруктураПоиска) Цикл
СтрокаРегистра.Результат =
РассчитатьНачисленияУдержания(СтрокаРегистра, Таблица.Индекс(СтрокаРегистра),
ДанныеБазы,,,);
КонецЦикла; КонецЦикла;
Движения.Премии.Загрузить(Таблица); Движения.Премии.Записать(); НаборПерераечетов.Очистить(); НаборПерераечетов.Записать(); ЗафиксироватьТранзакцию(); КонецПроцедуры
Процедура ОбработкаЗаполнения(Основание)
126
Решение задачи
ПериодРегистрации = НачалоМесяца(ТекущаяДатаО); Дата = ТекущаяДата(); КонецПроцедуры
Процедура ВвестиПерерассчет() Экспорт Начать Транзакцию();
НаборПерерасчетов =
Регистр ыРасчета.Премии,Перерасчеты.Перерасчет.СоздатьНаборЗаписей();
НаборПерерасчетов.Отбор.ОбъектПерерасчета.Значение = Ссылка;
НаборПерерасчетов.Прочитать();
ДокументПерерасчета = Документы.НачислениеПремий.СоздатьДокумент();
ДокументПерерасчета.Заполнить(Ссылка);
Запрос = Новый Запрос(
"ВЫБРАТЬ
I*
|ИЗ
|РегистрРасчета.Премии
ГДЕ РегистрРасчета.Премии.Регистратор=парДокументОбъект
|");
Запрос.УстановитьПараметрС'парДокументОбъект", Ссылка); Таблица =Запрос.Выполнить().Выгрузить();
СтруктураПоиска = Новый Структура("Подразделение,Должность,Сотрудник"); Для Каждого СтрокаПерерасчета Из НаборПерерасчетов Цикл
СтруктураПоиска.Подразделение = СтрокаПерерасчета.Подразделение;
СтруктураПоиска. Должность = СтрокаПерерасчета. Должность;
СтруктураПоиска.Сотрудник = СтрокаПерерасчета. Сотрудник;
Для Каждого СтрокаРегистра Из Таблица.НайтиСтроки(СтруктураПоиска)
Цикл
НоваяСтрока = ДокументПерерасчета. Список. Добавить(); НоваяСтрока.Сотрудник = СтрокаРегистра. Сотрудник; НоваяСтрока.Подразделение = СтрокаРегистра.Подразделение; НоваяСтрока. Должность = СтрокаРегистра. Должность; НоваяСтрока.ВидРасчета = СтрокаРегистра.ВидРасчета;
НоваяСтрока.ДатаНачала =
СтрокаРегистра.БазовыйПериодНачало;
НоваяСтрока.ДатаОкончания =
СтрокаРегистра.БазовыйПериодОкончание;
НоваяСтрока.Размер = СтрокаРегистра.Результат; НоваяСтрока.Сторно = Истина;
НоваяСтрока = ДокументПерерасчета,Список.Добавить(); НоваяСтрока.Сотрудник = СтрокаРегистра.Сотрудник; НоваяСтрока.Подразделение = СтрокаРегистра.Подразделение;
127
Конфигурирование в системе "1С:Предприятие 8.0". Решение расчетных задач
НоваяСтрока.Должность = СтрокаРегистра.Должность; НоваяСтрока.ВидРасчета = СтрокаРегистра.ВидРасчета;
НоваяСтрока.ДатаНачала СтрокаРегистра.БазовыйПериодНачало;
НоваяСтрока.ДатаОкончания СтрокаРегистра.БазовыйПериодОкончание;
НоваяСтрока.Размер = СтрокаРегистра.ПараметрРасчета; КонецЦикла; КонецЦикла;
ДокументПерерасчета. Записать(); НаборПерерасчетов.Очистить(); НаборПерерасчетов.Записать(); ЗафиксироватьТранзакцию(); КонецПроцедуры
Комментарии.
Приведенные процедуры практически ничем не отличаются от процедур в документе «НачислениеЗарплатыВсей». Отличия - в именах регистров расчета.
В предыдущем разделе после ввода отпуска сотруднику Ивановой, был перерассчитан оклад. В соответствии с настройками свойства Ведущие виды расчетов плана видов расчета «Премии», должен быть выполнен перерасчет февральской «ПремииПроцентом».
Откроем обработку «Перерасчет зарплаты».
При открытии заполнится табличная часть. На этот раз сюда попадет документ, которым вводилась премия в регистр расчета Премии.

Нажмем кнопку «Выполнить перерасчет».
Если константа «ДатаЗапретаРедактирования» имеет значение большее, чем 01.01.2003 00.00.00 (дата проведения документа), тогда будет создан документ-перерасчет.
128
Решение задачи

После проведения которого в регистре расчета «Премии» появятся сторнирующая и корректирующая записи.

Если константа «ДатаЗапретаРедактирования» имеет значение меньше или равное дате проведения документа, тогда будет выполнен перерасчет документа (будут пересчитаны те записи, которые попали в перерасчет).
Отчет Расчеты сотрудников по нескольким регистрам расчета
Создадим отчет, который будет выдавать информацию о состоянии расчетов сотрудников (отчет по функционалу такой же, какой мы уже создавали), но теперь при создании отчета будем обращаться к нескольким регистрам расчета.
В результате работы отчета должно получиться примерно следующее.
129

Конфигурирование в системе "1С:Предприятие 8.0". Решение расчетных задач
Основные свойства отчета полностью совпадают со свойствами отчета
«РасчетыСотрудниковВсе». Поэтому создадим отчет
«РасчетыСотрудников» путем копирования отчета
«РасчетыСотрудниковВсе».
Имя: «РасчетыСотрудников». Реквизиты: ДатаОтчета тип Дата, Табличные части: Сотрудники. Реквизиты табличной части:
о «Сотрудник» тип
«СправочникСсылка.ФизическиеЛица».
Формы: РасчетыСотрудников. Макет: РасчетыСотрудников.
По сравнению с отчетом «РасчетыСотрудниковВсе» серьезно изменится лишь запрос к информационной базе (алгоритм обработки запроса не изменится).
Запрос к нескольким регистрам расчета
ТекстЗапроса = "ВЫБРАТЬ
|Расчеты.Подраздеяение КАК Подразделение,
|Расчеты.Должность КАК Должность,
|Расчеты,Сотрудник КАК Сотрудник,
|Расчеты.ВидРаечета КАК ВидРасчета,
|Расчеты.Начислено,
|Расчеты.Удержано,
|Расчеты.Выплачено
|ИЗ
|(ВЫБРАТЬ
130
Решение задачи
|НачисленияОсн.Подразделение КАК Подразделение, |НачисденияОсн.Должность КАК Должность, |НачисленияОсн. Сотрудник КАК Сотрудник, |НачисленияОсн.ВидРасчета КАК ВидРасчета, |ВЫБОР
|КОГДА
ТОГДА
ВидРасчета.Тип=Начисления
СУММА(НачисленияОсн.Результат)
|КОНЕЦ КАК Начислено, |0 КАК Удержано, |0 КАК Выплачено |ИЗ
|РегистрРасчета.ОсновныеНачисления КАК НачисленияОсн |ГДЕ
|НачисленияОсн.ПериодРегистрации = ДатаОтчета"; Условие=""; Если Сотрудники.Количество() о 0 Тогда
Условие = Условие + " И Сотрудник В Иерархии (СписокСотрудников)";
Запрос.УстановитьПараметр("СписокСотрудников", Сотрудники. ВыгрузитьКолонку("Сотрудник"));
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + Условие;
ТекстЗапроса = ТекстЗапроса +"
|СГРУППИРОВАТЬ ПО
|НачисленияОсн.Подразделение,
|НачисленияОсн.Должность,
|НачисленияОсн.Сотрудник,
|НачисленияОсн .В идРасчета
|ОБЪЕДИНИТЬВСЕ
|ВЫБРАТЬ
|Премии.Подразделение КАК Подразделение,
|Премии.Должность КАК Должность,
|Премии.Сотрудник КАК Сотрудник,
|Премии.ВидРасчета КАК ВидРасчета,
|ВЫБОР
|КОГДА ВидРасчета.Тип=Начисления ТОГДА СУММА(Премии.Результат)
|КОНЕЦ КАК Начислено, |0 КАК Удержано, |0 КАК Выплачено |ИЗ
|РегистрРасчета.Премии КАК Премии |ГДЕ
131
|Премии.ПернодРегистрации = ДатаОтчета";
Условие="";
Если Сотрудники.Количестве() 0 Тогда
Условие = Условие + " И Сотрудник В Иерархии (СписокСотрудников)";
Запрос.УстановитьПараметрС СписокСотрудников", Сотрудники.ВыгрузитьКолонкуС'Сотрудник"));
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + Условие;
ТекстЗапроса = ТекстЗапроса +"
|СГРУППИРОВАТЬ ПО
|Премии.Подразделение,
|Премии Должность,
|Премии.Сотрудник,
|Премии.ВидРасчета
|ОБЪЕДИНИТЬВСЕ
|ВЫБРАТЬ
|Удержаяия.Подразделение КАК Подразделение,
|Удержания.Должность КАК Должность,
|Удержания.Сотрудник КАК Сотрудник,
|Удержания.ВидРасчета КАК ВидРасчета,
|0 КАК Начислено,
|ВЫБОР
|КОГДА ВидРасчета.Тип=Удержания ТОГДА СУММА(Удержания.Результат)
|КОНЕЦ КАК Удержано, |0 КАЮ Выплачено |ИЗ
|РегистрРасчета.Удержания КАК Удержания |ГДЕ
|Удержания.ПериодРегистрации = ДатаОтчета"; Условие=""; Если Сотрудники.КоличествоО 0 Тогда
Условие = Условие + " И Сотрудник В Иерархии (СписокСотрудников)";
Запрос.УстановитьПараметр("СписокСотрудников",
Сотрудннкн.ВыгрузитьКолонку("Сотрудник"));
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + Условие; ТекстЗапроса = ТекстЗапроса +" |СГРУППИРОВАТЬ ПО
|Удержания. Подразделение,
|Удержания. Должность,
|Удержания. Сотрудник,
|Удержания.ВидРасчета
132
Решение задачи
|ОБЪЕДИНИТЬВСЕ |ВЫБРАТЬ
|Выплаты.Подразделение КАК Подразделение, |Выплаты.Должноеть КАК Должность, |Выплаты.Сотрудник КАК Сотрудник, |Выплаты.ВидРасчета КАК ВидРасчета, |0 КАК Начислено, |0 КАК Удержано, |ВЫБОР
|КОГДА ВидРаечета.Тип=Выплаты ТОГДА СУММА(Выплаты.Результат)
|КОНЕЦ КАК Выплачено |ИЗ
|РегистрРасчета.Выплаты КАК Выплаты |ГДЕ
|Выплаты.ПериодРегистрации = ДатаОтчета"; Условие=""; Если Сотрудники.Количество() о 0 Тогда
Условие = Условие + " И Сотрудник В Иерархии (СпиеокСотрудников)";
Запрос.УстановитьПараметр("СписокСотрудников", Сотрудники.ВыгрузитьКолонкуС'Сотрудник"));
КонецЕсли;
ТекстЗапроса = ТекстЗапроса + Условие;
ТекстЗапроса = ТекстЗапроса +"
|СГРУППИРОВАТЬ ПО
|Выплаты.Подразделение,
|Выплаты.Должность,
|Bыплаты. Сотрудник,
|Выплаты.ВидРасчета)
|КАК Расчеты
|УПОРЯДОЧИТЬ ПО
|Подразделение,
|Должность,
|Сотрудник
|ИТОГИ СУММА(Начислено),СУММА(Удержано),СУММА(Выплачено) ПО
|Подразделение,
|Должность,
|Сотрудник
|";
Комментарии.
133
Конфигурирование в системе
В данном запросе последовательно производится обращение к каждому из регистров расчета «ОсновныеНачисления», «Премии», «Удержания», «Выплаты». В результате получается четыре «подзапроса», результаты которых собираются в одну таблицу с помощью оператора ОБЪЕДИНИТЬ ВСЕ (результирующая таблица используется для заполнения табличного документа).
Для того, чтобы лучше понять механизм такого объединения таблиц, проверим с помощью отчета «Знакомство с запросом» работу следующего достаточно простого запроса.
Текст запроса.
ВЫБРАТЬ
НачисленияОсн.Подразделение КАК Подразделение, НачисленияОсн. Должность КАК Должность, НачисленияОсн.Сотрудник КАК Сотрудник, НачисленияОсн.ВидРасчета КАК ВидРасчета ИЗ
РегиетрРасчета.ОсновныеНачисления КАК НачисленияОсн ОБЪЕДИНИТЬ ВСЕ ВЫБРАТЬ
Премии.Подразделение КАК Подразделение, Премии.Допжность КАК Должность, Премии.Согрудник КАК Сотрудник, Премии.ВндРасчета КАК ВидРасчета ИЗ РегистрРасчета.Премии КАК Премии
Таблица результатов запроса.

Замечание. Для того, чтобы работал оператор ОБЪЕДИНИТЬ ВСЕ, необходимо, чтобы объединяемые таблицы имели одинаковое количество полей. Поля результата запроса будут называться так, как описано в списке полей выборки первого из объединяемых запросов. Поля выборки остальных запросов сопоставляются с полями результата в соответствии с порядком их следования в списке полей выборки. Если поля выборки объединяемых запросов имеют разный тип, то поля результата запроса будут иметь составной тип данных.
Процесс объединения результатов запроса удобно представить на
схеме.
134

Схема «Процесс объединения результатов запроса»
Решение задачи
135
Конфигурирование в системе " 1 С:Предприятие 8.0". Решение расчетных задач
Практикум №2
Налог на доходы физических лиц (НДФЛ)
Реализуйте возможность удержания с сотрудников НДФЛ. Для этого создайте следующие объекты:
План видов расчета «Налоги». Вид расчета «НДФЛ»
Создайте план видов расчета «Налоги». Создайте реквизит Тип, а также ФормуСписка и ФормуЭлемента. Определите свойство Зависимость от базы: Зависит по периоду регистрации. В качестве Базовых планов видов расчета определите планы видов расчета «Премии», «ОсновныеНачисления».
Создайте предопределенный вид расчета «НДФЛ». Определите базовые и ведущие виды расчета:

Регистр расчета «Налоги»
Создайте регистр расчета «Налоги». Определите свойство Вид
расчета: Налоги. Поставьте признак Базовый период,
периодичность: Месячный. Измерения: «Сотрудник»,
«Подразделение», «Должность». Ресурс: «Результат». Создайте ФормуСписка регистра.
Константа «СтавкаНалога»
Создайте константу «СтавкаНалога» типа Число длиной 5, точностью 2. В режиме исполнения определите ставку налога 13%.
Замечание. Мы сознательно упрощаем задачу, создавая константу, которая не может хранить историю значений. При этом подразумеваем, что в реальных конфигурациях «СтавкаНДФЛ» может изменяться во времени и для хранения истории значений ставки понадобилось бы создать периодический регистр сведений без измерений.
Документ «ВводНалогов»
Создайте документ «ВводНалогов». Определите свойство Движения: регистр расчета «Налоги».
Реквизиты документа: «ПериодРегистраци»и. Реквизиты табличной части Налоги: «Сотрудник», «Подразделение», «Должность», «ВидРасчета».
При проведении документа предусмотрите возможность получения налоговой базы по нескольким регистрам расчета методом
136
Решение задачи
ПолучитъБазу(). Доработайте процедуру
РассчитатъНачисленияУдержания() в общем модуле
ПроцедурыРасчета так, чтобы результат расчета считался по формуле: ДанныеБазы *СтавкаНалога/100.
Перерасчет подоходного налога
Создайте в регистре расчета «Налоги» перерасчет «ПерерасчетНДФЛ». НДФЛ должен пересчитыватъся при изменении оклада, отпуска или премии. Доработайте алгоритм перерасчета, реализованный в обработке «ПерерасчетЗарплаты» так, чтобы в список перерасчетов попадали перерасчеты еще и из регистра расчета «Налоги».
Отчет «РасчетыСотрудников»
Доработайте отчет «РасчетыСотрудников» так, чтобы в результат попадал и НДФЛ.
Введите в режиме исполнения удержание «НДФЛ» сотруднику Баранову (Бухгалтерия, Бухгалтер) и проверьте правильность работы программы.
137
чие расчетных задач
Некоторые особенности технологии реализации расчетных задач
Представленная выше технология решения простейшей расчетной задачи не отличается особой сложностью.
Рассмотрим некоторые технологические особенности и приемы конфигурирования, которые могут возникнуть при реализации реальных расчетных задач.
Долгосрочные начисления и удержания. Использование регистров сведений для хранения сведений о расчетах.
Для хранения данных о долгосрочных начислениях или удержаниях, когда-либо введенных сотруднику, можно использовать специальный регистр сведений, в котором регистрировать факт ввода сотруднику начисления или удержания, отображать сведения о некоторых характеристиках вводимых начислений и удержаний и о том, действует или прекратило действие введенное начисление или удержание.
При использовании такой схемы при инициализации нового расчетного периода для долгосрочных начислений и удержаний уже не надо будет создавать новые документы по вводу расчетов, достаточно будет проанализировать регистр сведений и на основании имеющихся сведений о действующих начислениях и удержаниях выполнить ввод расчетов на основании уже введенных ранее документов.
Уточнение разрезов учета. Распределение результатов расчета по нескольким разрезам учета
При ведении различных видов учета часто возникают задачи распределения результатов расчета, например, по нескольким счетам бухгалтерского учета, или по нескольким кодам налогового учета, или по нескольким источникам финансирования и т.д. Более того, очень часто подобное распределение не может быть выполнено в момент отражения в системе реальной расчетной хозяйственной операции (например, отражение в налоговом и бухгалтерском учете осуществляется по результатам определенного периода, а не в момент ввода расчета).
Для реализации подобных схем учета в системе «1С:Предприятие 8.0» достаточно создать несколько дополнительных регистров расчета, каждый из которых будет уточнять результат по тому или иному разрезу учета.
Регистры расчета, в которых будут распределяться результаты расчетов, должны повторять измерения основного регистра расчета и,
138
Решение задачи
возможно, дополнять их уточняющими измерениями (бухгалтерский счет, код налогового регистра и т.д.). Регистры расчета, в которых будут распределяться результаты расчетов, должны использовать тот же план видов расчета, что и основной регистр, должны поддерживать базовый период.
Приведем пример распределения результатов расчета по нескольким разрезам учета.

Реализуем механизм распределения результатов расчета начислений и удержаний по нескольким источникам финансирования.
Справочник «Источники финансирования»
Создадим справочник, в котором будем хранить перечень источников финансирования, используемых в организации.
Основные свойства:
- Имя: «ИсточникиФинансирования».
- Длина наименования: 30.
- Форма: ФормаСписка.
Остальные свойства справочника оставим по умолчанию.
139
Справочник будет иметь один предопределенный элемент -Пропорционально. Данный элемент будет использоваться при необходимости распределения результатов расчета пропорционально расчетной базе вида расчета.
Конфигурщование в системе "1С:Предприятие 8.0". РешениЈЈасчетных задач
Регистр расчета «РасчетыВсеИФ»
Создадим регистр расчета «РасчетыВсеИФ».
В данном регистре расчета будем распределять результаты расчетов начислений и удержаний по источникам финансирования. Регистр будет повторять измерения регистра расчета «РасчетыВсе». Кроме того, регистр будет иметь уточняющее измерение Источник финансирования. Регистр расчета «РасчетыВсеИФ» будет использовать тот же план видов расчета, что и регистр «РасчетыВсе» (план видов расчета «ВидыРасчетаВсе»), будет иметь период действия и базовый период. Также регистр расчета «РасчетыВсеИФ» будет иметь дополнительный реквизит Пропорционально (тип Булево), который будет использоваться как признак необходимости распределения результата расчета пропорционально расчетной базе.
Замечание. Для простоты можно создать регистр расчета «РасчетыВсеИФ» путем копирования регистра расчета «РасчетыВсе», а затем уточнить недостающие характеристики.

Документ «РаспределениеПоИФ»
Создадим документ «РаспределениеПоИФ». Документ будет создаваться в каждом расчетном периоде для каждого сотрудника. В данном документе в табличную часть будут автоматически заполняться все начисления и удержания по сотруднику за выбранный период.
Реализуем возможность распределения начислений и удержаний сотрудника по различным источникам финансирования.
Основные свойства документа:
Имя: «РаспределениеПоИФ». Реквизиты:
Решение задачи
о Сотрудник: тип
СправочникСсылка. ФизическиеЛица,
о Подразделение: тип
СправочникСсылка.Подразделения,
о Должность: тип СправочникСсылка.Должности,
о ПериодРегистрации тип Дата.
Табличные части:
о ВидыРасчета
- ВидРасчета: тип
ПланВидовРасчетаСсылка.ВидыРасчетаВсе
- ИсточникФинансирования: тип
СправочникСсылка.ИсточникиФинансирова
ния,
- График: тип
СправочникСсылка.ГрафикиРаботы,
- Результат: тип Число длина 10 точность 2,
- ДатаНачала: тип Дата,
- ДатаОкончания: тип Дата,
- Сторно: Булево.
Формы:
о ФормаСписка, о ФормаДокумента.

В форме документа запретим пользователю добавлять вручную новые строки в табличную часть. Для этого назначим обработчик события ПередНачаломДобавления и в процедуре-обработчике события запишем следующее.
Процедура ВидыРасчетаПередНачаломДобавления(Элемент, Отказ, Копирование)
141
Конфигурирование в системе "1С:Предприятие^8.0"'. Решение расчетных задач
II Вставить содержимое обработчика. Отказ=Истина; КонецПроцедуры
Создадим на командной панели кнопку «Заполнить», назначим обработчтк события кнопки Нажатие и запишем содержимое обработчика.
Процедура ОсновныеДействияФормыЗаполнить(Кнопка)
// Вставить содержимое обработчика.
ЗаполнитьСписок(); КонецПроцедуры
Процедура ЗашолнитьСписок()

Если (Сотрудник.Пустая()=Ложь) и (Подразделение.Пустая()=Ложь) (Должность.Пустая()=Ложь) и (ПериодРегистрацииоДата("00010101000000")) Тогда
В идыРасчета.Очистить();
Запрос=Новый Запрос; ТекстЗапроса="ВЫБРАТЬ
| РасчетыВсе.ВидРасчета КАК ВидРасчета,
| РасчетыВсе.Результат КАК Результат,
| РасчетыВсе.График КАК График,
| РасчетыВсе.ПериодДействияНачало КАК ДатаНачала,
| РасчетыВсе.ПериодДействияОкончание КАК ДатаОкончания,
| РасчетыВсе.Сторно КАК Сторно
|ИЗ
| РегистрРасчета.РасчетыВсе КАК РасчетыВсе
|ГДЕ
| РасчетыВсе.Сотрудник = Сотрудник И
| РасчетыВсе.Подразделение = Подразделение И
| РасчетыВсе.Должность = Должность И
| РасчетыВсе.ПериодРегистрации = ПериодРегистрации И
| (РасчетыВсе.ВидРасчета.Тип = Начисление или
| РасчетыВсе.ВидРасчета.Тип = У держание)
|УПОРЯДОЧИТЬ ПО
| ВидРасчета";
Запрос.УстановитъПарметр(" Сотрудник", Сотрудник); Запрос.УстановитьПараметр("Подразделение",Подразделение); Запрос.УстановитьПараметр(" Должность" Должность); Запрос.УстановитьПараметр("ПериодРегистрации",ПериодРегистрации); Запрос.УстановитьПараметр("Начисление",Перечисления.ТипыВидовРасчета.Начислен
ие);
142
Решение задачи
Запрос.УстановитьПараметр("Удержание",Перечисления.ТипыВидовРасчета.Удержани
е);
Запрос.Текст=ТекстЗапроса; Выборка=Запрос.Вьшолнить().Выбрать(); Пока Выборка.СледующийО Цикл
Строка=ВидыРасчета.Добавить();
Строка.ВидРасчета=Выборка.ВидРасчета;
Строка.Результат=Выборка.Результат;
Строка.График=Выборка.График;
Строка.ДатаНачала=Выборка.ДатаНачала;
Строка.ДатаОкончания=Выборка.ДатаОкончания;
Строка.Сторно=Выборка.Сторно; КонецЦикла; КонецЕсли; КонецПроцедуры
Комментарии.
Выбираем запросом из регистра расчета «РасчетыВсе» записи начислений и удержаний за выбранный период для выбранного
сотрудника. Затем создаем в табличной части строки, соответствующие начислениям и удержаниям сотрудника.
В модуле документа создадим процедуру ОбработкаПроведения.
Процедура ОбработкаПроведения(Отказ, РежимПроведения) Для Каждого Строка Из ВидыРасчета Цикл
Если Не(Строка.ИсточникФинансирования=Справочники.ИсточникиФинансирования.Пропорци
овально) Тогда
Движение = Движения.РасчетыВсеИФ.Добавить(); Движение.ПериодРегистрации = ПериодРегистрации; Движение.ПериодДействияНачало = Строка.ДатаНачала; Движение.ПериодДействияОкончание = Строка.ДатаОкончания; Движение.Сотрудник = Сотрудник; Движение.Подразделение = Подразделение; Движение. Должность = Должность; Движение.График = Строка.График; Движение.ВидРасчета = Строка.ВидРасчета; Движение.Результат = Строка.Результат; Движение.Сторно = Строка.Сторно;
Движение.ИсточникФинансирования =
Строка.ИсточникФинансирования;
Иначе
ВыборкаИФ=Справочники.ИсточникиФинансирования.Выбрать();
Пока ВыборкаИФ.СледующийО Цикл
143
Конфигурирование в системе " 1С:Предприятие 8.0". Решение расчетных задач
Если ВыборкаИФ.СсьшкаоСправочники.ИсточникиФинансирования.Пропорционально Тогда
Движение = Движения.РасчетыВсеИФ.Добавить();
Движение.ПериодРегистрации = ПериодРегистрации;
Движение.ПериодДействияНачало = Строка.ДатаНачала;
Движение.ПериодДействияОкончание =
Строка.ДатаОкончания;
Движение.Сотрудник = Сотрудник; Движение.Подразделение = Подразделение; Движение.Должность = Должность; Движение.График = Строка.График; Движение. ВидРасчета = Строка.ВидРасчета; Движение.ПараметрРасчета = Строка.Результат;
Движение.Сторно = Строка.Сторно;
Движение.ИсточникФинансирования =
ВыборкаИФ.Сеылка;
Движение.Пропорционально = Истина; КонецЕсли; КонецЦикла;
КонецЕсли; КонецЦикла;
Движения.РасчетыВсеИФ.Записать(); РВсеМенеджер=РегистрыРасчета.РасчетыВсеИФ;
НаборЗаписей = РВсеМенеджер.СоздатьНаборЗаписей(); НаборЗапнсей.Отбор.Регистратор.Значение = Ссылка; Отбор= НаборЗаписей.Отбор; Ресурсы = Новый Массив( 1); Ресурсы[0] = "РасчетыВсеИФ.Результат"; Измерения= Новый Структура();
Измерения.Вставить("Подразделение","РасчетыВсеИФ.Подразделение"); Измерения.Вставить(" Должность","РасчетыВсеИФ.Должность"); Измерения.Вставить("Сотрудник","РасчетыВсеИФ.Сотрудник"); ИзмеренияИФ= Новый Структура();
ИзмереЕияИФ.Вставить("Подразделение","РасчетыВсеИФ.Подразделение"); ИзмеренияИФ .Встав ить(" Должность","РасчетыВсеИФ.Должность"); ИзмеренияИФ.Вставить("Сотрудник","РасчетыВсеИФ. Сотрудник");
ИзмеренияИФ .Вставить("ИсточникФинансирования","РасчетыВсеИФ.ИсточникФи нансирования");
Для Каждого Движение Из Движения.РасчетыВсеИФ Цикл Если Движение.Пропорционально =Истнна Тогда
ДанныеБазы = Движение.ПолучитьБазу(Ресурсы,Измерения);
144
Решение задачи
ДанныеБазыИФ
Движение.ПолучитьБазу(Ресурсы,ИзмеренияИФ);
Движение.Результат ДанныеБазыИФ[0].Результат/ДанныеБазы[0].Результат*Движение.ПараметрРасчета;
КонецЕсли;
КонецЦикла; КонецПроцедуры
Комментарии.
В алгоритме реализован механизм создания записей в регистре расчета РасчетыВсеИФ. Если в табличной части документа-распределения для начисления или удержания указан конкретный источник финансирования, то в регистре расчетов РасчетыВсеИФ создается одна запись. Если же для начисления или удержания указан источник финансирования Пропорциональное распределение, то в регистре расчетов РасчетыВсеИФ создается столько записей, сколько источников финансирования используется в организации.
Для каждой такой записи производится расчет результата с учетом источника финансирования. Для получения расчетной базы по конкретному источнику финансирования используется метод записи регистра расчета ПолучитъБазу(Ресурсы,ИзмеренияИФ). Причем в качестве второго параметра используется структура с дополнительным значением ИсточникФинансирования.
Для получения доли при пропорциональном распределении результат (из таблицы значений, возвращаемой методом ПолучитъБазу) по конкретному источнику финансирования делится на данные базы по всем источникам финансирования.
Замечание. В данной реализации с целью упрощения не учитывается округление результата.
Создадим в режиме исполнения документ РаспределениеПоИФ для сотрудника Ивановой со следующими характеристиками.
Шапка:
о ПериодРегистрации 01.01.2003; о Сотрудник: Иванова; о Подразделение: Дирекция; о Должность: Директор;
Табличная часть: заполним автоматически.
145

Конфигурирование в системе "1С:Предприятие 8.0". Решение расчетных задач
После автоматического заполнения табличной части уточним источники финансирования:
1 для Оплаты по окладу - Бюджет;
1 для Премии процентом - Пропорциональное
распределение.
Проведем документ. В результате в регистре расчета «РасчетыВсеИФ» появятся новые записи.

Практикум №3
Отчет Расчеты сотрудников по источникам финансирования
Доработтайте отчет «Расчеты сотрудников» так, чтобы можно было формировать отчет как по выбранному, так и по всем источникам финансирования.
146
Заключение
Итак, на этом курс завершен, что мы можем посоветовать дальше?
Во-первых, пройти эту методичку еще раз самостоятельно, но на этот раз в спокойном темпе, не пропуская ни одного практикума. Это будет уже намного проще, т.к. готовая база данных в результате прохождения курса у Вас уже имеется.
Во-вторых, имеет смысл продолжить изучение методов встроенного языка и типовых конфигураций на наших курсах.
В-третьих, решайте больше реальных практических задач! Ничто так не укрепляет знания, как реальная практика.
147
Желаем Вам успехов!
Бухгалтерия: Автоматизация - Система 1С