&НаСервере
Функция ПодготовитьЗапросСДанными()
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| &Период1 КАК Период
|ПОМЕСТИТЬ ВТ_Периоды
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| &Период2
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| &Период3
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СотрудникиСрезПоследних.Сотрудник КАК Сотрудник,
| СотрудникиСрезПоследних.СтруктурнаяЕдиница КАК СтруктурнаяЕдиница,
| СотрудникиСрезПоследних.Должность КАК Должность,
| СотрудникиСрезПоследних.ЗанимаемыхСтавок КАК ЗанимаемыхСтавок,
| СотрудникиСрезПоследних.ГрафикРаботы КАК ГрафикРаботы
|ПОМЕСТИТЬ ВТ_РаботающиеСотрудники
|ИЗ
| РегистрСведений.Сотрудники.СрезПоследних(&ПериодКонец, ) КАК СотрудникиСрезПоследних
|ГДЕ
| СотрудникиСрезПоследних.ЗанимаемыхСтавок > 0
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| СотрудникиДополнительныеРеквизиты.Ссылка КАК Ссылка,
| СотрудникиДополнительныеРеквизиты.Значение КАК Значение,
| СотрудникиДополнительныеРеквизиты.Ссылка.Наименование КАК Наименование
|ПОМЕСТИТЬ ВТ_СотрудникиИзГруппы
|ИЗ
| ВТ_РаботающиеСотрудники КАК ВТ_РаботающиеСотрудники
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Сотрудники.ДополнительныеРеквизиты КАК СотрудникиДополнительныеРеквизиты
| ПО (ВТ_РаботающиеСотрудники.Сотрудник = СотрудникиДополнительныеРеквизиты.Ссылка)
|ГДЕ
| СотрудникиДополнительныеРеквизиты.Свойство = &Свойство
| И СотрудникиДополнительныеРеквизиты.Значение = &Значение
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| РАУ_СтатусИПР.Период КАК Период,
| РАУ_СтатусИПР.Сотрудник КАК Сотрудник,
| РАУ_СтатусИПР.Продвижение КАК Продвижение,
| РАУ_СтатусИПР.Комментарий КАК Комментарий
|ПОМЕСТИТЬ ВТ_ДанныеИзРС
|ИЗ
| РегистрСведений.РАУ_СтатусИПР КАК РАУ_СтатусИПР
|ГДЕ
| РАУ_СтатусИПР.Период >= &ПериодНачало
| И РАУ_СтатусИПР.Период <= &ПериодКонец
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_СотрудникиИзГруппы.Ссылка КАК Ссылка,
| ВТ_Периоды.Период КАК Период,
| ВТ_СотрудникиИзГруппы.Наименование КАК Наименование
|ПОМЕСТИТЬ ВТ_СотрудникиПериоды
|ИЗ
| ВТ_СотрудникиИзГруппы КАК ВТ_СотрудникиИзГруппы,
| ВТ_Периоды КАК ВТ_Периоды
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВТ_СотрудникиПериоды.Ссылка КАК Сотрудник,
| ВТ_СотрудникиПериоды.Период КАК Период,
| ЕСТЬNULL(ВТ_ДанныеИзРС.Продвижение, ЛОЖЬ) КАК Продвижение,
| ЕСТЬNULL(ВТ_ДанныеИзРС.Комментарий, """") КАК Комментарий,
| рауИндивидуальныйПланРазвития.Ссылка КАК ИПР_Документ
|ИЗ
| ВТ_СотрудникиПериоды КАК ВТ_СотрудникиПериоды
| ЛЕВОЕ СОЕДИНЕНИЕ ВТ_ДанныеИзРС КАК ВТ_ДанныеИзРС
| ПО ВТ_СотрудникиПериоды.Ссылка = ВТ_ДанныеИзРС.Сотрудник
| И ВТ_СотрудникиПериоды.Период = ВТ_ДанныеИзРС.Период
| ЛЕВОЕ СОЕДИНЕНИЕ Документ.рауИндивидуальныйПланРазвития КАК рауИндивидуальныйПланРазвития
| ПО (рауИндивидуальныйПланРазвития.Сотрудник = ВТ_СотрудникиПериоды.Ссылка)
|
|УПОРЯДОЧИТЬ ПО
| ВТ_СотрудникиПериоды.Наименование, Период";
Запрос.УстановитьПараметр("Свойство",ЭтаФорма.ПланВидовХарактеристик);
Запрос.УстановитьПараметр("ПериодНачало",Объект.ПериодНачало);
Запрос.УстановитьПараметр("ПериодКонец",Объект.ПериодКонец);
Запрос.УстановитьПараметр("Значение",ЭтаФорма.Группа);
Запрос.УстановитьПараметр("Период1",НачалоМесяца(Объект.ПериодНачало));
Запрос.УстановитьПараметр("Период2",НачалоМесяца(ДобавитьМесяц(Объект.ПериодНачало,1)));
Запрос.УстановитьПараметр("Период3",НачалоМесяца(ДобавитьМесяц(Объект.ПериодНачало,2)));
Возврат Запрос;
КонецФункции
| Ревьюер | 1С:Напарник | GPT | Gemini 2.5 pro |
|---|---|---|---|
| 1. Проблема: Критично, производительность: Фильтрация виртуальной таблицы в секции ГДЕ
Описание: Использование секции ГДЕ для фильтрации данных виртуальной таблицы приводит к тому, что система сначала получает все записи регистра на указанную дату, и только потом применяет фильтр. Это вызывает серьезную деградацию производительности, особенно на больших базах.
Рекомендация: Перенесите условие в параметры виртуальной таблицы: СрезПоследних(&ПериодКонец, ЗанимаемыхСтавок > 0).
2. Проблема: Критично, функционал: Отсутствие условий соединения с таблицей документа (Декартово произведение)
Описание: Соединение с таблицей документа выполняется только по сотруднику. Если у сотрудника есть несколько документов "рауИндивидуальныйПланРазвития" за разные периоды (или даже в одном периоде), это приведет к задвоению/размножению строк в итоговом результате.
Рекомендация: Необходимо добавить условие соединения по периоду (например, попадание даты документа в месяц) или использовать срез последних/подзапрос, чтобы выбрать только один актуальный документ для сотрудника на конкретный период.
3. Проблема: Важно, производительность: Неявное соединение таблиц (разыменование ссылки)
Описание: Получение реквизита через точку от ссылки (Ссылка.Наименование) вызывает неявное левое соединение с основной таблицей справочника "Сотрудники" на уровне СУБД. Это снижает оптимальность запроса.
Рекомендация: Лучше получать "Наименование" в первом пакете запроса (ВТ_РаботающиеСотрудники), где уже есть поле "Сотрудник", либо явно соединить таблицу "Справочник.Сотрудники".
4. Проблема: рекомендация, производительность: Использование ОБЪЕДИНИТЬ вместо ОБЪЕДИНИТЬ ВСЕ
Описание: Оператор ОБЪЕДИНИТЬ выполняет неявный поиск дублей и сортировку, что требует дополнительных ресурсов. Так как в параметры передаются заведомо разные периоды (НачалоМесяца, ДобавитьМесяц 1, ДобавитьМесяц 2), дублей быть не может.
Рекомендация: Замените «ОБЪЕДИНИТЬ» на «ОБЪЕДИНИТЬ ВСЕ».
5. Проблема: Рекомендация, производительность: Отсутствие индексов у временных таблиц
Описание: Временные таблицы ВТ_СотрудникиПериоды и ВТ_ДанныеИзРС используются в соединениях в последнем пакете запроса. Отсутствие индексов может привести к сканированию всей таблицы (Table Scan) при соединении.
Рекомендация: Добавьте команду ИНДЕКСИРОВАТЬ ПО в пакеты создания ВТ. Для ВТ_ДанныеИзРС: ИНДЕКСИРОВАТЬ ПО Сотрудник, Период. Для ВТ_СотрудникиПериоды: ИНДЕКСИРОВАТЬ ПО Ссылка, Период.
6. Проблема: рекомендация, оформление: Избыточное использование контекста формы
Описание: Прямое обращение к контексту формы через "ЭтаФорма" внутри серверных вызовов модуля формы не является ошибкой, но считается избыточным и не соответствует современным стандартам чистого кода 1С.
Рекомендация: Удалите "ЭтаФорма." и обращайтесь к реквизитам напрямую: ПланВидовХарактеристик, Группа.
| 1. Отступы и форматирование: В целом, код хорошо отформатирован. Однако, некоторые строки запроса можно было бы сделать более читаемыми, используя отступы и переносы строк.
2. Именование параметров: Параметры запроса такие как &Период1, &Период2, &Период3, &Свойство, &Значение, &ПериодНачало, &ПериодКонец можно было бы назвать более осмысленно, чтобы было понятно их предназначение.
3. Проверка параметров: Перед использованием параметров запроса (ЭтаФорма.ПланВидовХарактеристик, Объект.ПериодНачало, Объект.ПериодКонец, ЭтаФорма.Группа), было бы неплохо проверить их на заполненность и тип, чтобы избежать потенциальных ошибок.
4. Упорядочивание: В запросе используется УПОРЯДОЧИТЬ ПО, но поля для упорядочивания не полностью квалифицированы. Лучше указать полные имена полей.
5. Использование временных таблиц: Код активно использует временные таблицы, что является хорошей практикой для сложных запросов. Однако, стоит убедиться, что индексы на временных таблицах настроены правильно для оптимальной производительности.
| 1. Серверный контекст нарушен: в функции используются ЭтаФорма и Объект.*. На сервере к форме обращаться нельзя — параметры нужно передавать явно.
2. Вирт.таблица СрезПоследних(&ПериодКонец, ) — синтаксическая ошибка (лишняя запятая). Должно быть СрезПоследних(&ПериодКонец).
3. Генерация трёх периодов через три параметра (&Период1/2/3) — негибко и шумно. Лучше построить периоды из «смещений» (0..2) прямо в запросе (ДОБАВИТЬКДАТЕ + НАЧАЛОПЕРИОДА).
4. Не задан порядок/индексация временных таблиц. Для производительности стоит ИНДЕКСИРОВАТЬ ПО по ключам соединений.
5. Возможны дубликаты из Документ.рауИндивидуальныйПланРазвития (если документов несколько на сотрудника). Нужна либо фильтрация, либо ограничение (в примере оставлю как есть, но помечу место).
6. Финальная сортировка идёт по Наименование из ВТ, но поле в SELECT не выводится (хотя и не обязано). Убедимся, что оно действительно присутствует в ВТ и используется в УПОРЯДОЧИТЬ.
7. Стиль/читаемость: многословные префиксы для ВТ, лишние «коммент-разделители», дубли имён — можно компактнее.
| 1. Временная таблица ВТ_Периоды жестко формируется для трех месяцев, начиная с Объект.ПериодНачало. Это делает код негибким: если потребуется отчет за другой интервал (например, 6 месяцев или 1 месяц), придется изменять сам запрос.
2. ЛЕВОЕ СОЕДИНЕНИЕ с таблицей Документ.рауИндивидуальныйПланРазвития (строки 86-87) выполняется только по полю Сотрудник. Если у одного сотрудника существует несколько документов "Индивидуальный план развития", каждая строка сотрудника будет умножена на количество его документов. Это приведет к неверным данным и серьезному падению производительности.
3. Запрос разбит на множество мелких временных таблиц. Хотя это может помогать в отладке, такая структура не всегда оптимальна и может затруднять чтение всего запроса целиком.
4. В УПОРЯДОЧИТЬ ПО (строки 89-90) используется поле ВТ_СотрудникиПериоды.Наименование, которое не включено в итоговую выборку ВЫБРАТЬ. Хотя синтаксис 1С это допускает, такой подход ухудшает читаемость и сопровождение кода, так как не очевидно, по какому именно значению происходит сортировка.
5. У самой функции ПодготовитьЗапросСДанными нет заголовочного комментария, который бы описывал ее назначение. Это нарушает стандарты оформления кода и усложняет его понимание для других разработчиков.
|