Получить первую субботу месяца и последнюю пятницу последней недели месяца

Эта потребность немного странная, и я могу сделать это на C#, но, похоже, не могу получить правильный синтаксис выражения для конструктора отчетов.

Я хочу установить параметры начала и окончания по умолчанию для отчета. Для этого мне нужны значения «только дата» для первой субботы месяца и дата пятницы последней недели этого месяца. Это означает, что последнее значение действительно может быть в следующем месяце. Итак, для 2012 года мои значения будут выглядеть так:

Дата начала: 06.10.2012 Дата окончания: 02.11.2012

Дата начала: 03.11.2012 Дата окончания: 30.11.2012

Дата начала: 01.12.2012 Дата окончания: 04.01.2013

Я работал с условными операторами, используя Month(), Weekday(), WeekdayName и т. д., но мне не повезло. Кто-нибудь делал что-то подобное?


person DJGray    schedule 21.12.2012    source источник
comment
Я не знаком с Visual Studio Report Designer, но похоже, что параметр End также может быть определен как: последняя суббота месяца плюс шесть дней. Это также: последняя пятница не позднее 6-го числа следующего месяца. Не знаю, поможет ли это?   -  person Jeppe Stig Nielsen    schedule 21.12.2012


Ответы (3)


Вам, вероятно, не нужны никакие здоровенные условные операторы. Если вы делаете это для имитации циклов и других императивных функций программирования, может быть проще создать функцию в Пользовательский код.

Альтернативой является поиск алгоритма для конкретных вычислений, которые вы делаете. Например, этот ответ может стать отличной основой для получения необходимых дат, пусть и с небольшой корректировкой. Вот как это будет работать для первой субботы этого месяца:

  1. День недели для 1 числа этого месяца:

    =Weekday(DateAdd("d", 1 - Now().Day, Now()), FirstDayOfWeek.Sunday)
    
  2. Сколько дней мы должны добавить к этому первому дню месяца:

    =7 - Weekday(DateAdd("d", 1 - Now().Day, Now()), FirstDayOfWeek.Sunday)
    
  3. Итак, дата первой субботы месяца:

    =DateAdd("d", 
         7 - Weekday(DateAdd("d", 1 - Now().Day, Now()), FirstDayOfWeek.Sunday),
         DateAdd("d", 1 - Now().Day, Now())
        )
    

Вероятно, есть еще более разумные способы сделать это, хотя выражения VBScript имеют небольшие ограничения. Приведенный выше пример также можно настроить, чтобы получить «пятницу последней недели месяца».

Итог: (косвенный, но общий) ответ на ваш вопрос состоит в том, чтобы подумать об алгоритме достижения желаемой даты (как можно более декларативном, потому что вы не можете выполнять циклы и вещи в выражениях легко).

person Jeroen    schedule 24.12.2012
comment
Jeroen, спасибо, что методично прошли через это. Это помогло увидеть, как вы аргументировали свой путь через это. Я могу использовать тот же подход, чтобы получить дату окончания. - person DJGray; 26.12.2012
comment
Я не большой программист, кроме SQL. Я не знал о команде FirstDayOfWeek. Спасибо за ответ. - person Neil; 27.12.2012

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

=IIF( WeekdayName(DatePart("w", (CDate((Month(NOW()) - 1) & "/1/" & YEAR(NOW()))))) = "Saturday", (CDate((Month(NOW()) - 1) & "/1/" & YEAR(NOW()))), 
(IIF( WeekdayName(DatePart("w", (CDate((Month(NOW()) - 1) & "/2/" & YEAR(NOW()))))) = "Saturday", (CDate((Month(NOW()) - 1) & "/2/" & YEAR(NOW()))), 
    (IIF( WeekdayName(DatePart("w", (CDate((Month(NOW()) - 1) & "/3/" & YEAR(NOW()))))) = "Saturday", (CDate((Month(NOW()) - 1) & "/3/" & YEAR(NOW()))),
        (IIF( WeekdayName(DatePart("w", (CDate((Month(NOW()) - 1) & "/4/" & YEAR(NOW()))))) = "Saturday", (CDate((Month(NOW()) - 1) & "/4/" & YEAR(NOW()))),
            (IIF( WeekdayName(DatePart("w", (CDate((Month(NOW()) - 1) & "/5/" & YEAR(NOW()))))) = "Saturday", (CDate((Month(NOW()) - 1) & "/5/" & YEAR(NOW()))),
                (IIF( WeekdayName(DatePart("w", (CDate((Month(NOW()) - 1) & "/6/" & YEAR(NOW()))))) = "Saturday", (CDate((Month(NOW()) - 1) & "/6/" & YEAR(NOW()))),
                    (IIF( WeekdayName(DatePart("w", (CDate((Month(NOW()) - 1) & "/7/" & YEAR(NOW()))))) = "Saturday", (CDate((Month(NOW()) - 1) & "/7/" & YEAR(NOW()))),
"1/1/2010")))))))))))))

С другой стороны, это очень простой способ получить, если у вас есть таблица календаря в SQL Server (особенно когда вам нужна пятница). Вы можете сделать простой оператор выбора, например следующий:

SELECT
    MIN(date)
FROM
    calendar c
WHERE
    MONTH(DATEADD("m", -1, GETDATE())) = MONTH(date)
    AND YEAR(DATEADD("m", -1, GETDATE())) = YEAR(date)
    AND datename(dw, date) = 'Saturday'
person Neil    schedule 21.12.2012
comment
Нил, спасибо за полезный ответ. Я делал вложенные IIF, но никогда так много!! ;-) - person DJGray; 26.12.2012
comment
Спасибо ОБОИМ из вас (Нил и Джероен). Мне удалось массировать ваши примеры, чтобы получить первую субботу и пятницу последней недели предыдущего месяца. (Мы всегда выставляем счет за один месяц в районе.) Я хотел бы выбрать ОБА ответа в качестве принятого ответа, потому что у меня действительно было две проблемы, и я использовал ваш пример кода для решения каждой. - person DJGray; 27.12.2012

Получить последнюю пятницу прошлого месяца.....

=DateAdd(DateInterval.Day,- Weekday(DateAdd("d", 1 - Now().Day, Now()), FirstDayOfWeek.Saturday), DateSerial(Year(Date.Now), Month(Date.Now), 1))

person Roger    schedule 12.12.2014