Как обойти использование запроса в цикле? #386245


#0 by Gallant
Попалась учебная задача на специалиста по платформе 8.1. В целом понятно и очевидно, что если гонять запрос в цикле, то это существенно тормозит работу программы. Но вот иногда бывают случаи, когда неочевидно, как сделать по-другому (а еще точнее - правильно). Приведу кусок задачи: Сотрудники получают оклад (начисляется только по отработанным дням). В том случае, если сотрудник продал в текущем месяце товаров на сумму, меньшую его лимита, то его штрафуют. Лимит устанавливается для каждого сотрудника индивидуально и может изменяться не чаще одного раза в день. Лимит для расчета определяется на начало расчетного периода. Штраф считается процентом от оклада, начисленного в предыдущем месяце. Процент штрафа определяется индивидуально и указывается прямо в документе «Начисление зарплаты». Задача решается естественно на каркасной конфигурации. Вариантов решения я смог придумать 2: 1) Нужно приделать в документе кнопочку, которая будет проверять продажи сотрудников (для этого делаем оборотный регистр, который данную информацию хранит), сравнивать с лимитом продаж данного сотрудника (хранится как ресурс регистра сведений "Сотрудники") и подставлять сотрудников, которых положено оштрафовать, в табличную часть документа. Минусом мне видится следующий момент: период, за который получаются обороты. За период можно взять месяц, который определяет реквизит документа "ПериодРегистрации" (ДатаНач = НачалоМесяца(ПериодРегистрации); ДатаКон = КонецМесяца(ПериодРегистрации);), но как быть если мы вводим начисление за неполный месяц? Или, скажем, за прошлый месяц? Как-то негибко все. 2) Второй вариант совсем неправильный с точки зрения описания грубых ошибок, приведенных в требованиях к экзамену. В общем модуле в процедуре Рассчитать(Движения, Ссылка) по каждой строке начисления оклада (в этих строках как раз указаны даты начала и окончания периода, за который происходит начисление) выбирать обороты продаж за период и уже их сравнивать с ресурсом "ЛимитПродаж". Данный запрос будет похож на запрос из 1 варианта решения, но он должен выполняться в цикле по каждой строке, что является грубой ошибкой. Хотя такое решение мне кажется более гибким. Безусловно на экзамене из этих 2 решений предпочтение стоит отдать 1 варианту, хотя он мне кажется некрасивым. Вот у меня и родилась просьба привести более красивое решение, если таковое существует, а так же просто соображениями и примерами. P.S. Кстати, подобная проблема, насколько я знаю, есть и в других билетах экзамена.
#1 by ТелепатБот
#2 by Defender aka LINN
"но как быть если мы вводим начисление за неполный месяц? Или, скажем, за прошлый месяц?" - а как ты эту "проблему" во втором случае решишь?
#3 by Gallant
В каждой строке регистра расчета есть реквизиты ПериодДействияНачало и ПериодДействияОкончание, поскольку оклад использует период действия - вот за этот период на мой взгляд брать обороты логичнее. Разве нет?
#4 by BuHu
"Минусом мне видится следующий момент: период, за который получаются обороты. За период можно взять месяц, который определяет реквизит документа "ПериодРегистрации" (ДатаНач = НачалоМесяца(ПериодРегистрации); ДатаКон = КонецМесяца(ПериодРегистрации);), но как быть если мы вводим начисление за неполный месяц? Или, скажем, за прошлый месяц? Как-то негибко все. " А в чем минус то? что ты не можеш рассчитать?
#5 by Gallant
Минусом мне видится то, что можно штраф ввести только по кнопочке и только за период месяц, причем строго определенный периодом регистрации документа. А если начисление будет за полмесяца? Или это не играет никакой роли? Допустим, что при начислении штрафа не повлияет, потому что не имеет особого смысла начислять штраф за полмесяца. Но в другой задаче я видел скажем другой момент с подобным контекстом: Сотрудники получают оклад, равный Прибыль подразделения, умноженный на КТУ (коэффициент трудового участия) этого сотрудника. Если начислять оклад за полмесяца, а оборот получать за период НачалоМесяца(ПериодРегистрации) - КонецМесяца(ПериодРегистрации), то начислится оклад, как за целый месяц. Или я что-то не понимаю в формулировке задачи?
#6 by BuHu
а количество рабочих дней в месяце и количество отработаных ?
#7 by Gallant
и как будет выглядеть функция? Для получения количества дней всего и отработанных есть поля в виртуальной таблице РегистрРасчета.ОсновныеНачисления.ДанныеГрафика с названиями "ЗначениеПериодДействия" (количество рабочих дней, назовем это НОРМА) и "ЗначениеФактическийПериодДействия" (реально отработано дней, назовем это ФАКТ). А начисление считается по простой формуле: ДневнаяСтавка = База / Норма; Результат = ДневнаяСтавка * Факт; Так вот при начислении за полмесяца (допустим пропусков не было) отношение ФАКТ / НОРМА = 1, то есть начислится Результат = База. Так же, как и за месяц при отсутствии пропусков. ТО ЕСТЬ: при таком раскладе Базу надо получать за тот период, за который вводится начисление, иначе может возникнуть ошибка.
#8 by BuHu
как за полмесяца человек сделал месячную норму часов ? а если и сделал норму то и получить должен весь оклад
#9 by Gallant
в рамках учебной задачи мы делаем по-простому - берем просто отношение Факт / Норма, то есть число [0..1], которое умножим на Базу. А потому я и спрашиваю, как будет выглядеть функция сравнения в предложенном решении? И напомню главный вопрос этой темы: Какие существуют еще варианты решения?
#10 by Aprobator
Что, собственно, говоря для 1 - ого решения мешает использовать фактический периода действия Оклада?
#11 by Aprobator
Т.е. сначала рассчитывается и делаются записи в регистре расчета по Окладу. Затем запрос по Регистру расчета ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления по сотруднику и периоду. Ну и т.д..
#13 by Gallant
В целом все так, но проблема в периоде, за который мы берем данные регистра накопления. Он может быть в каждой строке свой. А гонять цикл по строкам нельзя.
#14 by Мелкий бес
и чем это левое соединение отличается от запроса в цикле :)
#15 by YauheniL
В куске по регистрам расчетов можно использовать запрос в цикле (если, например, смотреть ЗУП, по идее, идеал для данного кусочка задачи, то там запросы в циклах активно используются). Так, 1 балл снимут, но прокомментируют всякую муть, а не эту ошибку
#16 by Gallant
А есть какие-нибудь официальные рекомендации на этот счет?.. Потом ведь не докажешь никому на экзамене, что без запроса в цикле не совсем адекватно расчет идет. P.S. А есть какой-либо способ привлечь к этой теме кого-то из теоретиков 1С, чтобы они могли это прокомментировать? Например, г-на Волшебника
Тэги:
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С