ВЫБРАТЬ
КонтактныеЛицаКонтрагентов.Наименование,
КонтактныеЛицаКонтрагентов.КонтактноеЛицо,
КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения,
ВЫБОР КОГДА МЕСЯЦ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения) > &ТекМесяц ТОГДА
ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(&ТекГод, МЕСЯЦ, МЕСЯЦ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)-1), ДЕНЬ, ДЕНЬ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)-1)
Когда МЕСЯЦ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения) < &ТекМесяц Тогда
ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(ДобавитьКДате(&ТекГод, Год, 1), МЕСЯЦ, МЕСЯЦ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)-1), ДЕНЬ, ДЕНЬ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)-1)
Иначе
Выбор Когда День(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения) < &ТекДень Тогда
ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(ДобавитьКДате(&ТекГод, Год, 1), МЕСЯЦ, МЕСЯЦ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)-1), ДЕНЬ, ДЕНЬ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)-1)
Иначе
ДОБАВИТЬКДАТЕ(ДОБАВИТЬКДАТЕ(&ТекГод, МЕСЯЦ, МЕСЯЦ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)-1), ДЕНЬ, ДЕНЬ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)-1)
Конец
КОНЕЦ КАК ДеньРождения
ИЗ
Справочник.КонтактныеЛицаКонтрагентов КАК КонтактныеЛицаКонтрагентов
Параметры Дата1 и Дата2 - это период поиска
ТекГод = НачалоГода(ТекущаяДата()), ТекМесяц = Месяц(ТекущаяДата()), ТекДень = День(ТекущаяДата())
ПоказатьПо теме из базы знаний
- Online телефонный справочник из 1С: Зарплата и управление персоналом
- Универсальные функции ЗУП 3.1 / ЗКГУ 3.1, которые помогут в разработке
- Телефонный справочник организации: управляемые формы, вэб клиент, api
- Личный кабинет сотрудника в 1С ЗУП 3.1 в Telegram
- Боли роста команды от 20 до 160 сотрудников: проверка гипотез и практические выводы
Ответы
Подписаться на ответы
Инфостарт бот
Сортировка:
Древо развёрнутое
Свернуть все
(1) Stivens, я бы свой алгоритм построил так:
1. Получить таблицу с днями рождения для текущего года
2. Для тех, у кого в текущем году д.р. уже прошел, добавить еще год
3. Отсортировать таблицу в порядке возрастания дат или наложить условие на даты по желанию
Параметры: ТекГод - текущий год выраженный числом, например 2015; ТекущаяДата - Дата относительно которой ищем ближайшие дни рождения.
Запрос выводит ВСЕ контактные лица с их датами рождения в порядке от самого ближнего до самого дальнего. При желании можно модифицировать запрос и поставить условие через выражение ГДЕ ограничив выборку скажем 1 месяцем.
1. Получить таблицу с днями рождения для текущего года
2. Для тех, у кого в текущем году д.р. уже прошел, добавить еще год
3. Отсортировать таблицу в порядке возрастания дат или наложить условие на даты по желанию
ВЫБРАТЬ
КонтактныеЛицаКонтрагентов.Наименование,
КонтактныеЛицаКонтрагентов.КонтактноеЛицо,
КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения КАК ДатаРождения,
ДОБАВИТЬКДАТЕ(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения, ГОД, &ТекГод - ГОД(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)) КАК ДатаРожденияТекущийГод
ПОМЕСТИТЬ ДниРожденияТекущийГод
ИЗ
Справочник.КонтактныеЛицаКонтрагентов КАК КонтактныеЛицаКонтрагентов
ИНДЕКСИРОВАТЬ ПО
ДатаРожденияТекущийГод
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ДниРожденияТекущийГод.Наименование,
ДниРожденияТекущийГод.КонтактноеЛицо,
ДниРожденияТекущийГод.ДатаРождения,
ДниРожденияТекущийГод.ДатаРожденияТекущийГод КАК ДатаРожденияБлижайшая
ИЗ
ДниРожденияТекущийГод КАК ДниРожденияТекущийГод
ГДЕ
ДниРожденияТекущийГод.ДатаРожденияТекущийГод >= &ТекущаяДата
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДниРожденияТекущийГод.Наименование,
ДниРожденияТекущийГод.КонтактноеЛицо,
ДниРожденияТекущийГод.ДатаРождения,
ДОБАВИТЬКДАТЕ(ДниРожденияТекущийГод.ДатаРожденияТекущийГод, ГОД, 1)
ИЗ
ДниРожденияТекущийГод КАК ДниРожденияТекущийГод
ГДЕ
ДниРожденияТекущийГод.ДатаРожденияТекущийГод < &ТекущаяДата
УПОРЯДОЧИТЬ ПО
ДатаРожденияБлижайшая
ПоказатьПараметры: ТекГод - текущий год выраженный числом, например 2015; ТекущаяДата - Дата относительно которой ищем ближайшие дни рождения.
Запрос выводит ВСЕ контактные лица с их датами рождения в порядке от самого ближнего до самого дальнего. При желании можно модифицировать запрос и поставить условие через выражение ГДЕ ограничив выборку скажем 1 месяцем.
ВЫБРАТЬ
Контрагенты.Ссылка КАК Контрагент,
КонтактныеЛицаКонтрагентов.Ссылка КАК КонтактноеЛицо,
КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения
ИЗ
Справочник.Контрагенты КАК Контрагенты
ПОЛНОЕ СОЕДИНЕНИЕ Справочник.КонтактныеЛицаКонтрагентов КАК КонтактныеЛицаКонтрагентов
ПО Контрагенты.Ссылка = КонтактныеЛицаКонтрагентов.Владелец
ГДЕ
НЕ КонтактныеЛицаКонтрагентов.Ссылка ЕСТЬ NULL
И НЕ КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения = ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0)
И ДЕНЬГОДА(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения) МЕЖДУ ДЕНЬГОДА(&Дата1) И ДЕНЬГОДА(&Дата2)
УПОРЯДОЧИТЬ ПО
ДЕНЬГОДА(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения)
Показать
(4) iskdv, решение так себе, не учтен вариант с, например, &дата1 = 01.11.15 и &дата2 = 11.01.16.
Универсальный вариант несколько сложнее:
Универсальный вариант несколько сложнее:
добавитькдате(датавремя(1,1,1), день, разностьдат(началопериода(КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения, год), КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения, день)) между
добавитькдате(датавремя(1,1,1), день, разностьдат(началопериода(&дата1, год), &дата1, день)) и
добавитькдате(датавремя(1,1,1), день, разностьдат(началопериода(&дата1, год), &дата1, день) + разностьдат(&дата1, &дата2, день))
(5) ditp, Ваш варинат работать не будет.
1. Вы к дате 01.01.0001 добавляете только разность дней между 01 января и днем рождения, однако если к дате 01.01.0001 прибавлять день, месяц, минуту или что угодно кроме года то получится дата 01.01.0001. Такая вот веселая эта пустая дата.
2. РазностьДат в вашем примере возвратит тоже, что возвратила бы функция ДеньГода(), только на 1 меньше. Смысл так извращаться?
3. Все та же проблема с високосными годами что и с функцией ДеньГода(). Человек мог родиться в високосный год, мы вычисляем разность дат, сравниваем с разностью дат для 2015 года и различие на 1 день только из-за 29 февраля в год рождения. А в 2016 году будет полная жопа.
4. Код не элегантен и трудно читаем.
1. Вы к дате 01.01.0001 добавляете только разность дней между 01 января и днем рождения, однако если к дате 01.01.0001 прибавлять день, месяц, минуту или что угодно кроме года то получится дата 01.01.0001. Такая вот веселая эта пустая дата.
2. РазностьДат в вашем примере возвратит тоже, что возвратила бы функция ДеньГода(), только на 1 меньше. Смысл так извращаться?
3. Все та же проблема с високосными годами что и с функцией ДеньГода(). Человек мог родиться в високосный год, мы вычисляем разность дат, сравниваем с разностью дат для 2015 года и различие на 1 день только из-за 29 февраля в год рождения. А в 2016 году будет полная жопа.
4. Код не элегантен и трудно читаем.
(7) vugluskr74, из всех возражений принимаю только насчет високосного года.
Исправленный вариант
Параметр &дата нужно заменить на "КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения".
Исправленный вариант
ВЫБОР
КОГДА &Дата1 <= &дата2
ТОГДА (МЕСЯЦ(&дата) > МЕСЯЦ(&Дата1)
ИЛИ МЕСЯЦ(&дата) = МЕСЯЦ(&Дата1)
И ДЕНЬ(&дата) >= ДЕНЬ(&Дата1))
И (МЕСЯЦ(&дата) < МЕСЯЦ(&Дата2)
ИЛИ МЕСЯЦ(&дата) = МЕСЯЦ(&Дата2)
И ДЕНЬ(&дата) <= ДЕНЬ(&Дата2))
ИНАЧЕ (МЕСЯЦ(&дата) > МЕСЯЦ(&Дата1)
ИЛИ МЕСЯЦ(&дата) = МЕСЯЦ(&Дата1)
И ДЕНЬ(&дата) >= ДЕНЬ(&Дата1))
И МЕСЯЦ(&дата) <= 12
ИЛИ (МЕСЯЦ(&дата) < МЕСЯЦ(&Дата2)
ИЛИ МЕСЯЦ(&дата) = МЕСЯЦ(&Дата2)
И ДЕНЬ(&дата) <= ДЕНЬ(&Дата2))
И МЕСЯЦ(&дата) >= 1
ПоказатьПараметр &дата нужно заменить на "КонтактныеЛицаКонтрагентов.КонтактноеЛицо.ДатаРождения".
(4) iskdv, Сразу 2 косяка в вашем решении:
1. Не учтен вариант перехода в новый год. То есть когда Дата1 скажем равна 20.12.2015 а Дата2 = 20.01.2016, в таком случае условие Между 354 и 20 всегда будет ложно.
2. ДеньГода дает смещение на 1 в большую сторону из-за 29 февраля в високосных годах. Год рождения может быть високосным, а текущий год нет или наоборот, тогда в интервал может не попасть дата находящаяся на границе интервала.
1. Не учтен вариант перехода в новый год. То есть когда Дата1 скажем равна 20.12.2015 а Дата2 = 20.01.2016, в таком случае условие Между 354 и 20 всегда будет ложно.
2. ДеньГода дает смещение на 1 в большую сторону из-за 29 февраля в високосных годах. Год рождения может быть високосным, а текущий год нет или наоборот, тогда в интервал может не попасть дата находящаяся на границе интервала.
ВЫБРАТЬ
КонтактныеЛица.Ссылка,
КонтактныеЛица.ДатаРождения,
КонтактныеЛица.КоличествоДнейДоНапоминания,
КонтактныеЛица.НапоминатьОДнеРождения,
ВЫБОР
КОГДА ДОБАВИТЬКДАТЕ(КонтактныеЛица.ДатаРождения, ГОД, РАЗНОСТЬДАТ(КонтактныеЛица.ДатаРождения, &ДатаОтчета, ГОД)) < &ДатаОтчета
ТОГДА ДОБАВИТЬКДАТЕ(КонтактныеЛица.ДатаРождения, ГОД, 1 + РАЗНОСТЬДАТ(КонтактныеЛица.ДатаРождения, &ДатаОтчета, ГОД))
ИНАЧЕ ДОБАВИТЬКДАТЕ(КонтактныеЛица.ДатаРождения, ГОД, РАЗНОСТЬДАТ(КонтактныеЛица.ДатаРождения, &ДатаОтчета, ГОД))
КОНЕЦ КАК ДатаРожденияВТекуще
ИЗ
Справочник.КонтактныеЛица КАК КонтактныеЛица
ГДЕ
РАЗНОСТЬДАТ(ВЫБОР
КОГДА ДОБАВИТЬКДАТЕ(КонтактныеЛица.ДатаРождения, ГОД, РАЗНОСТЬДАТ(КонтактныеЛица.ДатаРождения, &ДатаОтчета, ГОД)) < &ДатаОтчета
ТОГДА ДОБАВИТЬКДАТЕ(КонтактныеЛица.ДатаРождения, ГОД, 1 + РАЗНОСТЬДАТ(КонтактныеЛица.ДатаРождения, &ДатаОтчета, ГОД))
ИНАЧЕ ДОБАВИТЬКДАТЕ(КонтактныеЛица.ДатаРождения, ГОД, РАЗНОСТЬДАТ(КонтактныеЛица.ДатаРождения, &ДатаОтчета, ГОД))
КОНЕЦ, &ДатаОтчета, ДЕНЬ) <= КонтактныеЛица.КоличествоДнейДоНапоминания
И КонтактныеЛица.НапоминатьОДнеРождения
Показать
Для УНФ на основе (10). Список покупателей, у которых был день рождения в указанный период:
ВЫБРАТЬ
Контрагенты.Ссылка КАК Ссылка,
Контрагенты.ДатаРождения КАК ДатаРождения,
Контрагенты.Покупатель КАК Покупатель,
ВЫБОР
КОГДА ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД)) < &ДатаОтчета
ТОГДА ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, 1 + РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД))
ИНАЧЕ ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД))
КОНЕЦ КАК ДатаРожденияВТекущемГоду,
Контрагенты.НомерТелефона КАК НомерТелефона
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
Контрагенты.НомерТелефона <> ""
И Контрагенты.ДатаРождения <> ДАТАВРЕМЯ(1, 1, 1)
И ВЫБОР
КОГДА ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД)) < &ДатаОтчета
ТОГДА ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, 1 + РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД))
ИНАЧЕ ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД))
КОНЕЦ >= &ДатаОтчета
И ВЫБОР
КОГДА ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД)) < &ДатаОтчета
ТОГДА ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, 1 + РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД))
ИНАЧЕ ДОБАВИТЬКДАТЕ(Контрагенты.ДатаРождения, ГОД, РАЗНОСТЬДАТ(Контрагенты.ДатаРождения, &ДатаОтчета, ГОД))
КОНЕЦ <= &ДатаОкончанияОтчета
УПОРЯДОЧИТЬ ПО
ДатаРожденияВТекущемГоду
Показать
подойдет для любой типовой.
передаете ТекущаяДата() в запрос и получаете список контактных лиц, день рождения которых наступают в ближайшие дни. ближайший день в данном случае задается для каждого контактного лица по отдельности, но при желании можно заменить одним числом. например в ближашие 7 дней
передаете ТекущаяДата() в запрос и получаете список контактных лиц, день рождения которых наступают в ближайшие дни. ближайший день в данном случае задается для каждого контактного лица по отдельности, но при желании можно заменить одним числом. например в ближашие 7 дней
Выбор
Когда М=Мн и М=Мк
тогда Д>=Дн и Д<=Дк
Когда М>=Мн и М=Мк
тогда Д<=Дк
Когда М=Мн и М<=Мк
тогда Д>=Дн
Иначе
Истина
Конец
М - месяц дня рождения
Д - день дня рождения
Мн - месяц начала периода
Мк - месяц конца периода
Дн - день начала периода
Дк - день конца периода
Когда М=Мн и М=Мк
тогда Д>=Дн и Д<=Дк
Когда М>=Мн и М=Мк
тогда Д<=Дк
Когда М=Мн и М<=Мк
тогда Д>=Дн
Иначе
Истина
Конец
М - месяц дня рождения
Д - день дня рождения
Мн - месяц начала периода
Мк - месяц конца периода
Дн - день начала периода
Дк - день конца периода
Остановился на
Оговорка только, что дату надо выбирать в пределах года.
И в отбор ставить, чтобы дата была не пустой.
Тогда решил что надо 2 интервала:
В таком ключе уже можно выбрать даты с разных лет, но про пустую дату либо в отбор, либо в условие в запросе, но думаю отбор будет лучше!
ДЕНЬГОДА(ДатаРождения) МЕЖДУ ДЕНЬГОДА(&ДатаРожденияНачало) И ДЕНЬГОДА(&ДатаРожденияОкончание)
Оговорка только, что дату надо выбирать в пределах года.
И в отбор ставить, чтобы дата была не пустой.
Тогда решил что надо 2 интервала:
ВЫБОР
КОГДА ГОД(&ДатаРожденияНачало) = ГОД(&ДатаРожденияОкончание)
ТОГДА ДЕНЬГОДА(ДатаРождения) МЕЖДУ ДЕНЬГОДА(&ДатаРожденияНачало) И ДЕНЬГОДА(&ДатаРожденияОкончание)
ИНАЧЕ ДЕНЬГОДА(ДатаРождения) МЕЖДУ ДЕНЬГОДА(&ДатаРожденияНачало) И ДЕНЬГОДА(КОНЕЦПЕРИОДА(&ДатаРожденияНачало, ГОД))
ИЛИ ДЕНЬГОДА(ДатаРождения) МЕЖДУ ДЕНЬГОДА(НАЧАЛОПЕРИОДА(&ДатаРожденияОкончание, ГОД)) И ДЕНЬГОДА(&ДатаРожденияОкончание)
КОНЕЦ
В таком ключе уже можно выбрать даты с разных лет, но про пустую дату либо в отбор, либо в условие в запросе, но думаю отбор будет лучше!
Задача: вывести список партнеров, не только у которых сегодня день рождения, но и у которых три дня до и три дня после (от сегодня). Пробовал запрос из (10) и (15), но они не учитывают границу года (сегодня 02.01.2021, а день рождения 30.12.1990). После долгих раздумий решил задачу в лоб.
Получается, сперва во временную таблицу закидываются все даты, а уже по этим 7 датам отбираются партнеры. Поскольку используется стандартный метод ДОБАВИТЬКДАТЕ, то и на границу года, и на высокосный год и т.п. "с высокой колокольни", как говорится.
У нас в базе есть еще некоторые реквизиты с типом Дата, которые участвуют в отборе, поэтому я просто их сюда добавил через ИЛИ в условие ГДЕ и все. Работает.
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -3) КАК ДеньРождения
ПОМЕСТИТЬ ВТДаты
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -2)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -1)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
&ТекущаяДата
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, 1)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, 2)
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, 3)
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗРЕШЕННЫЕ
Партнеры.Ссылка КАК Партнер
ИЗ
Справочник.Партнеры КАК Партнеры
ГДЕ
(МЕСЯЦ(Партнеры.ДатаРождения), ДЕНЬ(Партнеры.ДатаРождения)) В
(ВЫБРАТЬ
МЕСЯЦ(ВТДаты.ДеньРождения),
ДЕНЬ(ВТДаты.ДеньРождения)
ИЗ
ВТДаты)
ПоказатьПолучается, сперва во временную таблицу закидываются все даты, а уже по этим 7 датам отбираются партнеры. Поскольку используется стандартный метод ДОБАВИТЬКДАТЕ, то и на границу года, и на высокосный год и т.п. "с высокой колокольни", как говорится.
У нас в базе есть еще некоторые реквизиты с типом Дата, которые участвуют в отборе, поэтому я просто их сюда добавил через ИЛИ в условие ГДЕ и все. Работает.
Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот