Использование даты начала и окончания в запросе Access - PullRequest
1 голос
/ 15 февраля 2012

Может кто-нибудь помочь мне с этим запросом Access, который я пытаюсь создать?

У меня есть таблица со списком проектов, датами их начала и окончания.Мне нужен запрос, который показывает разбивку дней проекта по месяцам для каждого проекта, например:

PROJECT    Jan       Feb       Mar
AAAAA       7        28        2

... и т. Д., Где числа - это дни проекта, рассчитанные на основе даты начала иДата окончания.Например, в приведенном выше запросе проект AAAAA будет иметь начальную дату 24/01/2012 и конечную дату 02/03/2012

. Может, кто-нибудь подскажет, как этого добиться?

Большое спасибо !!

Ответы [ 2 ]

1 голос
/ 16 февраля 2012

Я создал таблицу календаря, чтобы было легче с ней справляться.Я включил код для двух процедур, которые я использовал (CreateTable_calendar и LoadCalendar) ниже.Я добавил поле «рабочий день» в таблицу календаря, если вы хотите ограничить количество дней только рабочими днями вашей организации в каждом месяце.Если это так, вам необходимо соответствующим образом изменить предложение WHERE.А также сбросьте значения рабочего дня для каждой календарной даты, если мой выбор не совпадает с вашим.

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

TRANSFORM Count(sub.the_date) AS CountOfProjectDays
SELECT sub.Project_name
FROM
    (
        SELECT
            p.Project_name,
            MonthName(Month(c.the_date),-1) AS month_name,
            c.the_date
        FROM Projects AS p, tblCalendar AS c
        WHERE
            c.the_date >= [p].[start_date]
            And c.the_date <= [p].[end_date]
        ORDER BY p.Project_name
    ) AS sub
GROUP BY sub.Project_name
PIVOT sub.month_name
    In ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
       "Aug", "Sep", "Oct", "Nov", "Dec");

Примечания :

  1. Я использовал список названий месяцев после PIVOT, чтобы изменить порядок столбцов.Без этого списка столбцы будут представлены в алфавитном порядке по названию месяца.Сократите этот список, если вы не хотите / не нуждаетесь в столбцах для всех 12 месяцев.
  2. Этот подход должен работать, когда все даты взяты из одного календарного года.Если вы хотите иметь дело с диапазоном дат, который охватывает более одного года ... у вас есть больше работы.: -)

Сделать таблицу календаря:

Public Sub CreateTable_calendar()
    Const cstrTable As String = "tblCalendar"
    Dim cn As Object
    Dim strSql As String
    Set cn = CurrentProject.Connection

    On Error Resume Next
    cn.Execute "DROP TABLE " & cstrTable & ";"
    If Err.Number <> 0 Then
        Debug.Print Err.Description
    End If
    On Error GoTo 0

    strSql = "CREATE TABLE " & cstrTable & " (" & vbCrLf & _
        "the_date DATETIME CONSTRAINT pkey PRIMARY KEY," & vbCrLf & _
        "work_day YESNO," & vbCrLf & _
        "CONSTRAINT midnite_only CHECK " & _
        "(the_date = DateValue(the_date))" & vbCrLf & _
        ");"
    Debug.Print strSql
    cn.Execute strSql

    Set cn = Nothing
End Sub

Загрузить таблицу календаря.Без указания аргумента для года будут загружены все даты текущего года.В противном случае он загружает даты за год, который вы указали в качестве аргумента.

Public Sub LoadCalendar(Optional ByVal pYear As Integer)
    Const cstrTable As String = "tblCalendar"
    Dim db As DAO.Database
    Dim dte As Date
    Dim intYear As Integer
    Dim rs As DAO.Recordset
    Dim strMsg As String

On Error GoTo ErrorHandler

    intYear = IIf(pYear = 0, Year(Date), pYear)
    dte = DateSerial(intYear, 1, 1)

    Set db = CurrentDb
    Set rs = db.OpenRecordset(cstrTable, dbOpenTable, dbAppendOnly)

    Do While Year(dte) = intYear
        rs.AddNew
        rs!the_date = dte
        rs!work_day = Not (Weekday(dte) = vbSunday Or _
            Weekday(dte) = vbSaturday)
        rs.Update
        dte = dte + 1
    Loop
    rs.Close

ExitHere:
    On Error GoTo 0
    Set rs = Nothing
    Set db = Nothing
    Exit Sub

ErrorHandler:
    strMsg = "Error " & Err.Number & " (" & Err.Description _
        & ") in procedure LoadCalendar"
    MsgBox strMsg
    GoTo ExitHere
End Sub

Редактировать : Календарь является зарезервированным словом.См. Имена проблем и зарезервированные слова в Access .Я не замечал этого, пока не проверил свою базу данных с помощью утилиты проверки проблем с базой данных мистера Брауна *1027*.Поэтому я изменил название календаря на tblCalendar в этом ответе.И я настоятельно рекомендую эту утилиту.Помимо выявления проблем с зарезервированными словами, он может информировать вас о многих других потенциальных проблемных проблемах.

0 голосов
/ 15 февраля 2012

Предлагаем посмотреть на кросс-таблицы запросов: http://www.databasedev.co.uk/crosstab_queries.html

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

Ваши шаги похожи на:
1 таблица диапазонов дат в месяц
2 рассчитать даты начала и окончания каждого проекта в месяц

Select p.projectName, md.monthNumber,
Case when p.startDate < md.startDate then md.startDate
When p.startDate < md.endDate then p.startDate else p.endDate
, case when p.endDate > md.endDate then md.endDate
When p.endDate > md.startDate then p.endDate else md.startdate end
From @projects p
Inner join @monthDates md on p.startDate <= md.endDate and p.endDate > md.startDate

В Access я думаю, что IIF является эквивалентом CASE?

Вам необходимо отрегулировать вышеперечисленное в зависимости от того, как вы хотите считать первые / последние дни месяца (если проект заканчивается 31-го числа, считается ли он до января или ему необходимо продолжить до 1-го февраля и т. Д.), Но его достаточно, чтобы начать

Наконец, вы используете кросс-таблицу Access, чтобы преобразовать ее в требуемый формат, делая вычитание даты между датами начала и окончания проекта в месяц.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...