有人可以帮助我解决我想要创建的Access查询吗?
我有一个包含项目列表及其开始日期和结束日期的表格。我需要的是一个查询,显示每个项目的逐月项目细分,例如:
PROJECT Jan Feb Mar
AAAAA 7 28 2
...等,其中数字是根据开始日期和结束日期计算的项目天数。例如,在上述查询中,项目AAAAA
的开始日期为24/01/2012
,结束日期为02/03/2012
有人可以指导我如何实现这个目标吗?
非常感谢!!
答案 0 :(得分:1)
我创建了一个日历表,以便更容易应对。我在下面包含了我使用的两个过程(CreateTable_calendar和LoadCalendar)的代码。我在日历表中添加了“work_day”字段,以防您将天数限制为仅在每个月的组织工作日。如果是这样,您将需要相应地调整查询的WHERE子句。如果我的选择与您的选择不匹配,还会重置每个日历日期的work_day值。
无论如何,我会留下这些细节供你整理。如果不对工作日和非工作日进行调整,此查询将返回我认为您想要的结果集。
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");
备注强>:
制作日历表:
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
修改:日历是保留字。见Problem names and reserved words in Access。直到我和布朗先生Database Issue Checker Utility检查我的数据库之前,我才注意到这一点。所以我在这个答案中将名称日历更改为tblCalendar。我强烈推荐这个实用程序。除了识别保留字的问题外,它还可以告知您许多其他潜在的问题。
答案 1 :(得分:0)
建议您查看交叉表查询: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日完成它是否计入jan还是需要继续第一个feb等)但是它足以让你入门
最后,使用Access交叉表将其转换为所需格式,在每月的项目开始日期和结束日期之间进行日期减法。