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

Сейчас учет звонков клиентам ведется так: в регистр записывается контрагент, договор и дата. Период учета календарный день, неделя, месяц.
Можно вывести список контрагентов и количество звонков по периоду, он будет одинаковым.
Тут просто Количество(*) + в условии Дата между &Начало и &Конец
Например,
Звонки: Вася 29.05, Вася 30.05, Вася 31.05, Алина 31.05, 3.06
Период неделя 29.05 - 04.06
Итого за период у Васи 3 звонка, у Алины 2 звонка.

Теперь период меняется, также день, неделя, месяц, но не календарные, имеющие разную дату начала. Т.е. у Васи период неделя начинается с 30.05, а у Алины с 27.05
Итого за период 'неделя' у Васи 2 звонка (период 30.05 - 5.06), у Алины 1 звонок (период 27.05 - 2.06).

Можно ли сделать выборку по периодам, если у каждого контрагента разная дата начала периода ? Достаточно ли только записывать дату начала, и можно ли запросом посчитать количество звонков?

Есть скорее всего нерациональное решение: регистр сведений с ресурсами дата начала, день, неделя, месяц. При звонке менять запись в день, неделя, месяц. Загвоздка: необходимо обнулять значения по истечению дня, недели, месяца (от даты начала) - может для этого подойдет рег. задания, не слишком ли ресурсозатратно постоянно пробегаться по всем контрагентам и обновлять записи регистра каждые неск минут ?

Заранее спасибо за подсказку!
---
Нужен календарь (регистр)
Нужен график работы сотрудников (регистр)
Нужен учет звонков (регистр)

Всё это похоже на 1С ЗУП, где есть смены работы сотрудников и нужно вести учет времени.
---
Создаем РС.СмещенияДатаСтандартныхПериодовСотрудников
   - в примере ниже моделируется первой временной таблицей.

Регистр периодический с периодом день.
Измерения:
Сотрудник (Справочник.ФизЛица, или пользвоатели - обычно последней удобней, хотя и не очень верно),
ТипПериода (перечисления.ТипыПериодов)
Ресурс:
СмещениеПериодаДней Число(3,0)

Пусть надо выбрать данные за ну скажем за Перечисления.ТипыПериодов.ПроизвольныйПериод- тогда в ограничения последнего запроса в &ДатаС ставим
начало периода, а &ДатаПо - конец периода + максимальное смещение по данному периоду

В примере делать не стал, сами справитесь - создаете еще один запрос на максимум по смещению.

Далее просто - проверяем попадание в диапазон в условии "выбор когда".

В запросе &ДатаС - это ДАТАВРЕМЯ(2023, 2, 1)
                  &ДатаПо - ДАТАВРЕМЯ(2023, 2, 11)

```1c
    ВЫБРАТЬ
    "Ася" КАК Сотрудник,
    "ПроизвольныйПериод" КАК ТипПериода,
    2 КАК СмещениеПериодаДней
    ПОМЕСТИТЬ ВТ

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Вася",
    "ПроизвольныйПериод",
    0
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    "Звонок1" КАК Звонок,
    "Вася" КАК АвторЗвонка,
    ДАТАВРЕМЯ(2023, 2, 1) КАК ДатаЗвонка
    ПОМЕСТИТЬ ВТЗвонки

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок2",
    "Вася",
    ДАТАВРЕМЯ(2023, 2, 1)

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок3",
    "Вася",
    ДАТАВРЕМЯ(2023, 2, 10)

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок1_1",
    "Ася",
    ДАТАВРЕМЯ(2023, 2, 11)

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок2_1",
    "Ася",
    ДАТАВРЕМЯ(2023, 2, 1)

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок3_1",
    "Ася",
    ДАТАВРЕМЯ(2023, 2, 11)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    КОЛИЧЕСТВО(ВЫБОР
    КОГДА ДОБАВИТЬКДАТЕ(ВТЗвонки.ДатаЗвонка, ДЕНЬ, -ВТ.СмещениеПериодаДней) < ДАТАВРЕМЯ(2023, 2, 1)
    ТОГДА NULL
    ИНАЧЕ ВТЗвонки.Звонок
    КОНЕЦ) КАК ЗвонокКолВо,
    ВТЗвонки.АвторЗвонка
    ИЗ
    ВТЗвонки КАК ВТЗвонки
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК ВТ
    ПО (ВТ.Сотрудник = ВТЗвонки.АвторЗвонка)
    И (ВТ.ТипПериода = "ПроизвольныйПериод")
    ГДЕ
    ВТЗвонки.ДатаЗвонка МЕЖДУ ДАТАВРЕМЯ(2023, 2, 1) И ДАТАВРЕМЯ(2023, 2, 11)
    СГРУППИРОВАТЬ ПО ВТЗвонки.АвторЗвонка
```
---
Хорошо. Как-то так:

```1c
    ВЫБРАТЬ
    ТаблицаЗвонков.ФизЛицо КАК ФизЛицо,
    МИНИМУМ(ТаблицаЗвонков.ДатаЗвонка) КАК ДатаПервогоЗвонка
    ПОМЕСТИТЬ ВТЗвонкиСрезПервых
    ИЗ
    ТаблицаЗвонков КАК ТаблицаЗвонков

    СГРУППИРОВАТЬ ПО
    ТаблицаЗвонков.ФизЛицо
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВТЗвонкиСрезПервых.ФизЛицо КАК ФизЛицо,
    ДЕНЬНЕДЕЛИ(ВТЗвонкиСрезПервых.ДатаПервогоЗвонка) КАК ДеньНеделиПервогоЗвонка
    ПОМЕСТИТЬ ВТДниНеделиПервыхЗвонков
    ИЗ
    ВТЗвонкиСрезПервых КАК ВТЗвонкиСрезПервых
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ РАЗЛИЧНЫЕ
    Т1.ФизЛицо КАК ФизЛицо,
    НАЧАЛОПЕРИОДА(Т1.ДатаЗвонка, ДЕНЬ) КАК НачалоНедели,
    КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(Т1.ДатаЗвонка, ДЕНЬ, 6), ДЕНЬ) КАК КонецНедели
    ПОМЕСТИТЬ ВТНеделиФизЛиц
    ИЗ
    ТаблицаЗвонков КАК Т1
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТДниНеделиПервыхЗвонков КАК Т2
    ПО (ДЕНЬНЕДЕЛИ(Т1.ДатаЗвонка) = Т2.ДеньНеделиПервогоЗвонка)
    И Т1.ФизЛицо = Т2.ФизЛицо
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    Т1.ФизЛицо КАК ФизЛицо,
    Т1.НачалоНедели КАК НачалоНедели,
    КОЛИЧЕСТВО(Т2.ДатаЗвонка) КАК КоличествоЗвонков
    ИЗ
    ВТНеделиФизЛиц КАК Т1
    ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаЗвонков КАК Т2
    ПО Т1.ФизЛицо = Т2.ФизЛицо
    И (НАЧАЛОПЕРИОДА(Т2.ДатаЗвонка, ДЕНЬ) МЕЖДУ Т1.НачалоНедели И Т1.КонецНедели)

    СГРУППИРОВАТЬ ПО
    Т1.ФизЛицо,
    Т1.НачалоНедели
```
---
Каким образом определяется дата начала "недели" для конкретного человека?
---
Датой первого звонка
---
```1c
    Петя Маша Петя Маша
    Пн 01.янв 08.янв 3 3
    Вт 02.янв 4 09.янв 5 3
    Ср 03.янв 3 10.янв 5 5
    Чт 04.янв 3 2 11.янв 3 3
    Пт 05.янв 5 6 12.янв 6 6
    Сб 06.янв 4 6 13.янв 5 4
    Вс 07.янв 3 5 14.янв 3

    Петя "неделя1" 27
    Петя "неделя2" 17+
    Маша "неделя1" 29
    Маша "неделя2" 21+
```

Так? или как?
---
(6) Да, верно!
---
Хорошо. Как-то так:

```1c
    ВЫБРАТЬ
    ТаблицаЗвонков.ФизЛицо КАК ФизЛицо,
    МИНИМУМ(ТаблицаЗвонков.ДатаЗвонка) КАК ДатаПервогоЗвонка
    ПОМЕСТИТЬ ВТЗвонкиСрезПервых
    ИЗ
    ТаблицаЗвонков КАК ТаблицаЗвонков

    СГРУППИРОВАТЬ ПО
    ТаблицаЗвонков.ФизЛицо
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    ВТЗвонкиСрезПервых.ФизЛицо КАК ФизЛицо,
    ДЕНЬНЕДЕЛИ(ВТЗвонкиСрезПервых.ДатаПервогоЗвонка) КАК ДеньНеделиПервогоЗвонка
    ПОМЕСТИТЬ ВТДниНеделиПервыхЗвонков
    ИЗ
    ВТЗвонкиСрезПервых КАК ВТЗвонкиСрезПервых
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ РАЗЛИЧНЫЕ
    Т1.ФизЛицо КАК ФизЛицо,
    НАЧАЛОПЕРИОДА(Т1.ДатаЗвонка, ДЕНЬ) КАК НачалоНедели,
    КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(Т1.ДатаЗвонка, ДЕНЬ, 6), ДЕНЬ) КАК КонецНедели
    ПОМЕСТИТЬ ВТНеделиФизЛиц
    ИЗ
    ТаблицаЗвонков КАК Т1
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТДниНеделиПервыхЗвонков КАК Т2
    ПО (ДЕНЬНЕДЕЛИ(Т1.ДатаЗвонка) = Т2.ДеньНеделиПервогоЗвонка)
    И Т1.ФизЛицо = Т2.ФизЛицо
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    Т1.ФизЛицо КАК ФизЛицо,
    Т1.НачалоНедели КАК НачалоНедели,
    КОЛИЧЕСТВО(Т2.ДатаЗвонка) КАК КоличествоЗвонков
    ИЗ
    ВТНеделиФизЛиц КАК Т1
    ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаЗвонков КАК Т2
    ПО Т1.ФизЛицо = Т2.ФизЛицо
    И (НАЧАЛОПЕРИОДА(Т2.ДатаЗвонка, ДЕНЬ) МЕЖДУ Т1.НачалоНедели И Т1.КонецНедели)

    СГРУППИРОВАТЬ ПО
    Т1.ФизЛицо,
    Т1.НачалоНедели
```
---
(4)Датой первого звонка Тогда и график не нужен. От первой даты периоды +6 дней. Для каждого это неделя. На любую дату можно рассчитать какой период будет приходится.
Но я думаю, что вы ошиблись в ответе про дату первого звонка. Сотрудники болеют, ходят в отпуск, меняют график работы. :-)
---
В задачу не входит привязка к графику работы сотрудника.
---
В задачу не входит привязка к графику работы сотрудника. Зачем контрагентов называть Петя, Вася, Алина?
(12) Хорошо. Как-то так: Где Контрагенты?
---
Физлицо = Контрагент
---
Нужен календарь (регистр)
Нужен график работы сотрудников (регистр)
Нужен учет звонков (регистр)

Всё это похоже на 1С ЗУП, где есть смены работы сотрудников и нужно вести учет времени.
---
Создаем РС.СмещенияДатаСтандартныхПериодовСотрудников
   - в примере ниже моделируется первой временной таблицей.

Регистр периодический с периодом день.
Измерения:
Сотрудник (Справочник.ФизЛица, или пользвоатели - обычно последней удобней, хотя и не очень верно),
ТипПериода (перечисления.ТипыПериодов)
Ресурс:
СмещениеПериодаДней Число(3,0)

Пусть надо выбрать данные за ну скажем за Перечисления.ТипыПериодов.ПроизвольныйПериод- тогда в ограничения последнего запроса в &ДатаС ставим
начало периода, а &ДатаПо - конец периода + максимальное смещение по данному периоду

В примере делать не стал, сами справитесь - создаете еще один запрос на максимум по смещению.

Далее просто - проверяем попадание в диапазон в условии "выбор когда".

В запросе &ДатаС - это ДАТАВРЕМЯ(2023, 2, 1)
                  &ДатаПо - ДАТАВРЕМЯ(2023, 2, 11)

```1c
    ВЫБРАТЬ
    "Ася" КАК Сотрудник,
    "ПроизвольныйПериод" КАК ТипПериода,
    2 КАК СмещениеПериодаДней
    ПОМЕСТИТЬ ВТ

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Вася",
    "ПроизвольныйПериод",
    0
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    "Звонок1" КАК Звонок,
    "Вася" КАК АвторЗвонка,
    ДАТАВРЕМЯ(2023, 2, 1) КАК ДатаЗвонка
    ПОМЕСТИТЬ ВТЗвонки

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок2",
    "Вася",
    ДАТАВРЕМЯ(2023, 2, 1)

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок3",
    "Вася",
    ДАТАВРЕМЯ(2023, 2, 10)

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок1_1",
    "Ася",
    ДАТАВРЕМЯ(2023, 2, 11)

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок2_1",
    "Ася",
    ДАТАВРЕМЯ(2023, 2, 1)

    ОБЪЕДИНИТЬ ВСЕ

    ВЫБРАТЬ
    "Звонок3_1",
    "Ася",
    ДАТАВРЕМЯ(2023, 2, 11)
    ;

    ////////////////////////////////////////////////////////////­////////////////////
    ВЫБРАТЬ
    КОЛИЧЕСТВО(ВЫБОР
    КОГДА ДОБАВИТЬКДАТЕ(ВТЗвонки.ДатаЗвонка, ДЕНЬ, -ВТ.СмещениеПериодаДней) < ДАТАВРЕМЯ(2023, 2, 1)
    ТОГДА NULL
    ИНАЧЕ ВТЗвонки.Звонок
    КОНЕЦ) КАК ЗвонокКолВо,
    ВТЗвонки.АвторЗвонка
    ИЗ
    ВТЗвонки КАК ВТЗвонки
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК ВТ
    ПО (ВТ.Сотрудник = ВТЗвонки.АвторЗвонка)
    И (ВТ.ТипПериода = "ПроизвольныйПериод")
    ГДЕ
    ВТЗвонки.ДатаЗвонка МЕЖДУ ДАТАВРЕМЯ(2023, 2, 1) И ДАТАВРЕМЯ(2023, 2, 11)
    СГРУППИРОВАТЬ ПО ВТЗвонки.АвторЗвонка
```
---
Тут надо понять несколько вещей
1) общий объем информации. Сколько всего записей, сколько контрагентов в списке, по которому надо получать сведения
2) насколько критична скорость выполнения алгоритма.
3) сколько времени (= денег) клиент (заказчик) согласен потратить на реализацию алгоритма.
Если информации не очень много (сотни например), если время не очень критично (допустима видимая задержка получения секунд 10-20), если ресурсы ограничены - можно сделать что-нибудь перебором или подобием перебора на паре запросов, реализация займет пару часов без доработок конфигурации.
Если же например в п. 3 у нас ограничение не очень строгое, то можно изобрести несколько промежуточных регистров, заполнить их не спеша, смастерить очень правильные запросы и через неделю выдать результат аналогичный предыдущему варианту... подзаработать на отпуск...
Поле для деятельности широкое в таких задачах о)
---
Поясню, Контрагент, Дата первого звонка, Количество звонков за период от первого звонка + 6 дней (неделя).
---
Огромное спасибо всем за помощь. Проблему решил!