Форум 1С
Программистам, бухгалтерам, администраторам, пользователям
Задай вопрос - получи решение проблемы
26 июн 2024, 14:17

Вычисление ближайшей даты к графику по дням недели.

Автор MrLvovsky, 18 апр 2017, 12:02

0 Пользователей и 1 гость просматривают эту тему.

MrLvovsky

Добрый день, Уважаемый форум!
Возникла следующая ситуация.
Есть поле, в которое ручками вносят данные о дне недели поставки в формате "пн, ср". День может быть один, может быть несколько (в неделе).
Очень костыльным образом я преобразовываю эти данные в число дня недели:
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номер");
Если НЕ СтрНайти(Строка, "пн") Тогда
ТЗ.Добавить().Номер = 1;
КонецЕсли;
Если НЕ СтрНайти(Строка, "вт") Тогда
ТЗ.Добавить().Номер = 2;
КонецЕсли;
Если НЕ СтрНайти(Строка, "ср") Тогда
ТЗ.Добавить().Номер = 3;
КонецЕсли;
Если НЕ СтрНайти(Строка, "чт") Тогда
ТЗ.Добавить().Номер = 4;
КонецЕсли;
Если НЕ СтрНайти(Строка, "пт") Тогда
ТЗ.Добавить().Номер = 5;
КонецЕсли;
Если НЕ СтрНайти(Строка, "сб") Тогда
ТЗ.Добавить().Номер = 6;
КонецЕсли;
Если НЕ СтрНайти(Строка, "вс") Тогда
ТЗ.Добавить().Номер = 7;
КонецЕсли;


Теперь мне нужно сравнить ближайшую дату к отчетной дате относительно этого графика. (Звучит запутанно, но я приведу примеры).
Выглядеть это должно в таком формате - 01.04.2017(сб) + пн, ср (1, 3) = 03.04.2017(пн) (То есть нужно взять отчетную дату и найти ближайшую дату к ней, соответствующую графику).

Возможно кто то раньше что то подобное описывал. Поделитесь пожалуйста.
Так же любые адекватные идеи приветствуются =)
Заранее спасибо.

LexaK

ничего кроме банального перебора на ум не приходит
попробуйте такую функцию

Функция БлижайшаяДата(лкДатаОтчета, МассивДней)

    //МассивДней - дни недели в порядке возрастания

лкДНОтчета = ДеньНедели(лкДата);
лкДней = 0;

Если МассивДней.Количество() = 0 Тогда
Возврат лкДатаОтчета;
КонецЕсли;

//для перебора до ближайшего дня в теущей недели
Для каждого лкДн Из МассивДней Цикл

Если лкДНОтчета < лкДн Тогда
//есть ближайший день
лкДней = лкДн - лкДНОтчета;
Прервать;
КонецЕсли;

КонецЦикла;

Если лкДней = 0 Тогда
//нет ближайшего деня в текущей недели
//берем первый день в следующей
лкДней = 7 + МассивДней[0] - лкДНОтчета;
КонецЕсли;

лкДата = лкДатаОтчета + лкДней * 24 * 3600; //прибалвяем нужное количесто дней

Возврат лкДата;

КонецФункции

если помогло нажмите: Спасибо!

Kironten

Я бы сделал так:
Делаем массив из найденных в строке дней недели, хотя можно и ТЗ как в вашем случае.
А потом так:
БлижайшаяДата = ОтчетнаяДата;
ДатаНеНайдена = Истина;
Если МассивДат.Количество() <> 0 Тогда
    Сч = 1;
    Пока ДатаНеНайдена ИЛИ Сч < 10 Цикл
        ДеньНеделиБлижайшейДаты = ДеньНедели(БлижайшаяДата);
        Если МассивДат.Найти(ДеньНеделиБлижайшейДаты) <> Неопределено
            Сообщить(БлижайшаяДата);
            ДатаНеНайдена = Ложь;
        Иначе
            БлижайшаяДата = БлижайшаяДата + 86400;
        КонецЕсли;
        Сч = Сч + 1;
    КонецЦикла;
Иначе
    Сообщить("Не найдены дни недели в строке ближайших. Проверьте заполнение или возможно орфографию заполненых");
КонецЕсли;

LexaK

упс, опечатка
лкДНОтчета = ДеньНедели(лкДата);
должно быть
лкДНОтчета = ДеньНедели(лкДатаОтчета);
если помогло нажмите: Спасибо!

Dethmontt

Если долго всматриваться в учебник...то в голову может прийти мысль его открыть!

MrLvovsky

У поставщиков нет праздников =) Как и у покупателей.
В итоге сделал так:
Функция ПолучитьДатуПоГрафику(Строка, ДатаЗПК)
ТЗ = Новый ТаблицаЗначений;
ТЗ.Колонки.Добавить("Номер");
Если НЕ СтрНайти(Строка, "пн") = 0 Тогда
ТЗ.Добавить().Номер = 1;
КонецЕсли;
Если НЕ СтрНайти(Строка, "вт") = 0  Тогда
ТЗ.Добавить().Номер = 2;
КонецЕсли;
Если НЕ СтрНайти(Строка, "ср") = 0  Тогда
ТЗ.Добавить().Номер = 3;
КонецЕсли;
Если НЕ СтрНайти(Строка, "чт") = 0  Тогда
ТЗ.Добавить().Номер = 4;
КонецЕсли;
Если НЕ СтрНайти(Строка, "пт") = 0  Тогда
ТЗ.Добавить().Номер = 5;
КонецЕсли;
Если НЕ СтрНайти(Строка, "сб") = 0  Тогда
ТЗ.Добавить().Номер = 6;
КонецЕсли;
Если НЕ СтрНайти(Строка, "вс") = 0  Тогда
ТЗ.Добавить().Номер = 7;
КонецЕсли;

ДН = ДеньНедели(ДатаЗПК);
ДатаНайдена = Ложь;
Итт = 0;

Пока НЕ ДатаНайдена = Истина Цикл
Если ТЗ.Найти(ДН) = Неопределено Тогда
Итт = Итт +1;
ДН = ДН+1;
Если ДН >=8 Тогда
ДН = 1;
КонецЕсли;
Иначе
ДатаНайдена = Истина;
Дата = ДатаЗПК + (Итт*24*60*60);
КонецЕсли;
КонецЦикла;
Возврат Дата;

КонецФункции


Может кому пригодится.

Kironten

Чисто на защиту от дурака: Если как вы говорите, в строку эти дни пишут менеджеры, то достаточно чтобы была строка к примеру "суб", или "понедельник" вместо "сб" и "пн", и получите бесконечный цикл.
Я бы не стал надеяться на их сознательность.

MrLvovsky

Цитата: Kironten от 19 апр 2017, 13:54
Чисто на защиту от дурака: Если как вы говорите, в строку эти дни пишут менеджеры, то достаточно чтобы была строка к примеру "суб", или "понедельник" вместо "сб" и "пн", и получите бесконечный цикл.
Я бы не стал надеяться на их сознательность.
Если он не находит нужного дня, то самого цикла не происходит и возвращается пустая дата.

Dethmontt

Если долго всматриваться в учебник...то в голову может прийти мысль его открыть!

MrLvovsky

Если ТЗ.Количество = 0 Тогда
Возврат '00010101';
КонецЕсли;

Теги:

Похожие темы (5)

Рейтинг@Mail.ru

Поиск