Reports Starter Kit详细介绍(二)
2006-05-28 14:57 Clingingboy 阅读(1954) 评论(1) 编辑 收藏 举报
这次接着继续分析交叉分析报表和详情资料报表
1.交叉分析报表
交叉分析报表是根据不同的年份,然后根据不同的季度统计月份销售总额和各地区销售总额
先看下图
这个效果跟表格式报表有点相似,还是DataList镶套DataGrid
DataList没有绑定数据库中的数据,而是绑定了一个数组,表示季节
在前台显示的时候也没有绑定任何字段(下面的绑定我也有点模糊,为什么就不需要字段呢,但我测试过,是可以用的)
然后DataGrid控件根据年份和季度来获取,因为绑定季度是固定不变的,所需要改变的只是年份而已
提取数据最关键的地方还是在存储过程这里.我第一眼看的时候发现有两个from子句,有点模糊,后来发现第一个From下面有一个"("
里面还存在一个select语句,是提取统计大多数字段,
大概意思是根据年份,季度获取各个区域的销售额,然后在季度中分组,其显示的效果就是DataGrid的效果
而外部的seleclt语句是为了定义一个TotalMoth,目的是获取月份地区销售额
ALTER PROCEDURE Reports_GetSalesByRegion
(
@Year int,
@Quarter int
)
AS
--销售总额为各个地区销售额的总和
Select
*, TotalMonth = Eastern + Western + Northern + Southern
From
(
--销售月份
Select DatePart(month, OrderDate) MonthOfSales,
--东部地区
Sum(Case RegionID When 1 Then (UnitPrice * Quantity ) Else 0 End) As Eastern,
--西部地区
Sum(Case RegionID When 2 Then (UnitPrice * Quantity ) Else 0 End) As Western,
--北部地区
Sum(Case RegionID When 3 Then (UnitPrice * Quantity ) Else 0 End) As Northern,
--南部地区
Sum(Case RegionID When 4 Then (UnitPrice * Quantity ) Else 0 End) As Southern
From Reports_Orders O
--地区
Inner Join Reports_Territories T On O.TerritoryID = T.TerritoryID
--订单详细
Inner Join [Reports_Order Details] OD On O.OrderID = OD.OrderID
--年份,季节条件
Where Year(OrderDate) = @Year And DatePart(q, OrderDate) = @Quarter
--按月份分组
Group By DatePart(month, OrderDate)
) As T
Order By MonthOfSales
我根据上面的语句改了一下,下面的语句看起来比较容易理解
ALTER PROCEDURE Reports_GetSalesByRegion
(
@Year int,
@Quarter int
)
AS
--销售总额为各个地区销售额的总和
--销售月份
Select DatePart(month, OrderDate) MonthOfSales,
--东部地区
Sum(Case RegionID When 1 Then (UnitPrice * Quantity ) Else 0 End) As Eastern,
--西部地区
Sum(Case RegionID When 2 Then (UnitPrice * Quantity ) Else 0 End) As Western,
--北部地区
Sum(Case RegionID When 3 Then (UnitPrice * Quantity ) Else 0 End) As Northern,
--南部地区
Sum(Case RegionID When 4 Then (UnitPrice * Quantity ) Else 0 End) As Southern,
Sum(UnitPrice * Quantity) As TotalMonth
From Reports_Orders O
--地区
Inner Join Reports_Territories T On O.TerritoryID = T.TerritoryID
--订单详细
Inner Join [Reports_Order Details] OD On O.OrderID = OD.OrderID
--年份,季节条件
Where Year(OrderDate) = @Year And DatePart(q, OrderDate) = @Quarter
--按月份分组
Group By DatePart(month, OrderDate)
其他的实现,还有页脚统计区域销售额,格式化,同上次讲的例子实现方法相同
实现代码需写在Item_Created事件里面,由于镶套在DataList里,需要手动写代码.
以为我是认为是实现报表效果的关键
2,详细资料报表
详细资料报表中有两张表,一张表按年度,月份统计订单数和销售额,另一张表则显示全年或指定季度订单的信息
(1)当我们重新选择年份的时候,两张表均发生变化,此事件需要重新绑定两个表
当选择季度的时候,第一张表不变,只需绑定一个表
(2)为了保存查询数据,当重新绑定的时候,其中设置了两个Session.然后在Page_Load中判断
其他效果,如页眉显示销售总额,实现方法差不多.下面还看存储过程怎么写.
上面我们讲的交叉分析报表是根据季度按月份分组,下面的则是根据年份按季度分组.道理是一样的.第一张表实现的关键就在于下面的存储过程.
ALTER PROCEDURE Reports_GetOrderSummary
(
@Year int
)
AS
--从订购日期中取季节
SELECT
DATEPART(q, OrderDate) Quarter,
--统计订单数
COUNT(DISTINCT Reports_Orders.OrderID) OrdersShipped,
--统计销售额
SUM(UnitPrice * Quantity * (1-Discount)) Sales
FROM Reports_Orders
--订单表和订单明细表关联
INNER JOIN [Reports_Order Details] Details
ON Reports_Orders.OrderID = Details.OrderID
--年份等于给定参数
WHERE YEAR(OrderDate) = @Year
--按季节分组
GROUP BY DATEPART(q, OrderDate)
显示第二张表数据的存储过程
ALTER PROCEDURE Reports_GetOrdersAndDetails
(
@Year int,
@Quarter int
)
AS
SELECT
Reports_Orders.OrderID,
OrderDate,
--计算单张订单销售额
SUM(UnitPrice * Quantity * (1-Discount)) Sales
FROM Reports_Orders
INNER JOIN [Reports_Order Details] Details
ON Reports_Orders.OrderID = Details.OrderID
WHERE
--年度等于指定年度
YEAR(OrderDate) = @Year AND
(@Quarter = 0 OR
--否则,只选取指定的季节
DATEPART(q, OrderDate) = @Quarter)
GROUP BY
--按年份,订单ID,订购日期分组
DATEPART(y, OrderDate),
Reports_Orders.OrderID,
OrderDate
wehre中有一个选择,表示如果下拉框中选择是All的话,则显示全部信息,否则根据季度显示
上面的几个存储过程多处用到了时间函数,如果不熟悉的话请,参考一下帮助文件.
以上就是我对两个报表的分析.本人表达能力不强.希望对看到此文的人有帮助.也望大家指出错误
1.交叉分析报表
交叉分析报表是根据不同的年份,然后根据不同的季度统计月份销售总额和各地区销售总额
先看下图
这个效果跟表格式报表有点相似,还是DataList镶套DataGrid
<asp:datalist id="QuartersList" runat="server" cellspacing="0" cellpadding="0">
<ItemTemplate>
<TABLE cellSpacing="0" cellPadding="3" border="0">
<TR>
<TD class="textbold" colSpan="2">Quarter
<%# Container.DataItem %>
</TD>
</TR>
<TR>
<TD colSpan="2"><IMG height="5" src="images/spacer.gif"></TD>
</TR>
<TR>
<TD><IMG src="images/spacer.gif" width="30"></TD>
<TD>
<TABLE cellSpacing="0" cellPadding="0" border="0">
<asp:datagrid id=DataGrid1 runat="server" CssClass="Content" CellPadding="3" OnItemDataBound="SumItems" DataSource="<%# GetQuarterDetails((int)Container.DataItem) %>" ShowFooter="True" GridLines="None" AutoGenerateColumns="False" width="600">
<columns>
<asp:templatecolumn headertext="Month" itemstyle-cssclass="ItemStyle" headerstyle-cssclass="HeaderStyle"
footerstyle-cssclass="FooterStyle">
<itemtemplate>
<%# String.Format("{0:MMMM}",DataBinder.Eval(Container.DataItem, "OrderDate")) %>
</itemtemplate>
</asp:templatecolumn>
<asp:boundcolumn datafield="Eastern" headertext="Eastern" itemstyle-cssclass="ItemStyleRight" headerstyle-cssclass="HeaderStyleRight"
footerstyle-cssclass="FooterStyleRight"></asp:boundcolumn>. </asp:datagrid></TABLE>
</TD>
</TR>
<TR> <TD colSpan="2"><IMG height="10" src="images/spacer.gif"></TD>
</TR>
</TABLE>
</ItemTemplate>
<HeaderStyle CssClass="ReportTitle"></HeaderStyle>
</asp:datalist>
<ItemTemplate>
<TABLE cellSpacing="0" cellPadding="3" border="0">
<TR>
<TD class="textbold" colSpan="2">Quarter
<%# Container.DataItem %>
</TD>
</TR>
<TR>
<TD colSpan="2"><IMG height="5" src="images/spacer.gif"></TD>
</TR>
<TR>
<TD><IMG src="images/spacer.gif" width="30"></TD>
<TD>
<TABLE cellSpacing="0" cellPadding="0" border="0">
<asp:datagrid id=DataGrid1 runat="server" CssClass="Content" CellPadding="3" OnItemDataBound="SumItems" DataSource="<%# GetQuarterDetails((int)Container.DataItem) %>" ShowFooter="True" GridLines="None" AutoGenerateColumns="False" width="600">
<columns>
<asp:templatecolumn headertext="Month" itemstyle-cssclass="ItemStyle" headerstyle-cssclass="HeaderStyle"
footerstyle-cssclass="FooterStyle">
<itemtemplate>
<%# String.Format("{0:MMMM}",DataBinder.Eval(Container.DataItem, "OrderDate")) %>
</itemtemplate>
</asp:templatecolumn>
<asp:boundcolumn datafield="Eastern" headertext="Eastern" itemstyle-cssclass="ItemStyleRight" headerstyle-cssclass="HeaderStyleRight"
footerstyle-cssclass="FooterStyleRight"></asp:boundcolumn>. </asp:datagrid></TABLE>
</TD>
</TR>
<TR> <TD colSpan="2"><IMG height="10" src="images/spacer.gif"></TD>
</TR>
</TABLE>
</ItemTemplate>
<HeaderStyle CssClass="ReportTitle"></HeaderStyle>
</asp:datalist>
DataList没有绑定数据库中的数据,而是绑定了一个数组,表示季节
1private void BindList()
2 {
3 QuartersList.DataSource = new int[4] { 1, 2, 3, 4 };
4 QuartersList.DataBind();
5 }
2 {
3 QuartersList.DataSource = new int[4] { 1, 2, 3, 4 };
4 QuartersList.DataBind();
5 }
在前台显示的时候也没有绑定任何字段(下面的绑定我也有点模糊,为什么就不需要字段呢,但我测试过,是可以用的)
Quarter<%# Container.DataItem %>
然后DataGrid控件根据年份和季度来获取,因为绑定季度是固定不变的,所需要改变的只是年份而已
protected CrossTabReportCollection GetQuarterDetails(int quarter)
{
return CrossTabReport.GetRegionSales(quarter, Convert.ToInt32(YearDropDownList.SelectedItem.Value));
}
{
return CrossTabReport.GetRegionSales(quarter, Convert.ToInt32(YearDropDownList.SelectedItem.Value));
}
DataSource="<%# GetQuarterDetails((int)Container.DataItem) %>"
提取数据最关键的地方还是在存储过程这里.我第一眼看的时候发现有两个from子句,有点模糊,后来发现第一个From下面有一个"("
里面还存在一个select语句,是提取统计大多数字段,
大概意思是根据年份,季度获取各个区域的销售额,然后在季度中分组,其显示的效果就是DataGrid的效果
而外部的seleclt语句是为了定义一个TotalMoth,目的是获取月份地区销售额
ALTER PROCEDURE Reports_GetSalesByRegion
(
@Year int,
@Quarter int
)
AS
--销售总额为各个地区销售额的总和
Select
*, TotalMonth = Eastern + Western + Northern + Southern
From
(
--销售月份
Select DatePart(month, OrderDate) MonthOfSales,
--东部地区
Sum(Case RegionID When 1 Then (UnitPrice * Quantity ) Else 0 End) As Eastern,
--西部地区
Sum(Case RegionID When 2 Then (UnitPrice * Quantity ) Else 0 End) As Western,
--北部地区
Sum(Case RegionID When 3 Then (UnitPrice * Quantity ) Else 0 End) As Northern,
--南部地区
Sum(Case RegionID When 4 Then (UnitPrice * Quantity ) Else 0 End) As Southern
From Reports_Orders O
--地区
Inner Join Reports_Territories T On O.TerritoryID = T.TerritoryID
--订单详细
Inner Join [Reports_Order Details] OD On O.OrderID = OD.OrderID
--年份,季节条件
Where Year(OrderDate) = @Year And DatePart(q, OrderDate) = @Quarter
--按月份分组
Group By DatePart(month, OrderDate)
) As T
Order By MonthOfSales
我根据上面的语句改了一下,下面的语句看起来比较容易理解
ALTER PROCEDURE Reports_GetSalesByRegion
(
@Year int,
@Quarter int
)
AS
--销售总额为各个地区销售额的总和
--销售月份
Select DatePart(month, OrderDate) MonthOfSales,
--东部地区
Sum(Case RegionID When 1 Then (UnitPrice * Quantity ) Else 0 End) As Eastern,
--西部地区
Sum(Case RegionID When 2 Then (UnitPrice * Quantity ) Else 0 End) As Western,
--北部地区
Sum(Case RegionID When 3 Then (UnitPrice * Quantity ) Else 0 End) As Northern,
--南部地区
Sum(Case RegionID When 4 Then (UnitPrice * Quantity ) Else 0 End) As Southern,
Sum(UnitPrice * Quantity) As TotalMonth
From Reports_Orders O
--地区
Inner Join Reports_Territories T On O.TerritoryID = T.TerritoryID
--订单详细
Inner Join [Reports_Order Details] OD On O.OrderID = OD.OrderID
--年份,季节条件
Where Year(OrderDate) = @Year And DatePart(q, OrderDate) = @Quarter
--按月份分组
Group By DatePart(month, OrderDate)
其他的实现,还有页脚统计区域销售额,格式化,同上次讲的例子实现方法相同
实现代码需写在Item_Created事件里面,由于镶套在DataList里,需要手动写代码.
以为我是认为是实现报表效果的关键
2,详细资料报表
详细资料报表中有两张表,一张表按年度,月份统计订单数和销售额,另一张表则显示全年或指定季度订单的信息
(1)当我们重新选择年份的时候,两张表均发生变化,此事件需要重新绑定两个表
当选择季度的时候,第一张表不变,只需绑定一个表
(2)为了保存查询数据,当重新绑定的时候,其中设置了两个Session.然后在Page_Load中判断
private void YearDropDownList_SelectedIndexChanged(object sender, System.EventArgs e)
{
Session[_masterDetailYear] = YearDropDownList.SelectedItem.Value;
BindSummary();
BindDetails();
}
private void QuarterDropDownList_SelectedIndexChanged(object sender, System.EventArgs e)
{
Session[_masterDetailQuarter] = QuarterDropDownList.SelectedItem.Value;
BindDetails();
}
{
Session[_masterDetailYear] = YearDropDownList.SelectedItem.Value;
BindSummary();
BindDetails();
}
private void QuarterDropDownList_SelectedIndexChanged(object sender, System.EventArgs e)
{
Session[_masterDetailQuarter] = QuarterDropDownList.SelectedItem.Value;
BindDetails();
}
其他效果,如页眉显示销售总额,实现方法差不多.下面还看存储过程怎么写.
上面我们讲的交叉分析报表是根据季度按月份分组,下面的则是根据年份按季度分组.道理是一样的.第一张表实现的关键就在于下面的存储过程.
ALTER PROCEDURE Reports_GetOrderSummary
(
@Year int
)
AS
--从订购日期中取季节
SELECT
DATEPART(q, OrderDate) Quarter,
--统计订单数
COUNT(DISTINCT Reports_Orders.OrderID) OrdersShipped,
--统计销售额
SUM(UnitPrice * Quantity * (1-Discount)) Sales
FROM Reports_Orders
--订单表和订单明细表关联
INNER JOIN [Reports_Order Details] Details
ON Reports_Orders.OrderID = Details.OrderID
--年份等于给定参数
WHERE YEAR(OrderDate) = @Year
--按季节分组
GROUP BY DATEPART(q, OrderDate)
显示第二张表数据的存储过程
ALTER PROCEDURE Reports_GetOrdersAndDetails
(
@Year int,
@Quarter int
)
AS
SELECT
Reports_Orders.OrderID,
OrderDate,
--计算单张订单销售额
SUM(UnitPrice * Quantity * (1-Discount)) Sales
FROM Reports_Orders
INNER JOIN [Reports_Order Details] Details
ON Reports_Orders.OrderID = Details.OrderID
WHERE
--年度等于指定年度
YEAR(OrderDate) = @Year AND
(@Quarter = 0 OR
--否则,只选取指定的季节
DATEPART(q, OrderDate) = @Quarter)
GROUP BY
--按年份,订单ID,订购日期分组
DATEPART(y, OrderDate),
Reports_Orders.OrderID,
OrderDate
wehre中有一个选择,表示如果下拉框中选择是All的话,则显示全部信息,否则根据季度显示
上面的几个存储过程多处用到了时间函数,如果不熟悉的话请,参考一下帮助文件.
以上就是我对两个报表的分析.本人表达能力不强.希望对看到此文的人有帮助.也望大家指出错误