Имя: Пароль:
1C
1C 7.7
v7: Найди ближайшую дату.
,
0 mishaPH
 
модератор
05.10.17
11:39
Блин что-то мозг не соображает

есть некий платежный календарь в рамках недели. например платим по понедельникам и средам.

Как найти ближайший платежный день??
если
есть текущая дата и день недели к ней. например вторник и день недели 2.
есть текущая дата и день недели к ней. например четверг и день недели 4.
1 Волшебник
 
модератор
05.10.17
11:42
нужен запрос в цикле
2 Филиал-msk
 
05.10.17
11:44
"В рамках недели" это всего 7 вариантов. Проверь каждый и не выноси мозг.
3 dezss
 
05.10.17
11:45
э..ну разницу посчитай и минимум сделай
4 DrShad
 
05.10.17
11:45
и не забудь проверку на конец календаря в 1С
5 dezss
 
05.10.17
11:45
(3) разницу дат, а не дней недели, ессно)
6 Рэйв
 
05.10.17
11:47
(0)Если вторник, то ближайший- следующая среда. Все остальное - ближайший понедельник. Если я правильно понял сабж
7 mishaPH
 
модератор
05.10.17
11:49
(2) 5
8 mishaPH
 
модератор
05.10.17
11:50
(6) нее. у контрагента календарь, где отменено, что День2 = 1 и день 4 = 1

Это не просто найти ближайший рабочий день
9 mishaPH
 
модератор
05.10.17
11:50
(6) да
10 VladZ
 
05.10.17
11:53
Из контрагента получаем дни оплаты в виде (2,4). Получаем все даты календаря, добавляем колонку "деньНедели" (как ДеньНедели). Накладываем условие деньНедели в (2,4). По полученным дням определяем ближайшую. Дальше расписывать?
11 torgm
 
05.10.17
11:56
(0) минимальная неотрицательная разница по дням недели, у меня логистика примерно так же работает.

дни недели доставки привязаны к сектору в регистре сведений
12 mishaPH
 
модератор
05.10.17
11:56
(10) если не трудно. что то не пойму пипец. завтра в отпуск и мозг не соображает ;)
13 mishaPH
 
модератор
05.10.17
11:58
(11) есть 1с 7ка. какой регистр сведений вы о чем... у контрагента есть День1...День5 реквизит там 0 или 1

есть тек дата или дата минимальная от которой надо идя вперед по дням недели найти тот который у ка = 1 и опознить его датой
14 Zmich
 
05.10.17
11:58
Функция ПолучитьБлижайшийДеньПлатежа(ВыбДата)
  День1 = 1; // понедельник - платежный день
  День2 = 3; // среда - тоже платежный день
  ВыбДеньНедели = ДеньНедели(ВыбДата);
  БлижайшийДеньПлатежа = НачалоДня(ВыбДата);
  Пока ((ВыбДеньНедели <> День1) И (ВыбДеньНедели <> День2)) Цикл
    БлижайшийДеньПлатежа = БлижайшийДеньПлатежа + 86400;
    ВыбДеньНедели = ДеньНедели(БлижайшийДеньПлатежа);
  КонецЦикла;
  Возврат БлижайшийДеньПлатежа;
КонецФункции

Не претендую на оптимальность, тупой перебор день за днем, пока не получим нужный.
15 mishaPH
 
модератор
05.10.17
11:58
могу конечно сделать дикий цикл 5*5 но хочется как-то покороче и элегантней.
16 mishaPH
 
модератор
05.10.17
12:00
(14) начало дня это что?
17 Альбатрос
 
05.10.17
12:01
(16) Это 00:00:00
18 VladZ
 
05.10.17
12:01
(13) Так это 7.7? Тогда вариант (14).
19 Альбатрос
 
05.10.17
12:01
(16) Можно и без него кстати
20 VladZ
 
05.10.17
12:02
Только он корявенький, ИМХО.
21 Zmich
 
05.10.17
12:02
(16). Начало дня не обязательно, просто чтобы возвращалась дата со временем 0:00:00, а не непонятно что. В 7-ке код из (14) не будет работать. ДеньНедели() не уверен, что там есть. И вместо +86400 просто +1.
22 mishaPH
 
модератор
05.10.17
12:03
(21) день недели есть НомерДняНедели
23 dezss
 
05.10.17
12:04
перенесите ветку в семерошную, а то путають тут нас...
24 mishaPH
 
модератор
05.10.17
12:04
счасПопробую..
25 Zmich
 
05.10.17
12:04
(20). Не спорю, что корявенький, но работать будет.
26 mishaPH
 
модератор
05.10.17
12:08
тут еще момент. у ка может быть в рамках от 1 до 5 платежных дней. т.е.

  День1 = 1;// понедельник - платежный день

  День2 = 3;// среда - тоже платежный день

дней моет быть несколько а может и не быть
27 VladZ
 
05.10.17
12:09
(26) Я и говорю, корявенький. :)
28 mistеr
 
05.10.17
12:09
(13) 1. Собрать дни платежа в список значений: ПлатежныеДни.
2. Получить номер дня текущей даты (не помню, как в семерке): ТекДень.
3. В ПлатежныеДни ищем первый ПлатежныйДень, который >= ТекДень. Разница = ПлатежныйДень - ТекДень.
4. Если такого нет, берем просто ПлатежныйДень = ПлатежныеДни(0). Разница = 7 - ТекДень + ПлатежныйДень.
5. ДатаПлатежа = ТекущаяДата + Разница.
29 VladZ
 
05.10.17
12:10
Как-то так.  Писал по памяти, 7.7 нет под рукой

Функция ПолучитьБлижайшийДеньПлатежа(ВыбДата, СписокДнейОплаты)

  ВыбДеньНедели = ДеньНедели(ВыбДата);
  БлижайшийДеньПлатежа = НачалоДня(ВыбДата);
  Пока СписокДнейОплаты.Принадлежит(ВыбДеньНедели) = 0 Цикл
    БлижайшийДеньПлатежа = БлижайшийДеньПлатежа + 86400;
    ВыбДеньНедели = ДеньНедели(БлижайшийДеньПлатежа);
  КонецЦикла;
  Возврат БлижайшийДеньПлатежа;
КонецФункции
30 VladZ
 
05.10.17
12:10
Упс. БлижайшийДеньПлатежа = БлижайшийДеньПлатежа + 1;
31 VladZ
 
05.10.17
12:11
На входе еще желательно проверить, заполнен ли список дней оплаты.
32 mishaPH
 
модератор
05.10.17
12:11
(28) да можно в список, можно в строк

а далее например вышла строка 1,3
и в условии Если найти(СтрокаА,ВыбДеньНедели) = 0
34 mishaPH
 
модератор
05.10.17
12:12
(29) Да или так
35 mishaPH
 
модератор
05.10.17
12:29
Функция ПолучитьБлижайшийДеньПлатежа(ВыбДата, СписокДнейОплаты)

  ВыбДеньНедели = НомерДняНедели(ВыбДата);
  БлижайшийДеньПлатежа = ВыбДата;

  Пока СписокДнейОплаты.Принадлежит(ВыбДеньНедели) = 0 Цикл
    БлижайшийДеньПлатежа = БлижайшийДеньПлатежа + 1;
    ВыбДеньНедели = НомерДняНедели(БлижайшийДеньПлатежа);
  КонецЦикла;
  Возврат БлижайшийДеньПлатежа;
КонецФункции

Процедура Сформировать()
    СписокДнейОплаты = СоздатьОбъект("СписокЗначений");
    СписокДнейОплаты.ДобавитьЗначение(1);
    СписокДнейОплаты.ДобавитьЗначение(3);
    
    Сообщить(ПолучитьБлижайшийДеньПлатежа(ДатаА,СписокДнейОплаты));
КонецПроцедуры


вот . работает если кому-то надо будет
36 Злопчинский
 
05.10.17
13:12
СписокДнейОплаты = СоздатьОбъект("СписокЗначений");
    СписокДнейОплаты.ДобавитьЗначение(1,"1");
    СписокДнейОплаты.ДобавитьЗначение(2,"3");
    СписокДнейОплаты.ДобавитьЗначение(3,"3");
    СписокДнейОплаты.ДобавитьЗначение(4,"1");
    СписокДнейОплаты.ДобавитьЗначение(5,"1");
    СписокДнейОплаты.ДобавитьЗначение(6,"1");
    СписокДнейОплаты.ДобавитьЗначение(7,"1");

    //ТДН - текущий день недели
    ДеньПлатежа="";
    СписокДнейОплаты.ПолучитьЗначение(ТДН,ДеньПлатежа);
    ДеньПлатежа = Число(ДеньПлатежа);
37 mistеr
 
05.10.17
15:18
(35) Добавь проверку, что СписокДнейОплаты не пустой, а то зациклишься.
38 mishaPH
 
модератор
05.10.17
15:22
(37) мерси