Привет.
В релизе ЗУП 3.1.9 (2018г примерно) была изменена форма списка сотрудников: теперь используется не форма справочника, а форма обработки. Работает быстро, но отборов считай никаких нет.
Подумал что теперь идеология "ищите сотрудников отчетами" - да не нашел каким отчетом это можно делать.
upd ЗУП КОРП
Поделитесь кто как решает эту проблему? Интересует опыт больших баз (от нескольких тысяч сотрудников).
ещё-настроить список. выведены те, которые иногда нужны
а так - просто. пишешь Иванов, оно и ищет
лучше успеть конечно написать Иванов алек
чтобы нашло меньшее количество.
вариант отчёта штатные сотрудники выведен в фавориты
дабы искать сотрудников конкретного подразделения на конкретную дату с нужными колонками
(5) Сейчас в списках сотрудников динамические списки, где слева регистр сведений, а справа кучка таблиц. Форма позволяет делать отборы для множества задач. О какой обработке речь?
Помню, 10 лет назад еще до списков на регистрах тормозило жестко уже на 5К.
Потом переписали на регистры и стало легко.
Сейчас около 20К, но на скуле и железо норм - летает.
В вашем случае, думаю, можно вынести форму списка и выбора в расширение и "выбросить" из запроса списка, по согласованию мало востребованные в форме таблицы и поля.
Хотя, там, вроде, все нужно
ИЗ
РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбора
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК Сотрудники
ПО ДанныеДляПодбора.Сотрудник = Сотрудники.Ссылка
И ДанныеДляПодбора.Наименование = Сотрудники.Наименование
И (ДанныеДляПодбора.ИдентификаторЗаписи В
(ВЫБРАТЬ ПЕРВЫЕ 1
ДанныеДляПодбораСотрудниковОтбор.ИдентификаторЗаписи
ИЗ
РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбораСотрудниковОтбор
ГДЕ
ДанныеДляПодбораСотрудниковОтбор.Сотрудник = ДанныеДляПодбора.Сотрудник
И ДанныеДляПодбораСотрудниковОтбор.Наименование = ДанныеДляПодбора.Наименование
И ДанныеДляПодбораСотрудниковОтбор.Начало <= &ДатаОкончания
И (ДанныеДляПодбораСотрудниковОтбор.Окончание = ДАТАВРЕМЯ(1, 1, 1)
ИЛИ ДанныеДляПодбораСотрудниковОтбор.Окончание >= &ДатаНачала)
УПОРЯДОЧИТЬ ПО
ДанныеДляПодбораСотрудниковОтбор.ПоДоговоруГПХ,
ДанныеДляПодбораСотрудниковОтбор.Начало УБЫВ,
ДанныеДляПодбораСотрудниковОтбор.Организация,
ДанныеДляПодбораСотрудниковОтбор.Филиал,
ДанныеДляПодбораСотрудниковОтбор.Подразделение))
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТекущиеКадровыеДанныеСотрудников КАК ТекущиеКадровыеДанные
ПО ДанныеДляПодбора.ФизическоеЛицо = ТекущиеКадровыеДанные.ФизическоеЛицо
И ДанныеДляПодбора.Сотрудник = ТекущиеКадровыеДанные.Сотрудник
И ДанныеДляПодбора.Организация = ТекущиеКадровыеДанные.ГоловнаяОрганизация}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РолиСотрудников КАК РолиСотрудниковРаботник
ПО ДанныеДляПодбора.Сотрудник = РолиСотрудниковРаботник.Сотрудник
И (&ИспользуетсяОтборПоРолиСотрудникаРаботник = ИСТИНА)
И (РолиСотрудниковРаботник.РольСотрудника = ЗНАЧЕНИЕ(Перечисление.РолиСотрудников.Работник))}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РолиСотрудников КАК РолиСотрудниковДоговорник
ПО ДанныеДляПодбора.Сотрудник = РолиСотрудниковДоговорник.Сотрудник
И (&ИспользуетсяОтборПоРолиСотрудникаДоговорник = ИСТИНА)
И (РолиСотрудниковДоговорник.РольСотрудника = ЗНАЧЕНИЕ(Перечисление.РолиСотрудников.Договорник))}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияСотрудников КАК СостоянияСотрудников
ПО ДанныеДляПодбора.Сотрудник = СостоянияСотрудников.Сотрудник
И (СостоянияСотрудников.Период <= &ДатаОкончания)
И (СостоянияСотрудников.ДействуетДо >= &ДатаНачалаСведений
ИЛИ СостоянияСотрудников.ДействуетДо = ДАТАВРЕМЯ(1, 1, 1))}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДанныеОбОплатеТрудаДляПодбораСотрудников КАК ДанныеОбОплатеТрудаДляПодбора
ПО ДанныеДляПодбора.Сотрудник = ДанныеОбОплатеТрудаДляПодбора.Сотрудник
И ДанныеДляПодбора.ФизическоеЛицо = ДанныеОбОплатеТрудаДляПодбора.ФизическоеЛицо
И ДанныеДляПодбора.ИдентификаторЗаписи = ДанныеОбОплатеТрудаДляПодбора.ИдентификаторЗаписи}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ВидыЗанятостиСотрудниковИнтервальный КАК ВидыЗанятостиСотрудниковДляПодбора
ПО ДанныеДляПодбора.Сотрудник = ВидыЗанятостиСотрудниковДляПодбора.Сотрудник
И (ВЫБОР
КОГДА ДанныеДляПодбора.Окончание = ДАТАВРЕМЯ(1, 1, 1)
ТОГДА ДАТАВРЕМЯ(3999, 12, 31, 23, 59, 59)
ИНАЧЕ КОНЕЦПЕРИОДА(ДанныеДляПодбора.Окончание, ДЕНЬ)
КОНЕЦ МЕЖДУ ВидыЗанятостиСотрудниковДляПодбора.ДатаНачала И ВидыЗанятостиСотрудниковДляПодбора.ДатаОкончания)}
(9) Уже есть в платформе: берет первые 45 (сколько помещается на экран дин.списка). Но здесь нюанс ЗУПа: сотрудники отсортированы по наименованию. Поэтому запрос сперва получает всех, сортирует, а лишь потом ПЕРВЫЕ применяется.
(11) расскажите пожалуйста как оптимизировать этот типовой запрос для postgres и 70.000 записей в справочнике?
ВЫБРАТЬ РАЗРЕШЕННЫЕ
0 КАК ИндикаторПроблем,
Сотрудники.Ссылка КАК Ссылка,
Сотрудники.ВерсияДанных КАК ВерсияДанных,
Сотрудники.ПометкаУдаления КАК ПометкаУдаления,
Сотрудники.Код КАК Код,
Сотрудники.Наименование КАК Наименование,
ДанныеДляПодбора.Наименование КАК НаименованиеСотрудника,
Сотрудники.ФизическоеЛицо КАК ФизическоеЛицо,
ДанныеДляПодбора.Организация КАК Организация,
Сотрудники.ВАрхиве КАК ВАрхиве,
Сотрудники.УточнениеНаименования КАК УточнениеНаименования,
Сотрудники.ГоловнойСотрудник КАК ГоловнойСотрудник,
Сотрудники.Предопределенный КАК Предопределенный,
Сотрудники.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных,
ВЫБОР
КОГДА Сотрудники.ПометкаУдаления
ТОГДА 4
ИНАЧЕ 3
КОНЕЦ КАК Пиктограмма,
ДанныеДляПодбора.Филиал КАК Филиал,
ДанныеДляПодбора.Подразделение КАК Подразделение,
ДанныеДляПодбора.Должность КАК Должность,
ДанныеДляПодбора.ДолжностьПоШтатномуРасписанию КАК ДолжностьПоШтатномуРасписанию,
ДанныеДляПодбора.КоличествоСтавок КАК КоличествоСтавок,
ДанныеДляПодбора.КоличествоСтавокПредставление КАК КоличествоСтавокПредставление,
ВидыЗанятостиСотрудниковДляПодбора.ВидЗанятости КАК ВидЗанятости,
ЕСТЬNULL(ДанныеДляПодбора.ВидДоговора, ЗНАЧЕНИЕ(Перечисление.ВидыДоговоровССотрудниками.ПустаяСсылка)) КАК ВидДоговора,
ДанныеОбОплатеТрудаДляПодбора.ТарифнаяСтавка КАК ТарифнаяСтавка,
ДанныеОбОплатеТрудаДляПодбора.ФОТ КАК ФОТ,
ДанныеОбОплатеТрудаДляПодбора.Надбавка КАК Надбавка,
ДанныеОбОплатеТрудаДляПодбора.СпособРасчетаАванса КАК СпособРасчетаАванса,
ДанныеОбОплатеТрудаДляПодбора.Аванс КАК Аванс,
ТекущиеКадровыеДанные.ДатаПриема КАК ДатаПриема,
ТекущиеКадровыеДанные.ДатаУвольнения КАК ДатаУвольнения,
ТекущиеКадровыеДанные.ОформленПоТрудовомуДоговору КАК ОформленПоТрудовомуДоговору,
ВЫБОР
КОГДА РолиСотрудниковРаботник.Сотрудник ЕСТЬ NULL
ТОГДА ЛОЖЬ
ИНАЧЕ ИСТИНА
КОНЕЦ КАК Работник,
ВЫБОР
КОГДА РолиСотрудниковДоговорник.Сотрудник ЕСТЬ NULL
ТОГДА ЛОЖЬ
ИНАЧЕ ИСТИНА
КОНЕЦ КАК Договорник,
"" КАК ПредставлениеСостояния,
СостоянияСотрудников.Состояние КАК Состояние,
СостоянияСотрудников.ДействуетДо КАК СостояниеДействуетДо,
ДанныеДляПодбора.РабочееМесто КАК РабочееМесто,
ДанныеДляПодбора.ЭтоГоловнойСотрудник КАК ЭтоГоловнойСотрудник,
ДанныеДляПодбора.Начало КАК Начало,
ДанныеДляПодбора.Окончание КАК Окончание,
ДанныеДляПодбора.МестоВСтруктуреПредприятия КАК МестоВСтруктуреПредприятия
ИЗ
РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбора
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК Сотрудники
ПО ДанныеДляПодбора.Сотрудник = Сотрудники.Ссылка
И ДанныеДляПодбора.Наименование = Сотрудники.Наименование
И (ДанныеДляПодбора.ИдентификаторЗаписи В
(ВЫБРАТЬ ПЕРВЫЕ 1
ДанныеДляПодбораСотрудниковОтбор.ИдентификаторЗаписи
ИЗ
РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбораСотрудниковОтбор
ГДЕ
ДанныеДляПодбораСотрудниковОтбор.Сотрудник = ДанныеДляПодбора.Сотрудник
И ДанныеДляПодбораСотрудниковОтбор.Наименование = ДанныеДляПодбора.Наименование
И ДанныеДляПодбораСотрудниковОтбор.Начало <= &ДатаОкончания
И (ДанныеДляПодбораСотрудниковОтбор.Окончание = ДАТАВРЕМЯ(1, 1, 1)
ИЛИ ДанныеДляПодбораСотрудниковОтбор.Окончание >= &ДатаНачала)
УПОРЯДОЧИТЬ ПО
ДанныеДляПодбораСотрудниковОтбор.ПоДоговоруГПХ,
ДанныеДляПодбораСотрудниковОтбор.Начало УБЫВ,
ДанныеДляПодбораСотрудниковОтбор.Организация,
ДанныеДляПодбораСотрудниковОтбор.Филиал,
ДанныеДляПодбораСотрудниковОтбор.Подразделение))
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТекущиеКадровыеДанныеСотрудников КАК ТекущиеКадровыеДанные
ПО ДанныеДляПодбора.ФизическоеЛицо = ТекущиеКадровыеДанные.ФизическоеЛицо
И ДанныеДляПодбора.Сотрудник = ТекущиеКадровыеДанные.Сотрудник
И ДанныеДляПодбора.Организация = ТекущиеКадровыеДанные.ГоловнаяОрганизация}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РолиСотрудников КАК РолиСотрудниковРаботник
ПО ДанныеДляПодбора.Сотрудник = РолиСотрудниковРаботник.Сотрудник
И (&ИспользуетсяОтборПоРолиСотрудникаРаботник = ИСТИНА)
И (РолиСотрудниковРаботник.РольСотрудника = ЗНАЧЕНИЕ(Перечисление.РолиСотрудников.Работник))}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РолиСотрудников КАК РолиСотрудниковДоговорник
ПО ДанныеДляПодбора.Сотрудник = РолиСотрудниковДоговорник.Сотрудник
И (&ИспользуетсяОтборПоРолиСотрудникаДоговорник = ИСТИНА)
И (РолиСотрудниковДоговорник.РольСотрудника = ЗНАЧЕНИЕ(Перечисление.РолиСотрудников.Договорник))}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СостоянияСотрудников КАК СостоянияСотрудников
ПО ДанныеДляПодбора.Сотрудник = СостоянияСотрудников.Сотрудник
И (СостоянияСотрудников.Период <= &ДатаОкончания)
И (СостоянияСотрудников.ДействуетДо >= &ДатаНачалаСведений
ИЛИ СостоянияСотрудников.ДействуетДо = ДАТАВРЕМЯ(1, 1, 1))}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДанныеОбОплатеТрудаДляПодбораСотрудников КАК ДанныеОбОплатеТрудаДляПодбора
ПО ДанныеДляПодбора.Сотрудник = ДанныеОбОплатеТрудаДляПодбора.Сотрудник
И ДанныеДляПодбора.ФизическоеЛицо = ДанныеОбОплатеТрудаДляПодбора.ФизическоеЛицо
И ДанныеДляПодбора.ИдентификаторЗаписи = ДанныеОбОплатеТрудаДляПодбора.ИдентификаторЗаписи}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ВидыЗанятостиСотрудниковИнтервальный КАК ВидыЗанятостиСотрудниковДляПодбора
ПО ДанныеДляПодбора.Сотрудник = ВидыЗанятостиСотрудниковДляПодбора.Сотрудник
И (ВЫБОР
КОГДА ДанныеДляПодбора.Окончание = ДАТАВРЕМЯ(1, 1, 1)
ТОГДА ДАТАВРЕМЯ(3999, 12, 31, 23, 59, 59)
ИНАЧЕ КОНЕЦПЕРИОДА(ДанныеДляПодбора.Окончание, ДЕНЬ)
КОНЕЦ МЕЖДУ ВидыЗанятостиСотрудниковДляПодбора.ДатаНачала И ВидыЗанятостиСотрудниковДляПодбора.ДатаОкончания)}
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РолиСотрудников КАК РолиСотрудниковРаботник
ПО ДанныеДляПодбора.Сотрудник = РолиСотрудниковРаботник.Сотрудник
И (&ИспользуетсяОтборПоРолиСотрудникаРаботник = ИСТИНА)
И (РолиСотрудниковРаботник.РольСотрудника = ЗНАЧЕНИЕ(Перечисление.РолиСотрудников.Работник))}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.РолиСотрудников КАК РолиСотрудниковДоговорник
ПО ДанныеДляПодбора.Сотрудник = РолиСотрудниковДоговорник.Сотрудник
И (&ИспользуетсяОтборПоРолиСотрудникаДоговорник = ИСТИНА)
И (РолиСотрудниковДоговорник.РольСотрудника = ЗНАЧЕНИЕ(Перечисление.РолиСотрудников.Договорник))
Тут можно одно соединение. И в селекте выбор когда. Остальное не смотрел. Просто сразу в глаза бросилось.
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТекущиеКадровыеДанныеСотрудников КАК ТекущиеКадровыеДанные
ПО ДанныеДляПодбора.ФизическоеЛицо = ТекущиеКадровыеДанные.ФизическоеЛицо
И ДанныеДляПодбора.Сотрудник = ТекущиеКадровыеДанные.Сотрудник
И ДанныеДляПодбора.Организация = ТекущиеКадровыеДанные.ГоловнаяОрганизация
(12) (14) Продолжим....
А у сотрудника бывает две разные организации?
Порядок измерений в РС.ДанныеДляПодбораСотрудников: Наименование, Сотрудник, ФизЛицо....
А Организация вообще ресурс, хотя и с индексом - правда не понятно зачем. Организаций обычно, ну десяток другой. Индекс позволяет быстро разделить список сотрудников на десяток другой групп. При этом по сотруднику уже разделяет наш список на эти группы.
ФизЛицо более "крупный" индекс по сравнению с Сотрудником. Если уж как есть, то в связи подсказать СУБД и указать, что сначала связь по Сотруднику, а уже потом по ФизЛицу. Не факт что поможет, но надо пробовать.
Наименование понятно для чего первым измерением - для частого поиска по ФИО.
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники КАК Сотрудники
ПО ДанныеДляПодбора.Сотрудник = Сотрудники.Ссылка
И ДанныеДляПодбора.Наименование = Сотрудники.Наименование
И (ДанныеДляПодбора.ИдентификаторЗаписи В
(ВЫБРАТЬ ПЕРВЫЕ 1
ДанныеДляПодбораСотрудниковОтбор.ИдентификаторЗаписи
ИЗ
РегистрСведений.ДанныеДляПодбораСотрудников КАК ДанныеДляПодбораСотрудниковОтбор
ГДЕ
Показать
По сути для каждого сотрудника надо взять "более" актуальную запись. Но она же одна, а не несколько. Сначала разобраться с актуальными (не актуальные выкинуть), а потом уже цеплять со справочником сотрудники по ссылке. Наименование уже не нужно. Не важно уже какое оно. Сотрудник уже уникальное поле. И если в РС не актуальное наименование, то для нашего случая это важно?
Наименование - это строка 100. Не быстро. Если не важно какое наименование, то ...
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДанныеОбОплатеТрудаДляПодбораСотрудников КАК ДанныеОбОплатеТрудаДляПодбора
ПО ДанныеДляПодбора.Сотрудник = ДанныеОбОплатеТрудаДляПодбора.Сотрудник
И ДанныеДляПодбора.ФизическоеЛицо = ДанныеОбОплатеТрудаДляПодбора.ФизическоеЛицо
И ДанныеДляПодбора.ИдентификаторЗаписи = ДанныеОбОплатеТрудаДляПодбора.ИдентификаторЗаписи}
Связь по "ИдентификаторЗаписи" уже уникальное условие для соединения. В них НЕ может НЕ совпасть сотрудник и физическое лицо. Для каждого изменения условий оплаты или кадрового перемещения создается уникальный ИД и прописывается в эти регистры. А выше уже можно (если нужно) ограничить какие нужны, а какие выкинуть, что бы не всё тащить.