gifts2017

Параметр Периодичность в СКД

Опубликовал Богдан Буляков (Laertid) в раздел Программирование - Практика программирования

Поиски в интернете удобных решений для задания в СКД пользовательского параметра Периодичность у меня успехом не увенчались. Поэтому когда в голову пришло такое решение, решил выложить.

Итак, задача состоит в том, чтобы для оборотного регистра накопления через выбор пользователем значения параметра Периодичность задавалась соответствующая периодичность регистра.

Очевидный способ вроде "РегистрНакопления.ЗаказыПокупателей.Обороты(, , День {(&Периодичность)}, )" не работает - СКД ругается на наличие параметра в этом месте.

Вариант "РегистрНакопления.ЗаказыПокупателей.Обороты(, , Авто, )" имеет такой недостаток, что пользователю приходится в настройках вывода отчета во всех местах, где он хочет отобразить период, изменять поле с ПериодДень на ПериодНеделя (или другие). Неудобно, некрасиво, раздражает. Но все же работает.

Еще вариант, красивый но для больших объемов данных не выигрышный. Используем в запросе периодичность День (или мельче вплоть до Регистратор). Создаем вычисляемое поле ПериодНовый с выражением вроде НачалоПериода(, &Периодичность). Параметры оформляем так же, как в итоговом решении (см. рисунок Параметры). Минус в том, что запрос, независимо от выбора Периодичности, выполняется с периодом День (или какой мы указали в запросе), а потом поле периода еще и пересчитывается. То есть такой отчет не только не оптимизирует отчет, но и содержит дополнительные вычисления.



Я предлагаю промежуточный вариант. Заводим следующие параметры (см. соответствующий рисунок). Видим 2 параметра Периодичность - один доступен пользователю, второй задан таким образом, что существует всегда. независимо от того, выбрал пользователь параметр или нет. Параметрам задан список допустимых значений "День", "Неделя", и т.д.

В запросе встречается параметр &Периодичность следующим образом:

ВЫБРАТЬ  

ВЫБОР   

КОГДА &Периодичность = "Неделя"    ТОГДА ЗаказыПокупателейОбороты.ПериодНеделя   

КОГДА &Периодичность = "Месяц"    ТОГДА ЗаказыПокупателейОбороты.ПериодМесяц   

КОГДА &Периодичность = "Кварта"    ТОГДА ЗаказыПокупателейОбороты.ПериодКвартал   

КОГДА &Периодичность = "Год"    ТОГДА ЗаказыПокупателейОбороты.ПериодГод   

ИНАЧЕ ЗаказыПокупателейОбороты.ПериодДень  КОНЕЦ КАК Период

ИЗ  РегистрНакопления.ЗаказыПокупателей.Обороты(, , Авто, ) КАК ЗаказыПокупателейОбороты

 

 

Затем поле период используем там, где нам надо. параметр Периодичность пользователь видит в списке параметров.

 

P.S. Я не знаю точно, считает ли СКД при запросе все поля периодДень, ПериодНеделя и т.д. или все же сама выбирает только нужное. Если кто знает, буду рад конкретному ответу. К сожалению, если она вычисляет их все, то данный способ становится не лучше, чем третий из упомянутых в начале.

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Евгений (Algiz) 17.01.12 14:41
а СтандартныйПериод не подходил?
2. Богдан Буляков (Laertid) 17.01.12 14:54
(1) Algiz, СтандартныйПериод задает границы периода. Пост не про это, с границами проблем нет, их можно десятком работающих способов задать. Тут нужна была периодичность настраиваемая, День/Месяц/Год. СтандартныйПериод я пока не использую, так что могу не знать, но скажите, там кроме ДатаНачала и ДатаКонца еще есть поле периодичности?
3. Георгий Перминов (Georgsius) 17.01.12 15:35
(2) Laertid, да есть Вариант, принимает значения ВариантСтандартногоПериода
4. Богдан Буляков (Laertid) 17.01.12 15:42
(3) Georgsius, это тоже не то. Нужна Периодичность - ссылка на Перечисления.Периодичность, или что-то в этом роде. Список "Начало дня/Начало недели/..." не позволит Вам задать периодичность отчета Квартал, а потом Декада, разве нет? Это поле служит для вычисления какой-то характерной даты из списка для нашей текущай даты.
5. Евгений Кабанов (kabanoff) 19.01.12 13:06
Мы на работе делаем так: в тех регистрах РБ и РН, где нужна произвольная периодичность больше, например, дня, в параметрах виртуальной таблицы оборотов ставим "День". А затем такую таблицу выводим в любой нужной пользователю периодичности. На скорости это существенно не сказывается, отчеты формируются достаточно быстро. Хотя база большая (около 90Гб).

Так что я бы на твоем месте не заморачивался и использовал вариант 3.
6. Богдан Буляков (Laertid) 19.01.12 13:19
Базу надолго занимать нельзя >_< А считается оно на больших временных периодах по несколько минут. У нас тоже, насколько я знаю, под сотню Гб база :)
7. Евгений Кабанов (kabanoff) 19.01.12 13:53
(6) Как вариант, можно сделать 6 необязательных соединений к РН с разной периодичностью, например,
8. Евгений Кабанов (kabanoff) 19.01.12 13:57
(6) Как вариант, можно сделать несколько необязательных соединений к РН с разной периодичностью, например:

ВЫБРАТЬ
ОсновнаяТаблица.*,
...
{...,
ПериодДень,
ПериодМесяц,
...}
ИЗ ОсновнаяТаблица
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ЗаказыПокупателей.Обороты(, , День, ) КАК ЗаказыПокупателейОборотыДень
ПО ...}
{ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ЗаказыПокупателей.Обороты(, , Месяц, ) КАК ЗаказыПокупателейОборотыМесяц
ПО ...}
...Показать Скрыть


В этом случае при выборе поля будет происходить только то соединение, чье поле выбрано в отчете.
9. Богдан Буляков (Laertid) 19.01.12 14:03
Да, только что попробовал еще один вариант, тоже основанный на Авто... Этот вот выбор большой прописал не в запросе, а в Вычисляемом поле. Тогда запрос точно выполняется в зависимости от выбора параметра Периодичность. И Ваша идея (20) работает на отлично :) *но все равно это всё попахивает извратом :D*
К сожалению, ни один из вариантов не дает ощутимого прироста в производительности :( Так что из двух последних вариантов в теме и вот этого, который в комментарии, выбирайте, какой удобный.
12. Богдан Буляков (Laertid) 19.01.12 15:51
М-м, кто-нибудь знает, можно ли таких вот хитрых банить или еще как-то наказывать? Ну и поудалять эти комменты тоже.
13. Dima Dr. (Scukosan) 19.01.12 23:09
(11) pavlov128, ставьте минусики)
а если по теме, то с переиодичностью в 1С явно что то не продуманно..
или нагромождаешь ненужными данными или теряешь в производительности..
сам писал вариант чем то похожий на (8) kabanoff и в производительности нет особых потерь и при формировании процесором макета отчета ненужные параметры отсекаются..
14. Богдан Буляков (Laertid) 20.01.12 09:11
Мой рейтинг пока недостаточен, чтоб минусики ставить :(
В (8) написана хорошая штука, но к теме непосредственного отношения не имеет. Про привязку периодичности регистра к параметру там не сказано.
15. Модератор раздела Артур Аюханов (artbear) 20.01.12 12:01
Офф. (12) По вашему замечанию выполнено - Чел забанен на 30 суток.
Всем - Пишите в форум Совет Администрации/Сообщества, будем таких отлавливать и ЖЕСТКО с ними разбираться.
16. Богдан Буляков (Laertid) 20.01.12 12:12
17. Иван Петров (boing) 24.01.12 09:59
Подскажите как заработать 1start для скачивания файла?
18. Богдан Буляков (Laertid) 24.01.12 10:03
Самое простое - оставляй комменты. Вот тебе сейчас немножечко прибавилось. Только комментируй по теме, ибо банят активно и оперативно.
Еще, если у тебя есть чем поделиться, можешь написать статью с файлом-вложением. Скачивание кем-то файла из твоей статьи дает тебе 1$м.
19. Dima Dr. (Scukosan) 24.01.12 13:16
забыл описать еще один вариант использования периодичности
нужно было сделать отчет с возможность выбора периодичности данных
поставил в параметрах виртуально таблицы периодичность поставил авто
а на закладке компоновка данных добавил все необходимые периоды и отключил в настройках макета ненужные для отбора поля
как итог пользователь получил возможность формировать отчет с необходимой периодичностью
20. Богдан Буляков (Laertid) 24.01.12 13:27
Этот способ я описал как второй. Если я правильно понимаю, пользователь в нем вынужден выбирать нужное ему поле - периодДень, периодНеделя, периодГод и т.д. Для пользователя типа "Бухгалтер" это неприятно и неудобно. Суть-то как раз в том, чтобы он мог выбрать из списка значение параметра, к такому способу настройки они привычны. Если этого не сделать, то необходимо менять это поле в настройках в Выбранных полях, в Группировке, в Сортировке, в отборе (если вдруг), и нигде не забыть ;)
21. leraks1 leraks1 (leraks) 22.03.12 11:53
22. sanches (sanches) 27.04.12 23:22
Спасибо за публикацию. Подскажите пожалуйста по моей ситуации.
Я пишу в тексте запроса следующее
ВЫБРАТЬ
	ЗаказыПоставщикам.ЗаказПоставщику,
	ЗаказыПоставщикам.Номенклатура,
	ЗаказыПоставщикам.Период
ИЗ
	(ВЫБРАТЬ
		ЗаказыПоставщикамОстаткиИОбороты.ЗаказПоставщику КАК ЗаказПоставщику,
		ЗаказыПоставщикамОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток,
		ЗаказыПоставщикамОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток,
		ЗаказыПоставщикамОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход,
		ЗаказыПоставщикамОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход,
		ЗаказыПоставщикамОстаткиИОбороты.Номенклатура КАК Номенклатура,
		ВЫБОР
			КОГДА &Периодичность = "Месяц"
				ТОГДА ЗаказыПоставщикамОстаткиИОбороты.ПериодМесяц
			КОГДА &Периодичность = "День"
				ТОГДА ЗаказыПоставщикамОстаткиИОбороты.ПериодДень
			КОГДА &Периодичность = "Неделя"
				ТОГДА ЗаказыПоставщикамОстаткиИОбороты.ПериодНеделя
			КОГДА &Периодичность = "Квартал"
				ТОГДА ЗаказыПоставщикамОстаткиИОбороты.ПериодКвартал
		КОНЕЦ КАК Период
	ИЗ
		РегистрНакопления.ЗаказыПоставщикам.ОстаткиИОбороты({(&НачалоПериода)}, {(&КонецПериода)}, Авто, , ) КАК ЗаказыПоставщикамОстаткиИОбороты) КАК ЗаказыПоставщикам
...Показать Скрыть

В результате получается таблица, в которой строк в два раза больше чем должно быть. Одна и та же номенклатура выходит 2 раза. Если же пишу так
ВЫБРАТЬ
	ЗаказыПоставщикам.ЗаказПоставщику,
	ЗаказыПоставщикам.Номенклатура,
	ЗаказыПоставщикам.Период
ИЗ
	(ВЫБРАТЬ
		ЗаказыПоставщикамОстаткиИОбороты.ЗаказПоставщику КАК ЗаказПоставщику,
		ЗаказыПоставщикамОстаткиИОбороты.КоличествоНачальныйОстаток КАК КоличествоНачальныйОстаток,
		ЗаказыПоставщикамОстаткиИОбороты.КоличествоКонечныйОстаток КАК КоличествоКонечныйОстаток,
		ЗаказыПоставщикамОстаткиИОбороты.КоличествоПриход КАК КоличествоПриход,
		ЗаказыПоставщикамОстаткиИОбороты.КоличествоРасход КАК КоличествоРасход,
		ЗаказыПоставщикамОстаткиИОбороты.Номенклатура КАК Номенклатура,
		ЗаказыПоставщикамОстаткиИОбороты.ПериодМесяц КАК Период
	ИЗ
		РегистрНакопления.ЗаказыПоставщикам.ОстаткиИОбороты({(&НачалоПериода)}, {(&КонецПериода)}, Авто, , ) КАК ЗаказыПоставщикамОстаткиИОбороты) КАК ЗаказыПоставщикам
...Показать Скрыть
то дублирования не происходит.
Периодичность выбираю месяц. Данные выбираю за один месяц. Подскажите что не верно?
Спасибо
23. Александр Исупов (isupov) 16.05.12 06:27
А у меня такой запрос работает:
ВЫБРАТЬ
КонтНачисленияОбороты.Полис,
КонтНачисленияОбороты.Период
ИЗ
РегистрНакопления.КонтНачисления.Обороты(&НачПериода, &КонПериода, День {(&Периодичность)}, ) КАК КонтНачисленияОбороты

Платформа: 8.2.13.202
Дальше программно, сама периодичность думаю числа День - 6, например. Посчитать несложно, или посмотреть в отладчике.
24. Богдан Буляков (Laertid) 16.05.12 09:52
(23) isupov, данный прием работает в Построителе отчетов, я мы обсуждаем СКД.
25. Богдан Буляков (Laertid) 16.05.12 09:55
(22) sanches, не могу сказать точно, почему оно так работает, но как вариант - в выборе надо явно прописать строку ИНАЧЕ.
Попробуйте сравнить даты у дублированных строк, которые выдает первый запрос. Возможно, они различаются и вам это что-то даст.
26. sanches (sanches) 27.06.12 15:19
Столкнулся с еще одной проблемой :)
Если выбирать периодичность Авто в параметрах виртуальной таблицы, то автоматически в запросе добавляются записи вплоть до документов (поправьте если не так). В этом случае если я хочу еще получать начальные и конечные остатки по периодам, то они рассчитываются на каждый документ, а потом суммируются в итоге, что приводит к неверному формированию данных о начальных и конечных остатках. Если что не так делаю, подскажите. Спасибо.
27. Богдан Буляков (Laertid) 27.06.12 15:39
(26) sanches, насколько я знаю, детализация в этом случае ограничивается тем уровнем, который вы используете в качестве поля. То есть если вы хотите получить детализацию по дням, тогда используете соответствующий ПериодДень, кажется, и СКДшка будет добывать данные из виртуальной таблицы, соответствующие именно этой периодичности. Она умная... вроде :) Если период вообще не использовать и не использовать группировок... Не пробовал, не знаю еще. Поэкспериментируйте :)
FractalizeR; sanches; +2 Ответить
28. sanches (sanches) 27.06.12 15:48
Вот похоже у меня опять моя первая проблема вылезла, что если явно указать в запросе например
ТоварыНаСкладахОстаткиИОбороты.ПериодМесяц
, то в результате остатки начальные и конечные правильно получаются, если же писать в выборке
ВЫБОР
			КОГДА &Периодичность = ЗНАЧЕНИЕ(Перечисление.Периодичность.День)
				ТОГДА ТоварыНаСкладахОстаткиИОбороты.ПериодДень
			КОГДА &Периодичность = ЗНАЧЕНИЕ(Перечисление.Периодичность.Неделя)
				ТОГДА ТоварыНаСкладахОстаткиИОбороты.ПериодНеделя
			КОГДА &Периодичность = ЗНАЧЕНИЕ(Перечисление.Периодичность.Месяц)
				ТОГДА ТоварыНаСкладахОстаткиИОбороты.ПериодМесяц
			ИНАЧЕ ТоварыНаСкладахОстаткиИОбороты.ПериодМесяц
		КОНЕЦ КАК П
...Показать Скрыть

то даже в консоли запросов выходит столько строк, сколько было движений за период и на каждую строку рассчитывается свой остаток, что в итоге приводит к неверному итоговому значению начального и конечного остатка.
Не пойму, где я косячу :)
Прикладываю скрины, может кто-то вразумит меня. В фильтре отчета указана одна позиция номенклатуры

Gayana; Serg0912; +2 Ответить
29. Сергей Галюк (dj_serega) 25.03.15 15:50
Я бы еще посоветовал так писать выбор периодичности (платформа 8.3.5)
ВЫБОР &Периодичность
		КОГДА "Неделя"
			ТОГДА НАЧАЛОПЕРИОДА(НазначенияВрачейОбороты.Период, НЕДЕЛЯ)
		КОГДА "Месяц"
			ТОГДА НАЧАЛОПЕРИОДА(НазначенияВрачейОбороты.Период, МЕСЯЦ)
		ИНАЧЕ НАЧАЛОПЕРИОДА(НазначенияВрачейОбороты.Период, ДЕНЬ)
	КОНЕЦ КАК Период,
...Показать Скрыть

30. Семён Павлюков (7OH) 16.10.16 20:21
Спасибо за идею.
Добавьте пару правок:.
1. Чтобы не было "Кварта" - надо тип строки поставить длину побольше (чтобы, например, влезло "Полугодие").
2. Ставим у Периодичность использование всегда - и тогда нужен всего один параметр.
3. Ну и через СтандартныйПериод 2 параметра было бы приятнее лицезреть.