Автор Тема: Неоднократное изменение оклада в расчетных задачах  (Прочитано 19229 раз)

0 Пользователей и 1 Гость просматривают эту тему.

HRom

  • Пользователь
  • **
  • Сообщений: 94
  • ФИО: HRom
tatyana_fiesta,
я делал разбиение не запросом, а методами объекта РегистрСведенийМенеджер

Uncle

  • Пользователь
  • **
  • Сообщений: 49
  • ФИО: Max
Сейчас нет времени опробовать ваше решение и искать свой запрос, но я точно помню, что решал так:
1)
регистр расчета ОН с периодичностью день.
2)
дальше думаю все понятно должно быть:
пакет1 получить даты из календаря
пакет2 соединить рег окладов и пакет1
пакет3 добавить в пакет2 оклады
пакет4... пакет3 соединить с РР записать Оклад в ресурс Размер.
3)
получение данных по графику выходит так что в каждой записи норма = 176 часов факт = 8 либо 0 (но такие записи можно было не писать в РР) и тут уже легко посчитать результат.


EMelihoff

  • Пользователь
  • **
  • Сообщений: 29
  • ФИО: Sanya
tatyana_fiesta, взял ваш запрос, попробовал на своём примере - не работает. Буду благодарен, если объясните как Вы добились того чтобы этот кусок кода работал?

tatyana_fiesta

  • Пользователь
  • **
  • Сообщений: 39
tatyana_fiesta, взял ваш запрос, попробовал на своём примере - не работает. Буду благодарен, если объясните как Вы добились того чтобы этот кусок кода работал?
Там нет моего запроса, сама пытаюсь узнать у коллег  :)
Самый первый запрос в этой теме хорош, но не работает при условии "в одном документе могут быть данные за разные расчетные периоды"

HRom

  • Пользователь
  • **
  • Сообщений: 94
  • ФИО: HRom
tatyana_fiesta,

Ну а почему нельзя в документе НачислениеЗарплаты сделать кнопку "Заполнить начисления по окладам", которая будет заполянть оклады за расчётный месяц? В том числе дробя их в соответствии с датами изменения оклада.
А если юзеру надо, он руками в этот документ может добавить данные за другие расчётные периоды, но сам при этом будет заполнять значение оклада в этих строках.

EMelihoff

  • Пользователь
  • **
  • Сообщений: 29
  • ФИО: Sanya
ВЫБРАТЬ
НачислениеЗарплатыОсновныеНачисления.Сотрудник КАК Сотрудник,
НачислениеЗарплатыОсновныеНачисления.ПериодДействияНачало КАК ПериодДействияНачало,
НачислениеЗарплатыОсновныеНачисления.ПериодДействияКонец,
МАКСИМУМ(ОкладыСотрудников.Период) КАК Период,
МАКСИМУМ(ОкладыСотрудников.Оклад) КАК Оклад
ИЗ
Документ.НачислениеЗарплаты.ОсновныеНачисления КАК НачислениеЗарплатыОсновныеНачисления
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ОкладыСотрудников КАК ОкладыСотрудников
ПО НачислениеЗарплатыОсновныеНачисления.Сотрудник = ОкладыСотрудников.Сотрудник
И НачислениеЗарплатыОсновныеНачисления.ПериодДействияНачало >= ОкладыСотрудников.Период
ГДЕ
НачислениеЗарплатыОсновныеНачисления.Ссылка = &Ссылка
И НачислениеЗарплатыОсновныеНачисления.ВидРасчета = &ВидРасчета

СГРУППИРОВАТЬ ПО
НачислениеЗарплатыОсновныеНачисления.Сотрудник,
НачислениеЗарплатыОсновныеНачисления.ПериодДействияНачало,
НачислениеЗарплатыОсновныеНачисления.ПериодДействияКонец

УПОРЯДОЧИТЬ ПО
ПериодДействияНачало

msergei

  • Новичок
  • *
  • Сообщений: 1
  • ФИО: Сергей
Запрос для неоднократного изменения окладов
Данный запрос был написан для Билета №2 без учета подразделений (в регистре СведенияОСотрудниках нет измерения Подразделение)
Тестовые данные:

Документ "Начисление зарплаты"
N   Сотрудник   Вид расчета   Дата начала   Дата окончания
1   Бельдыев   Оклад                 01.07.2015   10.07.2015
2   Бельдыев   Оклад                 20.07.2015   31.07.2015
3   Иванов                 Оклад                 01.07.2015   31.07.2015
4   Иванов                 Оклад                 01.05.2015   31.05.2015

Регистр "Сведения о сотрудниках"
Период                 Сотрудник   Оклад
01.01.2015   Бельдыев   10 000,00
01.01.2015   Иванов                 15 000,00
01.07.2015   Иванов                 25 000,00
02.07.2015   Бельдыев   15 000,00
10.07.2015   Бельдыев   17 000,00
25.07.2015   Бельдыев   13 500,00
31.07.2015   Иванов                 20 000,00

Результат запроса:
Сотрудник   ВидРасчета   ПериодДействияНачало   ПериодДействияКонец   Размер
Бельдыев   Оклад                    01.07.2015 0:00:00   01.07.2015 23:59:59   10 000
Бельдыев   Оклад                     02.07.2015 0:00:00   09.07.2015 23:59:59   15 000
Бельдыев   Оклад                    10.07.2015 0:00:00   10.07.2015 23:59:59   17 000
Бельдыев   Оклад                    20.07.2015 0:00:00   24.07.2015 23:59:59   17 000
Бельдыев   Оклад                    25.07.2015 0:00:00   31.07.2015 23:59:59   13 500
Иванов                 Оклад                    01.05.2015 0:00:00   31.05.2015 23:59:59   15 000
Иванов                 Оклад                    01.07.2015 0:00:00   30.07.2015 23:59:59   25 000
Иванов                 Оклад                    31.07.2015 0:00:00   31.07.2015 23:59:59   20 000

Текст запроса:

ВЫБРАТЬ
   НачислениеЗарплатыОсновныеНачисления.Сотрудник КАК Сотрудник,
   НачислениеЗарплатыОсновныеНачисления.ВидРасчета,
   НАЧАЛОПЕРИОДА(НачислениеЗарплатыОсновныеНачисления.ДатаНачала, ДЕНЬ) КАК ДатаНачала,
   КОНЕЦПЕРИОДА(НачислениеЗарплатыОсновныеНачисления.ДатаОкончания, ДЕНЬ) КАК ДатаОкончания
ПОМЕСТИТЬ ДанныеДокумента
ИЗ
   Документ.НачислениеЗарплаты.ОсновныеНачисления КАК НачислениеЗарплатыОсновныеНачисления
ГДЕ
   НачислениеЗарплатыОсновныеНачисления.Ссылка = &Ссылка

ИНДЕКСИРОВАТЬ ПО
   Сотрудник
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   МАКСИМУМ(СведенияОСотрудниках.Период) КАК Период,
   СведенияОСотрудниках.Сотрудник КАК Сотрудник
ПОМЕСТИТЬ СотрудникиСрез
ИЗ
   РегистрСведений.СведенияОСотрудниках КАК СведенияОСотрудниках
      ВНУТРЕННЕЕ СОЕДИНЕНИЕ ДанныеДокумента КАК ДанныеДокумента
      ПО СведенияОСотрудниках.Сотрудник = ДанныеДокумента.Сотрудник
ГДЕ
   СведенияОСотрудниках.Период <= ДанныеДокумента.ДатаОкончания

СГРУППИРОВАТЬ ПО
   СведенияОСотрудниках.Сотрудник

ИНДЕКСИРОВАТЬ ПО
   Сотрудник
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   СведенияОСотрудниках.Сотрудник КАК Сотрудник,
   СведенияОСотрудниках.Период,
   СведенияОСотрудниках.Оклад
ПОМЕСТИТЬ СотрудникиСрезОклады
ИЗ
   СотрудникиСрез КАК СотрудникиСрез
      ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СведенияОСотрудниках КАК СведенияОСотрудниках
      ПО СотрудникиСрез.Сотрудник = СведенияОСотрудниках.Сотрудник

СГРУППИРОВАТЬ ПО
   СведенияОСотрудниках.Сотрудник,
   СведенияОСотрудниках.Период,
   СведенияОСотрудниках.Оклад

ИНДЕКСИРОВАТЬ ПО
   Сотрудник
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   СотрудникиСрезОклады.Сотрудник КАК Сотрудник,
   ВЫБОР
      КОГДА СотрудникиСрезОклады.Период < ДанныеДокумента.ДатаНачала
         ТОГДА ДанныеДокумента.ДатаНачала
      ИНАЧЕ СотрудникиСрезОклады.Период
   КОНЕЦ КАК Период1,
   МАКСИМУМ(СотрудникиСрезОклады.Период) КАК Период
ПОМЕСТИТЬ СотрудникиПериоды
ИЗ
   ДанныеДокумента КАК ДанныеДокумента
      ВНУТРЕННЕЕ СОЕДИНЕНИЕ СотрудникиСрезОклады КАК СотрудникиСрезОклады
      ПО ДанныеДокумента.Сотрудник = СотрудникиСрезОклады.Сотрудник
         И ДанныеДокумента.ДатаОкончания >= СотрудникиСрезОклады.Период

СГРУППИРОВАТЬ ПО
   СотрудникиСрезОклады.Сотрудник,
   ВЫБОР
      КОГДА СотрудникиСрезОклады.Период < ДанныеДокумента.ДатаНачала
         ТОГДА ДанныеДокумента.ДатаНачала
      ИНАЧЕ СотрудникиСрезОклады.Период
   КОНЕЦ

ИНДЕКСИРОВАТЬ ПО
   Сотрудник
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   СотрудникиПериоды.Сотрудник КАК Сотрудник,
   СотрудникиПериоды.Период1 КАК Период,
   СотрудникиСрезОклады.Оклад
ПОМЕСТИТЬ ПериодыОклады
ИЗ
   СотрудникиПериоды КАК СотрудникиПериоды
      ВНУТРЕННЕЕ СОЕДИНЕНИЕ СотрудникиСрезОклады КАК СотрудникиСрезОклады
      ПО СотрудникиПериоды.Сотрудник = СотрудникиСрезОклады.Сотрудник
         И СотрудникиПериоды.Период = СотрудникиСрезОклады.Период

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
   ДанныеДокумента.Сотрудник,
   ДанныеДокумента.ДатаОкончания,
   0
ИЗ
   ДанныеДокумента КАК ДанныеДокумента

ИНДЕКСИРОВАТЬ ПО
   Сотрудник
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ПериодыОклады.Сотрудник,
   ПериодыОклады.Период КАК ПериодС,
   ПериодыОклады.Оклад,
   МИНИМУМ(ПериодыОклады1.Период) КАК ПериодПо
ПОМЕСТИТЬ РазделениеПоПериодам
ИЗ
   ПериодыОклады КАК ПериодыОклады
      ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПериодыОклады КАК ПериодыОклады1
      ПО ПериодыОклады.Сотрудник = ПериодыОклады1.Сотрудник
         И ПериодыОклады.Период < ПериодыОклады1.Период
ГДЕ
   ПериодыОклады.Оклад > 0

СГРУППИРОВАТЬ ПО
   ПериодыОклады.Сотрудник,
   ПериодыОклады.Период,
   ПериодыОклады.Оклад
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   РазделениеПоПериодам.Сотрудник КАК Сотрудник,
   РазделениеПоПериодам.ПериодС,
   РазделениеПоПериодам.Оклад,
   ВЫБОР
      КОГДА КОНЕЦПЕРИОДА(РазделениеПоПериодам.ПериодПо, ДЕНЬ) = РазделениеПоПериодам.ПериодПо
         ТОГДА РазделениеПоПериодам.ПериодПо
      ИНАЧЕ ДОБАВИТЬКДАТЕ(РазделениеПоПериодам.ПериодПо, ДЕНЬ, -1)
   КОНЕЦ КАК ПериодПо
ПОМЕСТИТЬ РазделениеПериодовГотово
ИЗ
   РазделениеПоПериодам КАК РазделениеПоПериодам

ИНДЕКСИРОВАТЬ ПО
   Сотрудник
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   ДанныеДокумента.Сотрудник КАК Сотрудник,
   ДанныеДокумента.ВидРасчета,
   ЕСТЬNULL(РазделениеПериодовГотово.ПериодС, ДанныеДокумента.ДатаНачала) КАК ПериодДействияНачало,
   КОНЕЦПЕРИОДА(ЕСТЬNULL(РазделениеПериодовГотово.ПериодПо, ДанныеДокумента.ДатаОкончания), ДЕНЬ) КАК ПериодДействияКонец,
   ЕСТЬNULL(РазделениеПериодовГотово.Оклад, 0) КАК Размер
ИЗ
   ДанныеДокумента КАК ДанныеДокумента
      ЛЕВОЕ СОЕДИНЕНИЕ РазделениеПериодовГотово КАК РазделениеПериодовГотово
      ПО ДанныеДокумента.Сотрудник = РазделениеПериодовГотово.Сотрудник

СГРУППИРОВАТЬ ПО
   ДанныеДокумента.Сотрудник,
   ДанныеДокумента.ВидРасчета,
   ЕСТЬNULL(РазделениеПериодовГотово.ПериодС, ДанныеДокумента.ДатаНачала),
   КОНЕЦПЕРИОДА(ЕСТЬNULL(РазделениеПериодовГотово.ПериодПо, ДанныеДокумента.ДатаОкончания), ДЕНЬ),
   ЕСТЬNULL(РазделениеПериодовГотово.Оклад, 0)

УПОРЯДОЧИТЬ ПО
   Сотрудник,
   ПериодДействияНачало
АВТОУПОРЯДОЧИВАНИЕ
« Последнее редактирование: Июль 31, 2015, 09:29:11 am от msergei »

tatyana_fiesta

  • Пользователь
  • **
  • Сообщений: 39
Вот это Запросище  :o (см.выше)
Круто! Всё работает! Теперь нужно понять всё логику запроса и "закрытыми" глазами написать на Экзамене  ;D

Jones

  • Проверенный
  • ***
  • Сообщений: 199
Други! Гляньте, если не лень, мой запрос по многократному изменению Оклада, разбираю его в ПР задаче 2 билета

Логика такая:
1 запрос получает строки ТЧ документа, только Оклады
2 запрос получает Периды записей рег.свед Оклады, состоит из двух запросов (Объединение)
      2.1 Периоды Окладов до ДатыНач строки документа (это будет Оклад на начало периода действия)
                +группировка, Период Максимум, чтобы получить только последний по периоду Оклад перед ДатаНач
      2.2 Периоды между ДатаНач и ДатаКон строки документа (это будут изменения Оклада в периоде действия)
3 запрос для каждого полученного периода получаю Оклад (тоже из физической таблицы Оклады)
4 запрос посложнее
        во Вложенном запросе, для каждого Оклада и Периода получаю его дату окончания, то есть дату начала следующего Оклада
          по сути, Вложенный запрос содержит готовые строки: Сотрудник/Оклад/ДатаНач/ДатаКон
        К данным из ТЧ справа цепляю строки Вложенного запроса

В результате строка ТЧ делится на столько строк, сколько было изменений оклада+Оклад на начало периода действия

alex1248

  • Призрак форума
  • *****
  • Сообщений: 714
Jones, отвечу прямо здесь, поскольку конкретно по данной (снова неоднозначной теме  :D. ).

В общем-то ответ будет просто мнением в целом по вопросу темы.
Во-первых, по самому запросу, убедился, что суть, как обычно, когда берем-таки разные расчетные периоды - выбирать данные из самого регистра, с разными периодами по каждому сотруднику. Кстати, сразу в начале запроса неточность - во втором запросе должно быть "И ТЧ.ПериодДействияНачало >= Оклады.Период" (больше или равно). И еще решил, что понял не правильно, увидев вот это Запрос.УстановитьПараметр("НачМесДатаДок", НачалоМесяца(Дата));, но похоже, что параметр НачМесДатаДок реально не используется.

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

ПС. Ну и ссылки:
http://forum.chistov.pro/index.php?topic=3419.0 - увы, но всё, что в интернете, выдает тот же вариант получения данных из реальной таблицы.
http://forum.chistov.pro/index.php?topic=1108.msg40497#msg40497
« Последнее редактирование: Август 02, 2015, 11:17:03 am от alex1248 »

tatyana_fiesta

  • Пользователь
  • **
  • Сообщений: 39
Други! Гляньте, если не лень, мой запрос по многократному изменению Оклада, разбираю его в ПР задаче 2 билета

Логика такая:
1 запрос получает строки ТЧ документа, только Оклады
2 запрос получает Периды записей рег.свед Оклады, состоит из двух запросов (Объединение)
      2.1 Периоды Окладов до ДатыНач строки документа (это будет Оклад на начало периода действия)
                +группировка, Период Максимум, чтобы получить только последний по периоду Оклад перед ДатаНач
      2.2 Периоды между ДатаНач и ДатаКон строки документа (это будут изменения Оклада в периоде действия)
3 запрос для каждого полученного периода получаю Оклад (тоже из физической таблицы Оклады)
4 запрос посложнее
        во Вложенном запросе, для каждого Оклада и Периода получаю его дату окончания, то есть дату начала следующего Оклада
          по сути, Вложенный запрос содержит готовые строки: Сотрудник/Оклад/ДатаНач/ДатаКон
        К данным из ТЧ справа цепляю строки Вложенного запроса

В результате строка ТЧ делится на столько строк, сколько было изменений оклада+Оклад на начало периода действия
У Вас запрос не правильно разбивает периоды при условии: "в одном документе могут быть данные за разные расчетные периоды"
Я прям в вашей базе добавила в существующий документе "Начисление з/п" Февральский период и программа стала выдавать ошибку, потому что запрос не работает

maratischee

  • Новичок
  • *
  • Сообщений: 4
Вот такая мысль:

ВЫБРАТЬ
 ВложенныйЗапрос.Период КАК Период,
 ВложенныйЗапрос.Сотрудник КАК Сотрудник,
 МАКСИМУМ(ВложенныйЗапрос.Оклад) КАК Оклад,
 ВложенныйЗапрос.Подразделение
ПОМЕСТИТЬ Периоды
ИЗ
 (ВЫБРАТЬ
  СведенияОСотрудникахСрезПоследних.Период КАК Период,
  СведенияОСотрудникахСрезПоследних.Сотрудник КАК Сотрудник,
  СведенияОСотрудникахСрезПоследних.Оклад КАК Оклад,
  СведенияОСотрудникахСрезПоследних.Подразделение КАК Подразделение
 ИЗ
  РегистрСведений.СведенияОСотрудниках.СрезПоследних(&Период, ) КАК СведенияОСотрудникахСрезПоследних
 
 ОБЪЕДИНИТЬ ВСЕ
 
 ВЫБРАТЬ
  СведенияОСотрудниках.Период,
  СведенияОСотрудниках.Сотрудник,
  СведенияОСотрудниках.Оклад,
  СведенияОСотрудниках.Подразделение
 ИЗ
  РегистрСведений.СведенияОСотрудниках КАК СведенияОСотрудниках
 ГДЕ
  СведенияОСотрудниках.Период МЕЖДУ &Период И &ПериодКонец) КАК ВложенныйЗапрос
СГРУППИРОВАТЬ ПО
 ВложенныйЗапрос.Период,
 ВложенныйЗапрос.Сотрудник,
 ВложенныйЗапрос.Подразделение
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
 ВЫБОР
  КОГДА Периоды.Период < &Период
   ТОГДА &Период
  ИНАЧЕ Периоды.Период
 КОНЕЦ КАК НачалоПериода,
 Периоды.Сотрудник КАК Сотрудник,
 Периоды.Оклад,
 Периоды.Подразделение,
 МИНИМУМ(ЕСТЬNULL(ДОБАВИТЬКДАТЕ(Периоды1.Период, ДЕНЬ, -1), &ПериодКонец)) КАК КонецПериода
ИЗ
 Периоды КАК Периоды
  ЛЕВОЕ СОЕДИНЕНИЕ Периоды КАК Периоды1
  ПО Периоды.Период < Периоды1.Период
   И Периоды.Сотрудник = Периоды1.Сотрудник
   И Периоды.Подразделение = Периоды1.Подразделение
СГРУППИРОВАТЬ ПО
 Периоды.Сотрудник,
 Периоды.Оклад,
 Периоды.Подразделение,
 ВЫБОР
  КОГДА Периоды.Период < &Период
   ТОГДА &Период
  ИНАЧЕ Периоды.Период
 КОНЕЦ
УПОРЯДОЧИТЬ ПО
 Сотрудник,
 НачалоПериода

В этом запросе разбиваются на периоды данные регистра СведенияОСтрудниках
« Последнее редактирование: Август 03, 2015, 02:56:30 pm от maratischee »

EMelihoff

  • Пользователь
  • **
  • Сообщений: 29
  • ФИО: Sanya
Не изобретайте велосипед, смотрите решение.

maratischee

  • Новичок
  • *
  • Сообщений: 4
В предложенном решении автоматически не разбиваются периоды, если в начислении зарплаты указать в одной строке период, например, месяц, внутри которого меняются оклады.   Или может я неправильно понимаю условие: "Расчет должен проводиться исходя из действующего на рассчитываемую дату начального значения оклада. Например, если начальное значение оклада изменилось 10 августа, то до 10 августа при расчете берется старое значение, а начиная с 10 августа – новое"
« Последнее редактирование: Август 04, 2015, 09:42:23 am от maratischee »

EMelihoff

  • Пользователь
  • **
  • Сообщений: 29
  • ФИО: Sanya
Правда, передалаю
« Последнее редактирование: Август 04, 2015, 09:43:48 am от EMelihoff »