Имя: Пароль:
1C
1С v8
ЗУП: как лучше получить все подразделения сотрудника
0 Антиквар
 
04.06.14
23:16
Всем привет!
Требуется получить все подразделения сотрудника, в которых он работал за квартал. Не получается красивый запрос. Сделал так:
ВЫБРАТЬ
    РаботникиОрганизацийСрезПоследних.Сотрудник КАК Сотрудник,
    ВЫБОР
        КОГДА РаботникиОрганизацийСрезПоследних.ПериодЗавершения <= &НачалоПериода
                И РаботникиОрганизацийСрезПоследних.ПериодЗавершения <> ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
            ТОГДА РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизацииЗавершения
        ИНАЧЕ РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизации
    КОНЕЦ КАК ПодразделениеОрганизации
ИЗ
    РегистрСведений.РаботникиОрганизаций.СрезПоследних(&НачалоПериода) КАК РаботникиОрганизацийСрезПоследних
ГДЕ
    РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния <> ЗНАЧЕНИЕ(Перечисление.ПричиныИзмененияСостояния.Увольнение)
    И (РаботникиОрганизацийСрезПоследних.Сотрудник.ВидЗанятости = ЗНАЧЕНИЕ(Перечисление.ВидыЗанятостиВОрганизации.ОсновноеМестоРаботы)
    ИЛИ РаботникиОрганизацийСрезПоследних.Сотрудник.ВидЗанятости = ЗНАЧЕНИЕ(Перечисление.ВидыЗанятостиВОрганизации.ВнутреннееСовместительство))

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

Но тут получается, что если в регистре сведений РаботникиОрганизаций нет записей за период МЕЖДУ &НачалоПериода И &КонецПериода, но есть запись за предыдущий период, в которой ПериодЗавершения находится МЕЖДУ &НачалоПериода И &КонецПериода, то нужно взять ПодразделениеЗавершения, т.к. оно в этот период попадает. Но запрос это не выбирает. Если сделать ещё одно объединение, но уже по условию:
РаботникиОрганизаций.ПериодЗавершения МЕЖДУ &НачалоПериода И &КонецПериода
то тут может попасть ненужная информация, т.к. в предыдущем запросе по обычному периоду могли быть записи и они перекрывают данные.

Короче запутался я что-то, помогите с запросом :)
Или может в стандарте ЗУПа есть аналогичное, я бы там посмотрел. Но сам не нашел такого отчета.
1 SeraFim
 
05.06.14
02:40
Из типовой:

        |ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |    ВЫБОР
        |        КОГДА РаботникиОрганизаций.ПериодЗавершения <> ДАТАВРЕМЯ(1, 1, 1)
        |                И РаботникиОрганизаций.ПериодЗавершения <= &НачалоМесяца
        |            ТОГДА РаботникиОрганизаций.ПериодЗавершения
        |        ИНАЧЕ РаботникиОрганизаций.Период
        |    КОНЕЦ КАК Период,
        |    ВЫБОР
        |        КОГДА РаботникиОрганизаций.ПериодЗавершения <> ДАТАВРЕМЯ(1, 1, 1)
        |                И РаботникиОрганизаций.ПериодЗавершения <= &НачалоМесяца
        |            ТОГДА РаботникиОрганизаций.ПодразделениеОрганизацииЗавершения
        |        ИНАЧЕ РаботникиОрганизаций.ПодразделениеОрганизации
        |    КОНЕЦ КАК ПодразделениеОрганизации,
        |    РаботникиОрганизаций.Сотрудник КАК Сотрудник
        |ПОМЕСТИТЬ ВТКадровыеПеремещенияРаботниковОрганизаций
        |ИЗ
        |    РегистрСведений.РаботникиОрганизаций.СрезПоследних(
        |            &НачалоМесяца,
        |            Сотрудник В
        |                (ВЫБРАТЬ
        |                    ВТСписокРаботников.Ссылка
        |                ИЗ
        |                    ВТСписокРаботников)) КАК РаботникиОрганизаций
        |
        |ОБЪЕДИНИТЬ
        |
        |ВЫБРАТЬ
        |    РаботникиОрганизаций.Период,
        |    РаботникиОрганизаций.ПодразделениеОрганизации,
        |    РаботникиОрганизаций.Сотрудник
        |ИЗ
        |    РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
        |ГДЕ
        |    РаботникиОрганизаций.Сотрудник В
        |            (ВЫБРАТЬ
        |                ВТСписокРаботников.Ссылка
        |            ИЗ
        |                ВТСписокРаботников)
        |    И РаботникиОрганизаций.Период МЕЖДУ &НачалоМесяца И &КонецМесяца
        |
        |ОБЪЕДИНИТЬ
        |
        |ВЫБРАТЬ
        |    РаботникиОрганизаций.ПериодЗавершения,
        |    РаботникиОрганизаций.ПодразделениеОрганизацииЗавершения,
        |    РаботникиОрганизаций.Сотрудник
        |ИЗ
        |    РегистрСведений.РаботникиОрганизаций КАК РаботникиОрганизаций
        |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РаботникиОрганизаций КАК ПериодыПерекрытия
        |        ПО (ПериодыПерекрытия.Период <= РаботникиОрганизаций.ПериодЗавершения)
        |            И (ПериодыПерекрытия.Период > РаботникиОрганизаций.Период)
        |            И РаботникиОрганизаций.Сотрудник = ПериодыПерекрытия.Сотрудник
        |ГДЕ
        |    РаботникиОрганизаций.Сотрудник В
        |            (ВЫБРАТЬ
        |                ВТСписокРаботников.Ссылка
        |            ИЗ
        |                ВТСписокРаботников)
        |    И РаботникиОрганизаций.ПериодЗавершения <> ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
        |    И РаботникиОрганизаций.ПериодЗавершения > &НачалоМесяца
        |    И РаботникиОрганизаций.ПериодЗавершения <= &КонецМесяца
        |    И ПериодыПерекрытия.Период ЕСТЬ NULL
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    Сотрудник,
        |    Период,
        |    ПодразделениеОрганизации
        |;
2 SeraFim
 
05.06.14
02:43
хотя и тут косяк:
во втором запросе условие

|    И РаботникиОрганизаций.Период МЕЖДУ &НачалоМесяца И &КонецМесяца

должно быть

|    И РаботникиОрганизаций.Период > &НачалоМесяца И РаботникиОрганизаций.Период <= &КонецМесяца
3 Dmitry1c
 
05.06.14
06:51
Вот за что я не люблю ЗУП. Чтобы получить какую-то типичную инфу, нужно из((ебну(ться
4 el7cartel
 
05.06.14
08:11
(3) ну так взял и изъеб(((нулся!
5 Антиквар
 
05.06.14
09:16
(1) Спасибо огромное, вот 3-ий запрос у меня никак и не получался, но понимал, что без него никак. Честно говоря я и сейчас, глядя на него, пока смысл не понял :)
6 SeraFim
 
05.06.14
10:07
(5) ПериодЗавершения - для временных переводов. То есть по окончании перевода - человек вернется на старое место.
Но возможны ситуации, когда по окончании перевода будет новый приказ. В таком случае, данные ПериодаЗавершения нам не нужны. Вот для этого и используется соединение в этом запросе
7 Антиквар
 
05.06.14
10:21
(6) да, я в курсе про период завершения.
>> Но возможны ситуации, когда по окончании перевода будет новый приказ.
>> В таком случае, данные ПериодаЗавершения нам не нужны.

Вот про это я и писал в первом посте, что не знаю как сделать 3-ий запрос в объединении, чтобы учесть данный момент. Вы мне прислали пример, но я пока не разобрался. Т.е. я понимаю, что этот запрос наверное делает то что нужно, но код для меня пока не читаемый :) Сейчас тут дергают по разным мелочам, подразгребу проблемы и вдумчиво буду читать код 3-го запроса :)
8 Антиквар
 
05.06.14
11:04
(6) >> Но возможны ситуации, когда по окончании перевода будет новый приказ. В таком случае, данные ПериодаЗавершения нам не нужны.
>>Вот для этого и используется соединение в этом запросе

По-моему не совсем так.
Если была запись в регистре до &НачалоМесяца, а период завершения у неё МЕЖДУ &НачалоМесяца И &КонецМесяца, и больше за отчетный период записей нет, то вот для этого и нужен 3-ий запрос, чтобы учесть подразделение завершения.
А если есть записи перекрытия, т.е. если в отчетном периоде есть другие записи в регистре, то мы ничего не берем этим запросом, т.к. эти записи перекрывают и выбраны вторым запросом.
9 Антиквар
 
05.06.14
11:09
(2) >> хотя и тут косяк

Почему? Мне кажется всё верно.
Во 2-м запросе мы должны учесть &НачалоМесяца, т.к. в первом запросе срез нам не даст движение регистра в дате начала месяца. В дате начала месяца он даст информацию лишь в том случае, если на эту дату есть период завершения. И вот тут проблема мне кажется, если период завершения - 1-ый день месяца, и в этот же день есть другая запись. Мы получим два подразделения, а нужно одно.
Поэтому мне кажется в первом запросе в полях запроса надо делать не "<=", а строго "<":
ВЫБОР
        |        КОГДА РаботникиОрганизаций.ПериодЗавершения <> ДАТАВРЕМЯ(1, 1, 1)
        |                И РаботникиОрганизаций.ПериодЗавершения < &НачалоМесяца
10 SeraFim
 
05.06.14
12:13
Все тут хорошо =)
11 Антиквар
 
05.06.14
14:24
(10) Всё-таки что-то не так.
Допустим делаем отчет за июнь. У сотрудника было кадровое перемещение с 15 по 31 мая из подразделения Подр1 в Подр2.
Затем оформили кадровое перемещение сотрудника с 1 июня в подразделение Подр3, т.е. сотруднику не надо в июне возвращаться в Подр1. А что имеем:
В регистре будет запись: Период = 15 мая, ПериодЗавершения = 1 июня.
Первый запрос нам вернет ПодразделениеЗавершения = Подр1.
Следующая запись в регистре: Период = 1 июня, и Подразделение = Подр3. Второй запрос нам вернет единственно правильное подразделение для месяца июнь: Подр3.
Но Подр1 в выборке первого запроса лишнее.
А если исправить второй запрос как ты пишешь, то и Подр3 не вернет, только Подр1. Совсем плохо :(
12 Антиквар
 
05.06.14
14:28
И даже если упростить задачу: имеем всего одно кадровое перемещение с 1 июня из подразделения Подр1 в Подр2, без всяких периодов завершения.
Первый запрос вернет Подр1, второй запрос либо Подр2, либо в твоем варианте ничего не вернет.
А должно вернуть только Подр2, Подр1 остается в мае.
13 Антиквар
 
05.06.14
14:31
Т.е. этот запрос видимо не дает готовый вариант. Нужно с его результатом работать, анализировать полученные периоды и исключать какие-то строки...
Зашибись, вроде хотелка то элементарная на первый взгляд, получить список подразделений, в которых работал, а как сложно сделать.
14 RomaH
 
naïve
05.06.14
14:35
(12) первый запрос вернет подр2
срез на 1 июня получит запись перемещения
15 RomaH
 
naïve
05.06.14
14:37
(11) - имеем:
15/05 П1 31/05 П2
01/06 П3

первый запрос вернет 01/06 ПЗ
16 RomaH
 
naïve
05.06.14
14:38
(11) в общем не надо фантазировать - давай скрины с неправильной выборкой типового запроса
17 RomaH
 
naïve
05.06.14
14:39
(2) дубли уберет, но смысла большого нет
18 SeraFim
 
05.06.14
15:11
У тебя путаница со срезом последних - неправильно понимаешь, как он работает.
Из справки:
СрезПоследних
Предназначена для получения наиболее поздних записей регистра сведений на указанную дату (включительно)

То есть если есть движения на дату среза (на 1 июня), то это движение и будет в срезе последних.
Именно поэтому я и сделал поправочку в (2). Движения с датой = началу периода уже учтены в первом запросе
19 Антиквар
 
05.06.14
15:54
(18) Да, ребят, извиняюсь, думал что не "включительно". Перепутал с сальдо регистра накопления.
Дубли мне не важны, их отсею, главное чтобы попало только то что надо.
Спасибо ещё раз, сейчас взгляну на эти запросы правильно :)
Основная теорема систематики: Новые системы плодят новые проблемы.