Виртуальные таблицы регистра расчета 1с. Сложные периодические расчеты

Для того чтобы можно было рассчитывать зарплату в конфигурации, работающей на платформе 1С Предприятие 8, необходимо умение работать с объектами конфигурации которые для этого и предназначены. Для реализации возможности расчета заработной платы, в конфигурации необходимо использовать такие объекты как планы видов расчета и регистры расчета. Без этих объектов реализовать расчет достаточно проблематично, если совсем не возможно. В этой статье хочу поведать какие объекты предназначены для расчета зарплаты и как с ними работать.
Основные используемые понятия:
Вид расчета – начисление или удержание, которое может быть применено к сотруднику.
План видов расчета – объект конфигурации, предназначенный для хранения однотипных видов расчета.
База – совокупность видов расчета, которые и являются основой для расчета конкретного вида расчета.
Период регистрации – это дата, когда документ зарегистрирован в системе. И если периодичность регистра расчета месяц, то период регистрации системой автоматически приводится к началу месяца.
Период действия – это интервал, в котором действует вид расчета. Например, зарегистрировать документ можно в одном месяце, а период действия будет находиться в другом месяце.
Сокращения, встречающиеся в тексте:
ПВР – план видов расчета;

Итак, начнем с настройки ПВР. В основном настройки ПВР схожи с настройками справочников, но настройки, характерные именно для ПВР находятся на закладке «Расчет» окна редактирования объекта. ПВР содержит однотипные виды расчета. В системе может быть несколько ПВР. Обычно, ПВР создают для основных начислений, для дополнительных начислений и для удержаний. Пример настройки ПВР приведен на рисунке 1.

Рисунок 1

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

После этого, в план видов расчета можно добавлять виды расчета и настраивать их. При настройке вида расчета нужно настроить Базовые, Ведущие, Вытесняющие виды расчета. Пример настройки вида расчета приведен на рисунке 2.

Рисунок 2

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

Рисунок 3

Свойство «План видов расчета» - здесь указывается то, какой ПВР будет соответствовать нашему регистру расчета.
Свойство «Период действия» - указывается флаг, если регистр расчета будет поддерживать период действия видов расчета, то есть те виды расчета, которые являются периодическими. При установленном флаге, у записи регистра расчета добавляются свойства «Период действия начало» и «Период действия конец».
Свойство «График работы» - если стоит флаг периода действия, то становится доступным это свойство. Указываем регистр сведений (непериодический), в котором будет регистрироваться норма времени за конкретный день календаря.
Свойство «Значение графика» - указывается ресурс регистра сведений Графики работы. По этому значению система сможет вычислить данные базы. То есть система сможет вычислить, сколько сотрудник должен отработать в тот или иной день.
Свойство «Дата графика» - указывается измерение с типом Дата. По этому измерению система сможет понять к какой дате относится рабочий/не рабочий день.
Свойство «Базовый период» - указывается, если регистр расчета будет поддерживать базовый период видов расчета. Если флаг установлен, то у записи регистра расчета появляются дополнительные свойства «Базовый период начало» и «Базовый период конец».
Свойство «Периодичность» - указывается периодичность регистра расчета.
На вкладке Данные настраиваются измерения, ресурсы и реквизиты регистра расчета. Пример настройки приведен на рисунке 4

Рисунок 4

Измерениями задаются разрезы, в которых будут храниться записи в регистре расчета. Ресурсы – это вычисляемые значения, фактический результат расчета вида расчета. Реквизиты – здесь указываются дополнительные сведения о записи регистра расчета. Например, в реквизите можно хранить плановые значения видов расчета.
Кроме этого, необходимо указать документы-регистраторы для регистра расчета иначе система не даст сохранить конфигурацию базы данных. Регистраторы задаются на одноименной закладке диалога редактирования объекта конфигурации.
После выполненных настроек, необходимо в обработчике проведения документа-регистратора описать алгоритм формирования движений по регистрам расчета. Пример алгоритма формирования движений может быть такой:

Процедура ОбработкаПроведения(Отказ, Режим) Движения.ОсновныеНачисления.Записывать = Истина; Для Каждого ТекСтрокаНачисления Из Начисления Цикл Движение = Движения.ОсновныеНачисления.Добавить(); Движение.Сторно = ТекСтрокаНачисления.Сторно; Движение.ВидРасчета = ТекСтрокаНачисления.ВидРасчета; Движение.ПериодДействияНачало = ТекСтрокаНачисления.ДатаНачала; Движение.ПериодДействияКонец = КонецДня(ТекСтрокаНачисления.ДатаОкончания); Движение.ПериодРегистрации = ПериодРегистрации; Движение.Сотрудник = ТекСтрокаНачисления.Сотрудник; Движение.Подразделение = ТекСтрокаНачисления.Подразделение; Движение.ТипГрафика = ТекСтрокаНачисления.ТипГрафика; Движение.Размер = ТекСтрокаНачисления.Размер; КонецЦикла; Движения.Записать();//записываем рабочий набор записей РассчитатьНачисления(Отказ); КонецПроцедуры

После того, как записи в регистре расчета записаны, можно выполнять непосредственно сам расчет ресурсов регистра расчета. В приведенном коде это выполняется в процедуре РассчитатьНачисления(). Процедура расчета начислений выглядит так:

Процедура РассчитатьНачисления(Отказ) Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ОсновныеНачисленияДанныеГрафика.НомерСтроки, | ОсновныеНачисленияДанныеГрафика.РабочийДеньПериодДействия КАК ПериодДействияПлан, | ОсновныеНачисленияДанныеГрафика.РабочийДеньФактическийПериодДействия КАК ПериодДействияФакт, | ОсновныеНачисленияДанныеГрафика.ВидРасчета.СпособРасчета КАК Способ, | ОсновныеНачисленияДанныеГрафика.ВидРасчета КАК ВидРасчета |ИЗ | РегистрРасчета.ОсновныеНачисления.ДанныеГрафика(| Регистратор = &Ссылка |) КАК ОсновныеНачисленияДанныеГрафика"; Запрос.УстановитьПараметр("Ссылка",Ссылка); Выборка = Запрос.Выполнить().Выбрать(); Поиск = Новый Структура("НомерСтроки"); Для каждого Запись Из Движения.ОсновныеНачисления Цикл Поиск.НомерСтроки = Запись.НомерСтроки; Выборка.Сбросить(); Если Выборка.НайтиСледующий(Поиск) Тогда Если Выборка.ВидРасчета = ПланыВидовРасчета.ОсновныеНачисления.ОкладПоДням Тогда Если Выборка.ПериодДействияПлан = 0 Тогда Сообщение = Новый СообщениеПользователю; Сообщение.Текст = "График не заполнен"; Сообщение.Сообщить(); Отказ = Истина; Иначе Запись.Результат = Выборка.ПериодДействияФакт*Запись.Размер/Выборка.ПериодДействияПлан; КонецЕсли; КонецЕсли; КонецЕсли; КонецЦикла; Движения.ОсновныеНачисления.Записать(,Истина); КонецПроцедуры // РассчитатьНачисления()

В данном примере будут рассчитываться начисления ОкладПоДням, а для того, чтобы рассчитывались и другие виды расчета, необходимо дописать соответствующее условие и формулу. Пример заполненного и рассчитанного документа начисления зарплаты приведен на рисунке 5.

Рисунок 5

Таким образом и происходит расчет зарплаты на платформе 1С:Предприятие 8. Здесь приведен самый простой случай, без всяких наворотов. Понятное дело, что в типовых решениях алгоритмы более объемные, развесистые и универсальные. В этой статье я показал основу работы с объектами платформы для возможности расчета зарплаты.

Спасибо за внимание! Если есть вопросы, постараюсь на них ответить.​

регистр сведений , который будет содержать график , используемый при расчете. В нашем случае это регистр РабочиеДниПоГрафику . В поле Значение графика выберем РабочийДень - именно в этом ресурсе регистра сведений будет храниться 1, если день является рабочим. В поле Дата графика выберем измерение регистра Дата .

Установим флаг Базовый период .

Зададим в группе параметров Периодичность параметр Месяц .

Перейдем на вкладку Данные . Зададим здесь следующие параметры, рис. 1.11 :


Рис. 1.11.

Измерение Сотрудник - тип СправочникСсылка.Сотрудники , флаг Базовое установлен. Будем хранить в этом измерении сотрудника, по которому ведется расчет.

Ресурс Результат - тип Число , длина 10, точность 2. Именно этот ресурс будет содержать вычисленное значение вида расчета , заданного для сотрудника. Результат будет содержать значение в рублях, именно это определило параметры типа данных, использованного для него.

Реквизит ИсходныеДанные - тип число, длина 10, точность 2. В этот реквизит мы будем записывать исходные данные для расчета. Например, для вида расчета Оклад мы запишем сюда исходный размер оклада, для вида расчета Премия - процент , который должен браться от расчетной базы, для вида расчета Удержание - размер удержания в рублях.

Реквизит График - тип СправочникСсылка.ГрафикиРаботы . В этом реквизите будем хранить график , который соответствует сотруднику, для которого мы начисляем заработную плату. В свойстве этого реквизита Связь с графиком установим измерение График регистра сведений Графики работы . Именно благодаря этой настройке мы сможем использовать различные графики работы для разных сотрудников (пятидневка, шестидневка) и при расчете получать правильное количество рабочих дней по каждому графику.

Прежде чем продолжать настройку параметров регистра расчета , нам понадобится создать документ, который будет создавать движения по регистру расчета .

1.6. Документ Начисление зарплаты

Создадим новый документ, дадим ему имя НачислениеЗарплаты . Этот документ должен иметь следующую функциональность:

  1. Возможность ручного ввода начислений;
  2. Формирование движений по регистру расчета ;

Перейдем на вкладку Данные окна настройки свойств документа НачислениеЗарплаты , рис. 1.12 . Создадим реквизит документа ПериодРегистрации - тип Дата , состав даты - Дата .


Рис. 1.12.

Создадим табличную часть НачисленияИУдержания . Создадим в ней следующие реквизиты:

Теперь перейдем на вкладку Движения . Запретим оперативное проведение документа , добавим в состав регистров, по которым документ формирует движения, регистр НачисленияИУдержания .

Нажмем на кнопку Конструктор движений . Откроется окно конструктора, рис. 1.13 .


Рис. 1.13.

При заполнении полей, задающих правила формирования движений мы заполним их следующим образом:

БазовыйПериодНачало и БазовыйПериодКонец в конструкторе мы заполнять не будем. Эти поля нужны нам для вида расчета Премия , поэтому мы заполним их в коде процедуры обработки проведения для данного вида расчета .

Нажмем на кнопку ОК в окне конструктора движений и посмотрим, какой код он сформировал:

Процедура ОбработкаПроведения(Отказ, Режим) //{{__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ // Данный фрагмент построен конструктором. // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!! Для Каждого ТекСтрокаНачисленияИУдержания Из НачисленияИУдержания Цикл // регистр НачисленияИУдержания Движение = Движения.НачисленияИУдержания.Добавить(); Движение.Сторно = Ложь; Движение.ВидРасчета = ТекСтрокаНачисленияИУдержания.ВидРасчета; Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания; Движение.ПериодРегистрации = ПериодРегистрации; Движение.Сотрудник = ТекСтрокаНачисленияИУдержания.Сотрудник; Движение.ИсходныеДанные = ТекСтрокаНачисленияИУдержания.ИсходныеДанные; Движение.График = ТекСтрокаНачисленияИУдержания.График; КонецЦикла; //}}__КОНСТРУКТОР_ДВИЖЕНИЙ_РЕГИСТРОВ КонецПроцедуры

Очевидно, что для каждой строки табличной части создается новый элемент коллекции документа Движения.НачисленияИУдержания , после чего заполняются свойства нового элемента.

Модифицируем этот код таким образом, чтобы задать параметры базового периода для вида начисления Премия . Для этого будем проверять вид расчета , присутствующий в обрабатываемой строке, если это - Премия - задаем параметры базового периода . Поместим в цикл обработки строк табличной части такой код:

Если ТекСтрокаНачисленияИУдержания.ВидРасчета= ПланыВидовРасчета.Основной.Премия Тогда Движение.БазовыйПериодНачало=НачалоМесяца(ПериодРегистрации); Движение.БазовыйПериодКонец=КонецМесяца(ПериодРегистрации); КонецЕсли;

Теперь немного изменим ту часть кода, которая задает начало и конец периода действия начисления. В нашем случае лишь один вид начисления нужно "оснастить" периодом действия , который в явном виде будет задавать пользователь . Это - Прогул . У всех остальных период действия будет равняться одному месяцу - начало периода будет совпадать с началом месяца, за который производится начисление заработной платы, конец периода действия будет совпадать с концом месяца. Поэтому мы, для того, чтобы избавить пользователя документа НачислениеЗарплаты от ввода ненужных значений, добавим в наш модуль следующий код, поместив его в цикл обработки строк табличной части:

Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Прогул Тогда Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания; Иначе Движение.ПериодДействияНачало = НачалоМесяца(ПериодРегистрации); Движение.ПериодДействияКонец = КонецМесяца(ПериодРегистрации); КонецЕсли;

Этот код заменит строки

Движение.ПериодДействияНачало = ТекСтрокаНачисленияИУдержания.ДатаНачала; Движение.ПериодДействияКонец = ТекСтрокаНачисленияИУдержания.ДатаОкончания;

После всех этих действий документ при проведении будет добавлять в регистр расчета данные для расчета. Проверим это. Запустим нашу конфигурацию в режиме 1С:Предприятие, создадим новый документ Начисление зарплаты , заполним его данными и проверим, как эти данные отразились в регистре расчета после проведения документа .

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

На рис. 1.14 вы можете видеть документ, который мы заполнили, и движения в регистре расчета , которые он произвел после проведения, после отработки кода, который мы написали выше.

Если все перенесено верно, а в нашем случае это именно так, мы можем приступать к реализации процедуры расчета. Сделаем это в том же модуле, в котором осуществляется формирование движений.

Сразу хотелось бы отметить, что в существующих конфигурациях обычно применяются несколько другие методы реализации расчетных процедур. В частности, для них характерна следующая последовательность действий. После того, как документ сформировал движения по регистру, происходит запись данных в регистр , после чего управление передается в расчетную процедуру общего модуля с установленным свойством Сервер , что актуально в том случае, если система работает в клиент-серверном режиме. В процедуре, с помощью запроса к таблицам регистра расчета , получают записанные данные и проводят манипуляции с ними. Все эти действия, в итоге, приводят к повышению быстродействия прикладных решений , которые могут использоваться в различных режимах, работать с большими объемами данных. Сущность действия такая же, как в нашем примере, но реализация отличается. Главная цель нашего учебного примера - показать принципы, по которым осуществляется решение расчетных задач, поэтому здесь мы концентрируемся именно на основных принципах, не обращая внимание на оптимальность кода или его быстродействие .

Добавим в процедуру проведения документа команду записи сформированных движений:

Движения.НачисленияИУдержания.Записать();

Эта команда должна следовать за командой закрытия цикла формирования движений.

Добавим в код блок расчета удержания. В соответствии с логикой заданных ранее видов расчета , здесь мы лишь копируем ИсходныеДанные для Удержания в Результат .

Для Каждого Движение из Движения.НачисленияИУдержания Цикл Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Удержание Тогда Движение.Результат=Движение.ИсходныеДанные; КонецЕсли; КонецЦикла; Движения.НачисленияИУдержания.Записать();

Теперь займемся расчетом оклада.

Для Каждого Движение из Движения.НачисленияИУдержания Цикл Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Оклад Тогда План = Движение.ПолучитьДанныеГрафика(ВидПериодаРегистраРасчета.ПериодДействия); Факт= Движение.ПолучитьДанныеГрафика(ВидПериодаРегистраРасчета.ФактическийПериодДействия); Движение.Результат= Движение.ИсходныеДанные*Факт.РабочийДень/План.РабочийДень; КонецЕсли; КонецЦикла; Движения.НачисленияИУдержания.Записать();

Метод ПолучитьДанныеГрафика записи регистра расчета возвращает данные графика в виде таблицы значений, причем, этот метод вызывается с параметром типа ВидПериодаРегистраРасчета . Если вызвать его с видом периода ПериодДействия - будут возвращены данные по графику, отражающие, в нашем случае, полное количество рабочих дней. Вызов метода с видом периода ФактическийПериодДействия возвращает данные с учетом вытесняющих видов расчета .

Запись вида Факт позволяет обратиться к строке таблицы значений. А записью Факт.РабочийДень (напомним, РабочийДень - это имя ресурса регистра сведений , который используется как график ) мы "вытаскиваем" нужные данные. В нашем случае - количество рабочих дней, отработанных по факту.

В итоге, получив нужные данные, мы проводим следующие манипуляции: делим фактическое количество отработанных дней на плановое и умножаем на размер оклада.

И, наконец, последним этапом нашей расчетной задачи является расчет премии. Его мы реализуем с помощью следующего кода:

Ресурсы=Новый Массив(1); Ресурсы="НачисленияИУдержания.Результат"; Измерения =Новый Структура ("Сотрудник", "НачисленияИУдержания.Сотрудник"); Для Каждого Движение из Движения.НачисленияИУдержания Цикл Если Движение.ВидРасчета=ПланыВидовРасчета.Основной.Премия Тогда ДанныеБазы=Движение.ПолучитьБазу(Ресурсы, Измерения); Движение.Результат=Движение.ИсходныеДанные*ДанныеБазы.Результат/100; КонецЕсли; КонецЦикла; Движения.НачисленияИУдержания.Записать();

Для начала мы подготовим параметры для передачи в метод ПолучитьБазу . Это будет массив Ресурсы , который в нашем случае содержит имя ресурса базового регистра расчета в формате "ИмяРегистра.ИмяРесурса" . Так же мы готовим структуру Измерения . В структуру мы добавляем новый элемент, имя которого совпадает с именем измерения регистра расчета ("Сотрудник" ), а значение содержит список измерений (в формате "ИмяРегистра.ИмяИзмерения" ), в нашем случае это одно измерение. Эти данные будут использованы при получении расчетной базы при расчете премии.

В цикле мы записываем в переменную ДанныеБазы результаты выполнения метода ПолучитьБазу для текущей записи регистра расчета (то есть - для вида расчета Премия ). Метод ПолучитьБазу возвращает таблицу значений, строки которой хранят запрошенные при вызове метода данные.

Вспомним, как называется ресурс регистра расчета , в котором хранятся результаты вычислений - это ресурс Результат . Именно по такому имени мы можем обратиться к строке таблицы значений (в нашем случае это одна строка с индексом 0) и получить расчетную базу.

После того, как расчетная база получена, мы рассчитываем размер премии. Так как при заполнении документа подразумевается, что мы вводим процентное значение премии в виде количества процентов (10, 40 и т.д.), то для того, чтобы узнать размер премии, мы должны введенный процентный размер премии разделить на 100 и уже после этого умножать на полученную расчетную базу.

После того, как все вышеперечисленные действия выполнены, мы можем испытать наше решение на практике. Если все выполнено верно - в

При работе с регистрами расчета есть возможность получения базовых данных. Это своеобразный способ расчета оборотов регистра, при котором функция расчета оборотов не является простой функцией суммирования ресурсов регистра по измерениям за определенный период, а представляет собой более сложную функцию. Эта функция зависит от состояния плана видов расчета, назначенного регистру расчета и, таким образом, управляется пользователем.

В данном разделе мы рассмотрим два существующих в системе способа получения базовых данных - при помощи языка запросов и при помощи функциональной записи, методом ПолучитьБазу() . При этом будет называть "основным" регистром расчета тот регистр, для которого необходимо получить базовые данные, а "базовыми" регистрами (которых в общем случае может быть несколько) будем называть те регистры, для которых выполняется суммирование ресурсов.

Мы не будем рассматривать эти способы подробно, рассмотрим только их отличия и область применения.

Метод ПолучитьБазу()

Метод ПолучитьБазу() определен для объектов РегистрРасчетаМенеджер.<Имя регистра расчета> и РегистрРасчетаЗапись.<Имя регистра расчета> . Метод позволяет задать ресурсы базовых регистров, по которым необходимо получить обороты, задать поля, в разрезе которых нужно получить обороты и задать правила сопоставления измерений основного и базовых регистров расчета.

Правила сопоставления записей регистров расчета задаются структурой, каждый элемент которой задает для того или иного измерения основного регистра список измерений базовых регистров расчета. Имена элементов структуры должны совпадать с именами измерений основного регистра, а значения элементов структуры - строки, со списком измерений базовых регистров через запятую. Если элемент структуры с именем того или иного измерения не задан, то это значит, что на соответствующее измерение не налагается условие.

Имена измерений и ресурсов базовых регистров задаются в формате <ИмяРегистраРасчета>.<ИмяПоля>.

Пример использования метода:
Код 1C v 8.х Ресурсы = Новый Массив(1);
Ресурсы = "ОсновныеНачисления.Результат,ДополнительныеНачисления.Результат";

Измерения = Новый Структура("ФизЛицо,Организация");
Измерения.ФизЛицо = "ОсновныеНачисления.Физлицо,ДополнительныеНачисления.Работник";
Измерения.Организация = "ОсновныеНачисления.Организация,ДополнительныеНачисления.Организация";

Разрезы = Новый Массив(1);
Разрезы = "ОсновныеНачисления.Способ,ДополнительныеНачисления.Способ";
// Рассчитываем базуТаблицаБазовыхДанных = РегистрРасчета.Удержания.ПолучитьБазу(Отбор,
// Ресурсы, Измерения, Разрезы);

В приведенном выше примере измерение "Физлицо" основного регистра при получении оборотов будет сопоставляться с измерением "Физлицо" базового регистра "ОсновныеНачисления" и измерением "Работник" базового регистра "ДополнительныеНачисления".

Таблица языка запросов для получения базовых данных
Для получения базовых данных в языке запросов определены виртуальные таблицы "РегистрРасчета.<Имя регистра расчета>.База<Имя базового регистра расчета>" . В качестве параметров виртуальной таблицы задаются измерения основного регистра, измерения базового регистра и поля, в разрезе которых нужно получить базовые данные. Измерения и разрезы задаются как массив (или список значений) строк с именами измерений.

Пример написания запроса с использованием виртуальных таблиц базовых данных:
Код 1C v 8.х
Измерения1 = Массив(2);
Измерения1 = "Физлицо";
Измерения1 = "Организация";

Измерения2 = Массив(2);
Измерения2 = "Работник";
Измерения2 = "Организация";

Разрезы = Новый Массив(1);
Разрезы = "Способ";

ТекстЗапроса = "ВЫБРАТЬ Физлицо, ВидРасчета, СУММА(РезультатБаза)
|ИЗ
|ВЫБРАТЬ Физлицо, ВидРасчета, РезультатБаза
| ИЗ РегистрРасчета.Удержания.БазаОсновныеНачисления(&Измерения1,&Измерения1,&Разрезы)
|ГДЕ " + УсловиеОсновных + "
|ОБЪЕДИНИТЬ ВСЕ
|ВЫБРАТЬ Работник, ВидРасчета, РезультатБаза
| ИЗ РегистрРасчета.Удержания.БазаДополнительныеНачисления(&Измерения1,&Измерения2,&Разрезы)
|ГДЕ " + УсловиеДополнительных + "
|) КАК База
|СГРУППИРОВАТЬ ПО
| Физлицо,
| ВидРасчета
|";

Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("Измерения1", Измерения1);
Запрос.УстановитьПараметр("Измерения2", Измерения2);
Запрос.УстановитьПараметр("Разрезы", Разрезы);

// ...установка дополнительных параметров запроса, применяемых в условиях в операторе ГДЕ// ,..
// получим выборку результата запросаВыборка = Запрос.Выполнить().Выбрать();

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

Сравнение
Заметным отличием функционального метода получения базовых данных и получения при помощи запроса является то, что в функциональном методе одним вызовом метода можно получить базовые данные по всем базовым регистрам, а при использовании запросов получение базовых данных делается запросом к нескольким таблицам - по числу базовых регистров. Тем не менее, рекомендуемым способом получения данных является получение данных запросом. Это позволит, например, получить не только данные базовых видов расчета, но и дополнительную информацию, необходимую для расчета.

Отметим, что производительность получения данных при помощи функционального метода и при помощи запроса одинакова несмотря на кажущееся усложнение исполняемого кода в случае с запросами.

Краткая функциональная запись с использованием метода ПолучитьБазу() допустима только в том случае, если нет необходимости в иных данных помимо базовых, и при этом хочется "сэкономить" на строках кода. Совершенно не допустимо из соображений производительности кода, применение метода ПолучитьБазу() в том случае, если после его использование все равно придется при помощи запроса получать дополнительные данные для расчета.

Еще одно соображение касается условий отбора базовых данных. Для метода ПолучитьБазу(), фактически, нет возможности получить базовые данные иначе, чем по одной записи или по конкретному регистратору (с отбором по тем или иным измерениям). В случае же запроса в распоряжении у разработчика все возможности языка запросов по отбору записей.

Учимся работать с регистрами (1С:Бухгалтерия 8.3, редакция 3.0)

2016-12-08T13:50:45+00:00

Дорогие читатели, в этом уроке я хочу затронуть крайне важную тему при работе в 1С:Бухгалтерия 8.3 - Регистры .

Сразу покажу на небольшом примере почему это так важно.

Пусть у нас есть начисление заработной платы за январь:

В начале февраля мы создаём ведомость на выплату зарплаты из кассы и нажимаем кнопку "Заполнить":

И получаем следующее:

Но ведь за январь:

  • Начисление 50 000 рублей
  • НДФЛ 6 500 рублей
  • Итого к выплате 43 500 рублей

Где закралась ошибка? Что пошло не так? Неужели теперь всегда вводить сумму к выплате вручную?

Опытный бухгалтер тут же сделает оборотно-сальдовую ведомость по 70 счёту:

И будет в ещё большем недоумении, потому что по данным отчёта к выплате выходят всё те же 43 500! И откуда же взялись лишние 5 000 рублей?

Причём такая ситуация (с любыми расчётами) может произойти как в "тройке", так и в "двойке".

Сегодня я попытаюсь приоткрыть завесу тайны - почему же иногда программа ведёт себя так странно. Я расскажу как в таких случаях находить и устранять ошибку. Ближе к концу статьи мы разберёмся - откуда же взялись эти самые 5 000 рублей.

Итак, поехали!

Учимся видеть регистры

При проведении документов 1С:Бухгалтерия 8 делает проводки по бухгалтерским счетам (кнопка ДтКт у любого документа):

Именно на основании этих проводок строятся все бухгалтерские отчёты: Анализ счёта, Карточка счёта, Оборотно-сальдовая ведомость...

Но есть огромный пласт данных, которые пишутся программой параллельно с проводками и используются для всего остального: заполнение КУДИР, книги покупок и продаж, регламентированной отчётности... заработной платы к выплате , наконец

Как вы уже, наверное, догадались этот пласт называется регистрами , вот он:

Я сейчас не буду вдаваться в подробности описания самих регистров, чтобы не запутать вас ещё больше.

Скажу лишь, что нам просто жизненно необходимо постепенно учиться "видеть" движения по этим регистрам, чтобы лучше понимать и, когда надо, корректировать поведение программы.

Давайте присмотримся к регистру "Зарплата к выплате" - именно он имеет смысл для решения нашей проблемы с лишними 5 000:

Мы видим две записи по этому регистру, сделанные в приход, то есть в плюс. Если пролистать экран в право, то мы увидим в первой строчке сумму к выплате "-6 500", а во второй "50 000".

Остаток по этому регистру -6 500 + 50 000 равен 43 500, который и должен попасть в документ "Ведомость на выплату из кассы", когда мы нажимаем на кнопку "Заполнить".

Ещё раз повторюсь - ведомость на выплату определяет нашу задолженность по заработной плате перед сотрудником не по 70 счёту, а по регистру "Зарплата к выплате" .

Получается мы знаем, что зарплата к выплате заполняется на основании этого регистра, но даже видя записи регистра не можем понять что не так.

Скорее всего мы не видим всей картины (может быть существуют другие записи по этому регистру) и напрашивается некий инструмент для анализа регистра подобный бухгалтерским отчётам.

Учимся анализировать регистры

И такой инструмент есть, он называется "Универсальный отчёт ".

Переходим в раздел "Отчеты" пункт "Универсальный отчёт":

Выбираем тип регистра "Регистр накопления", регистр "Зарплата к выплате" и нажимаем кнопку "Сформировать":

Получилось не очень информативно:

Всё потому, что требуется предварительная настройка отчёта, нажимаем кнопку "Показать настройки" и на закладке "Группировка" добавляем поле "Сотрудник":

На закладке "Отборы" делаем отбор по нашей организации:

Нажимаем кнопку "Сформировать":

Вот это уже более интересно. Видим остаток к выплате нашему сотруднику те самые 48 500 рублей!

Снова заходим в настройки отчёта и добавляем на закладку "Показатели" новое поле "Регистратор":

Снова формируем отчёт:

Вот теперь мы прекрасно видим, что 5 000 появились как результат операции (видимо ввода остатков) 31 декабря 2014 года.

И нам нужно либо изменить эту операцию, либо вручную откорректировать регистр "Зарплата к выплате" и закрыть эти 5 000 рублей, например, 31 декабря 2015 года.

Давайте пойдём вторым путём. Итак, наша задача - сделать так, чтобы на начало 2016 года по регистру "Зарплата к выплате" не было нашей задолженности перед сотрудником.

Это делается ручной операцией.

Учимся корректировать регистры

Заходим в раздел "Операции" пункт "Операции, введенные вручную":

Создаём новую операцию концом 2015 года:

Из меню "Ещё" выбираем пункт "Выбор регистров...":

Указываем регистр "Зарплата к выплате" и нажимаем ОК:

Переходим на появившуюся закладку регистра и делаем расход на 5 000 рублей:

Этим самым мы как бы отнимаем от регистра 5 000 рублей по сотруднику, чтобы выйти на ноль к началу 2016 года.

Проводим операцию и заново формируем универсальный отчёт:

Всё получилось! Видим, что наша ручная операция от 31.12.2015 вывела остаток в ноль и зарплата к выплате после начисления равна ожидаемым 43 500.

Замечательно. И сейчас мы проверим это в ведомости на выплату.

Но прежде я хочу обратить ваше внимание на ещё один важный момент:

Обратите внимание, что остатки на начало и на конец по группировке "Сотрудник" показывают ерунду. Это никакая не ошибка, это нюанс, который нужно учитывать, связанный с архитектурными особенностями 1с.

Запомните. В том случае, если универсальный отчёт выводится с детализацией до документа (регистратора) - остатки по группировкам будут показывать ерунду.

Если нам требуются остатки по группировке сотрудник - нужно сначала удалить из настроек добавленный нами показатель "Регистратор".

Регистры расчета - это прикладные объекты конфигурации . Они используются в механизме сложных периодических расчетов и служат для хранения записей о тех или иных видах расчета, которые необходимо выполнить, а также для хранения промежуточных данных и самих результатов выполненных расчетов

Структура

Информация в регистре расчета хранится в виде записей, каждая из которых содержит значения измерений и соответствующие им значения ресурсов.

Измерения регистра описывают разрезы, в которых хранится информация, а ресурсы регистра непосредственно содержат хранимую информацию. Например, для регистра расчета Начисления , который имеет следующую структуру:

записи, хранимые в базе данных, будут выглядеть следующим образом:

Связь с планом видов расчета

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

Периодичность

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

Подчинение регистратору

Изменение состояния регистра расчета происходит, как правило, при проведении документа. Поэтому каждая запись регистра связана с определенным документом - регистратором и номером строки этого документа. Добавление записей в регистр, их изменение и удаление возможно только одновременно для всех записей, относящихся к одному документу.

Связь с графиком времени

Для регистра расчета может быть указана связь с графиком времени. График времени представляет собой регистр сведений, в котором содержится временная схема исходных данных, участвующих в расчетах. Измерениями этого графика могут быть, например, график работы и дата, а ресурсом – количество рабочих часов в этой дате. Тогда можно будет связать запись регистра расчета с каким-либо конкретным графиком работы и в дальнейшем, средствами встроенного языка получать информацию о количестве рабочих часов, необходимую для выполнения расчетов.

Например, график времени, имеющий следующую структуру:

Перерасчеты

Регистр расчета может включать в себя специальные объекты - Перерасчеты :

В этих объектах система будет хранить информацию о том, какие записи регистра расчета утратили свою актуальность и подлежат перерасчету в результате работы механизмов зависимости по базовому периоду и вытеснения по периоду действия.

Уникальность записей

Система обеспечивает контроль уникальности записей, хранящихся в регистре расчета. Поэтому в регистре расчета не может находиться двух записей, относящихся к одной и той же строке одного и того же документа.

Механизмы, реализуемые регистром расчета

Вытеснение по периоду действия

Механизм вытеснения по периоду действия позволяет рассчитывать фактический период действия записи регистра расчета на основании анализа других записей, содержащихся в регистре.

В общем случае, запись регистра расчета содержит две даты, определяющие период, на который распространяется действие данной записи. Этот период называется периодом действия записи. Однако, если вид расчета, к которому относится данная запись, может быть вытеснен другим видом расчета, то период действия данной записи является лишь "запрашиваемым" периодом, то есть "мы хотим, чтобы запись действовала в этом периоде". Реально, фактический период действия данной записи можно будет определить лишь после анализа всех записей видов расчета, которые вытесняют данный вид расчета по периоду действия. Фактический период действия будет представлять собой набор периодов, являющихся подмножеством исходного периода действия данной записи. Если не будет найдено ни одной записи, вытесняющей данную по периоду действия, то фактический период действия данной записи будет равен ее периоду действия. Другим крайним случаем вытеснения по периоду действия является полное вытеснение данной записи другими записями. В этом случае фактический период действия записи будет отсутствовать.

Каждая запись регистра расчета содержит вид расчета, к которому она относится. Чтобы определить, какие записи должны вытеснять данную запись по периоду действия, регистр расчета использует связь с планом видов расчета, в котором описано взаимное влияние видов расчета друг на друга. Использование этой связи позволяет регистру расчета определять фактический период действия каждой записи.

Зависимость по базовому периоду

Механизм зависимости по базовому периоду позволяет получать значение базы для записи регистра расчета на основании анализа других записей, содержащихся в регистре.

База представляет собой числовое значение, которое должно быть использовано для расчета результата данной записи. База рассчитывается путем анализа результатов расчета других записей, от которых данная запись зависит по базовому периоду. Таким образом, в общем случае, запись регистра расчета содержит две даты, определяющие период, в котором нужно анализировать записи видов расчета, от которых данный вид расчета зависит по базе - базовый период. Использование связи с планом видов расчета позволяет регистру расчета определять виды расчета, от которых данный вид расчета зависит по базовому периоду.

Регистр расчета поддерживает два вида зависимости по базовому периоду:

  • зависимость по периоду действия;
  • зависимость по периоду регистрации.

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

В случае зависимости по периоду регистрации для получения базы будут выбираться результаты расчета тех записей, которые попадают в базовый период данной записи значением своего поля «Период регистрации».

Наиболее сложным вариантом зависимости по базовому периоду является случай, когда для вида расчета данной записи установлено свойство "Период действия является базовым периодом". Это свойство означает, что в качестве базового периода данной записи будет использоваться не базовый период, который указан в соответствующих полях записи, а фактический период действия записи, получаемый в результате работы механизма вытеснения по периоду действия и являющийся, в общем случае, набором некоторых периодов.

Формирование записей перерасчета

Механизм формирования записей перерасчета отслеживает факт появления в регистре записей, влияющих на результат расчета уже существующих записей. Возможность влияния новых записей на существующие определяется в результате анализа взаимного влияния видов расчета и на основании работы механизмов вытеснения по периоду действия и зависимости по базовому периоду.

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

Функциональные возможности регистра расчета

Основными функциональными возможностями, которые предоставляет регистр расчета разработчику, являются:

  • выбор записей в заданном интервале по заданным критериям;
  • выбор записей по регистратору;
  • получение значения базы для записей регистра, удовлетворяющих заданному отбору;
  • получение данных графика для записей регистра, удовлетворяющих заданному отбору;
  • получение данных о записях, подлежащих перерасчету;
  • чтение, изменение и запись набора записей в регистр.