Related Posts
- Получение логина и пароля техподдержки 1С из базы
- Класс для вывода отчета в Excel
- Счет-фактура для УПП
- Библиотека классов для создания внешней компоненты 1С на C#
- Акт об оказании услуг (со скидками) — внешняя печатная форма для Управление торговлей 11.1.10.86
- Прайс-лист с артикулом в отдельной колонке
Что такое РегистрСведений.РегламентированныйПроизводственныйКалендарь и где его найти?
(1) akomar, вопрос скорее для пятницы! )))
(1) akomar,
ЗУП тебе в помощь.
Ну я бы сначало написал, что актуально для ЗУП.
Да ладно, в Бухии 2.0 он тоже есть. Думаю, что это стандарт 1С.
РегламентированныйПроизводственныйКалендарь есть БУХ, ЗУП, УПП. Содержит все даты периода. Прикладное значение, к примеру, можно получить в запросе остатки на каждый день, неделю и т.д. в соединении с регистрами накопления и т.п. Тебе для чего нужно ?
Автор, совет, изучай СКД и не понадобится тебе зуповский регистр который к тому же в бухе редко кто заполняет
(7) Спасибо за бесплатный совет, но не всё можно решить на СКД. Хотя, если подскажете, как вызвать СКД из общего модуля при проведении или расчете документа, буду очень признателен. К тому же язык запросов не отличается от используемого в СКД.
З.Ы. А регистр и не надо заполнять, он заполняется автоматически при обновлении ИБ.
Спасибо. Правда, не совсем понял, зачем вторая временная таблица и левое соединение к ней в итоговом запросе. Может быть, так:
ВЫБРАТЬ
ПроизводственныйКалендарь.ДатаКалендаря,
ГОД(ПроизводственныйКалендарь.ДатаКалендаря) * 100 + МЕСЯЦ(ПроизводственныйКалендарь.ДатаКалендаря) КАК НомерМесяца
ПОМЕСТИТЬ ВТ_ДатыКалендаря
ИЗ
РегистрСведений.РегламентированныйПроизводственныйКалендарь КАК ПроизводственныйКалендарь
ГДЕ
ПроизводственныйКалендарь.ДатаКалендаря МЕЖДУ &ПериодДействияНачало И &ПериодДействияКонец
;
ВЫБРАТЬ
МИНИМУМ(ВТ_ДатыКалендаря.ДатаКалендаря) КАК ДатаНачала,
МАКСИМУМ(ВТ_ДатыКалендаря.ДатаКалендаря) КАК ДатаОкончания
ИЗ
ВТ_ДатыКалендаря КАК ВТ_ДатыКалендаря
СГРУППИРОВАТЬ ПО
ВТ_ДатыКалендаря.НомерМесяца
(9) Mu_meson, да, так гораздо лучше =)
ПроизводственныйКалендарь для примера или он необходим по любому т.к. там все даты?
Интересует вопрос:
необходимо сгрупирровать по периодам (месяцам) данные по выборке документов, что бы в результате по куждому месяцу увидеть суммы.
И объеденить этот результат с еще одной таблицей регистра накопления с переодичностью месяц.
месяц сумма по документам
объеденить
месяц сумма по регистру
(11) Думаю, что ПроизводственныйКалендарь безболезненно можно заменить на выборку документов и группировать уже по дате документа, а не по дате календаря.
Обман во многом. Не указана область применимости (типовые конфигурации). Не указана необходимость сначала заполнить регистр за тот период, для которого нужны интервалы. И т.д. В общем очень небрежно.
Вообще задачу разбиения на месяцы (и не только) легко можно решить и без регистра одним запросом (менее эффективно) или пакетным запросом (более эффективно). Здесь уже есть такие публикации.
Присоединюсь к замечанию в (13). Производственный календарь для решения этой задачи не требуется. Так можно и таблицу умножения в базу данных внести, если умножать разучиться.
(13) tormozit, Замечательно, ну и где на инфостарте эти публикации ???
(14) ildarovich, ну так ведь если инструмент (календарь) есть, то можно его использовать, не так ли? Все претензии разработчикам типовых 🙂
(16) давайте я поясню свою мысль…
Предложенное вами решение без должного основания использует зависимости:
1) от наличия в составе конфигурации такого объекта как регистр сведений «РегламентированныйПроизводственныйКалендарь»;
2) от его правильной заполненности на нужный период.
Если первая зависимость легко проверяется (при попытке использовать этот метод в конфигурации без календаря, вы просто получите ошибку), то вторая зависимость неприятнее. При частичной заполненности календаря вы получите ошибку в отчете, которую еще потребуется поискать.
Кроме того, используемый принцип совершенно зря перебирает все даты периода, когда из месяца требуется только одна запись. То есть работает в 30 раз медленнее возможного.
Вопрос, наверное не такой уж важный, но тут много начинающих, которые используют готовый код, никак его не осмысливая. В результате чего недостаточно проработанные, сделанные на скорую руку решения множатся. Авторы публикаций могли бы этому препятствовать, а вы, кажется, способствуете.
Кстати, если уж настаиваете на использовании календаря, могу предложить вот такой вариант из одного запроса:
Показать
Он короче и более универсальный — легко вид периода (день, месяц, год, квартал) поменять.
А вообще в свете вопроса (15) можно было бы и конкурс объявить на решение этой задачи без календаря.
+(17) Требуется решить данную задачу
разбиения произвольного периода на интервалы в запросе
без использования регламентированного производственного календаря.
Но потребуется постобработка.
(19) kasper076, хорошее решение, но нужно, чтобы результат можно было внутри запроса использовать, поэтому итоги не годятся
Быстренько для не более 64 месяцев
Показать
(21) HanterVol, да, решение нужно примерно такое, если покороче нельзя
Думаю что можно…. но нужно уже думать :)))
Если только без группировки, но с отбором
Показать
(21) HanterVol, Разве так не проще?
Показать
(24) Ovrfox, последний запрос лучше так
Показать
Или в 2 Запроса
и с другим алгоритмом заполнения таблицы чисел (кому как нравится, я если честно предыдущий хреново понимаю)
Показать
(26) HanterVol, (25) Ovrfox, это уже заявки на победу, подождем еще, возможно, будут еще варианты…
(26) HanterVol,
Выражение
ТОГДА НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ДатаНачала, МЕСЯЦ, Числа1.Поле + 10 * Числа2.Поле), МЕСЯЦ)
не имеет смысла при ограничении по датам и даже без ограничения нужно включать «Выбрать различные»
(28) Ovrfox, Согласен, косяк
(28) Ovrfox, но хотелось избавиться от «Различные»
(30) herfis, не вполне подходит, так как тут много возни с первым и последним периодом, а в вашем варианте об этом ничего нет, так что без допиливания не подойдет
(32) ildarovich, Есть, на самом деле. «Возня» отображена в вычислении «КвоДнейСтандартногоПериода». Просто делается по аналогии
и аналогично для конца периода
(33) herfis, Запрос возвращает не кол-во периодов, а одну запись в день. Чтобы получить периоды — нужно группировать — не самый эффективный метод.
Но как вариант — очень хорош.
(34) Ovrfox, Именно так. Я об этом сразу предупредил. По сути, это просто небольшая модификация получения таблицы дней. Мне нужна была именно такая. Вероятно, именно для периодов возможен более оптимальный вариант. Но без группировок (РАЗЛИЧНЫЕ просто одна из вариаций) в голову ничего не приходит. Тут тоже достаточно добавить РАЗЛИЧНЫЕ и убрать «ДеньПериода» для получения таблицы именно периодов.
(33) herfis, Примерно такой запрос получен по вашим следам
При этом легко видеть, что при замене слова НЕДЕЛЯ на любой другой период запрос останется точно таким же, изменится только протяженность периода
Показать
(36) Ovrfox, Все так. Исходный запрос многословен из-за динамической разбивки по периодам (периодичность выбирает пользователь в параметре СКД).
(33) herfis, извиняюсь, невнимательно посмотрел, но … теперь увидел, что интервал разворачивается по дням. Это слишком легкий путь. И хотя время выполнения тут не особенно критично, все же зачем делать лишние вычисления? Их будет в 30 раз меньше, чем при перечислении не дней, как в (30) и (36), а периодов, как в (25) и (26). Кроме того, при перечислении дней самым простым способом будет использовании уже записанного в (17) запроса. Без лишних условий:
Показать
(38) ildarovich, Согласен.
ЗЫ. В использовании двоичного расчета плюсов не вижу, скорее наоборот, а вот группировка по разности дат — элегантный ход.
(39) herfis, двоичный, десятичный и тому подобное к сути решения не относятся. Можно использовать кому что нравится. Я использовал двоичное основание из-за того, что оно дает самую короткую запись, выраженную в числе строк запроса, раскрытого конструктором. Уж очень длинной выглядит формирование таблицы из десяти цифр. Еще плюсом двоичного основания является минимум лишнего в итоге соединения, из которой затем выбирается нужное число записей, потому что ряд 1-2-4-8-16-64-128 чаще, чем 1-10-100-1000. Есть и минусы и другие методы. Но здесь об этом смысла спорить не вижу.
Сейчас хочу увидеть более короткое чем (25) и (26) решение без развертки по дням.
Сделал с другой идеей, но… короче не получилось
Показать
(40) ildarovich, ИМХО, Orfox победитель.
Он первый предложил оптимальный алгоритм генерации таблицы периодов (без группировок). Оптимальнее вроде некуда. Один простой запрос.
Остальное, включая уточнение границ периодов — вторично.
Было бы соблазнительно сгенерировать таблицу полных периодов и объединить с «краями», но, к сожалению, обработка всех возможных ситуаций в итоге будет выглядеть хуже, а не лучше.
(41) HanterVol, хороший вариант, кое-где вроде бы РАЗЛИЧНЫЕ лишние. Он кажется более «воздушным». Нужно будет еще по числу знаков сравнить.
(42) herfis, хотел еще подождать свежих вариантов, прежде чем победителя определять, не хотелось бы пока точку ставить. Если что, я вознаграждение увеличу.
Пора подводить итоги. Добавлю вознаграждение, съеденное временем. HanterVol предложил свой вариант первым, а потом добавил еще один интересный вариант решения. Но в итоге с небольшим перевесом (0,5:1,5) побеждает вариант (24) Ovrfox. Этот вариант самый простой и короткий.
К сожалению, из-за редизайна форума, обещанное вознаграждение до победителя не дошло, останусь должен, сочтемся с Ovrfox при случае.
Для коллекции добавлю свой вариант. Он самый короткий, но не самый простой:
Показать
К сожалению, этот вариант не отрабатывает ситуацию отсутствия необходимости разбивки: если Дата1 и Дата2 находятся в одном месяце.
Я, может, не врубился до конца в тему, но не понимаю чем не устраивает банальные варианты с:
?
(48) задача совсем другая: дан интервал, его нужно РАЗБИТЬ на подпериоды. То есть ответом должно быть множество записей — по одной для каждого входящего в интервал подпериода.
Например, 15.08.16 — 30.10.16 разбивается на месяцы так: 15.08.16 — 31.08.16; 1.09.16 — 30.09.16; 1.10.16 — 30.10.16.
(47)
Чуточку изменил Ваш запрос:
ВЫБРАТЬ
0 КАК Х
ПОМЕСТИТЬ Бит
ОБЪЕДИНИТЬ
ВЫБРАТЬ
1
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
Б0.Х + 2 * (Б1.Х + 2 * (Б2.Х + 2 * (Б3.Х + 2 * (Б4.Х + 2 * Б5.Х)))) КАК Х
ПОМЕСТИТЬ Периоды
ИЗ
Бит КАК Б0,
Бит КАК Б1,
Бит КАК Б2,
Бит КАК Б3,
Бит КАК Б4,
Бит КАК Б5
ГДЕ
Б0.Х + 2 * (Б1.Х + 2 * (Б2.Х + 2 * (Б3.Х + 2 * (Б4.Х + 2 * Б5.Х)))) < РАЗНОСТЬДАТ(&Дата1, &Дата2, МЕСЯЦ)
;
//////////////////////////////////////////////////////////// ////////////////////
ВЫБРАТЬ
ЕСТЬNULL(НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&Дата1, МЕСЯЦ, Начала.Х + 1), МЕСЯЦ), &Дата1) КАК ДатаНачала,
ЕСТЬNULL(КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&Дата1, МЕСЯЦ, Окончания.Х), МЕСЯЦ), &Дата2) КАК ДатаОкончания
ИЗ
Периоды КАК Начала
ПОЛНОЕ СОЕДИНЕНИЕ Периоды КАК Окончания
ПО (Начала.Х + 1 = Окончания.Х)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
&Дата1,
&Дата2
ГДЕ
НАЧАЛОПЕРИОДА(&Дата1, МЕСЯЦ) = НАЧАЛОПЕРИОДА(&Дата2, МЕСЯЦ)
УПОРЯДОЧИТЬ ПО
ДатаНачала
Этот вариант
не отрабатываетотрабатывает ситуацию отсутствия необходимости разбивки: если Дата1 и Дата2 находятся в одном месяце.Также, если в тексте запроса МЕСЯЦ -> #Детализация и через СтрЗаменить(…) в тексте запроса заменять #Детализация на МЕСЯЦ, ДЕНЬ, КВАРТАЛ… То можно получить вполне универсальную функцию.