Reporting Services报表订阅开发手札

    技术2022-05-11  56

    订阅概述

    订阅是一种持续存在的请求,它在特定的时间或为响应某个事件而传递报表,然后以您定义的方式提交该报表。订阅提供了一种可替代按需运行报表的方法。按需运行报表要求您在每次查看报表时都执行特定的操作。相比之下,使用订阅则可以自动传递最新的报表。

    目前我们仅开发了标准订阅文件共享传递”,即由各个用户创建和管理并将报表生成到用户指定得UNC路径下.

    订阅创建/更新API

    创建订阅API

    [C#]

    public string CreateSubscription(

       string Report,

       [Namespace].ExtensionSettings ExtensionSettings,

       string Description,

       string EventType,

       string MatchData,

       [Namespace].ParameterValue[] Parameters

    );

       Member of [Namespace].ReportingService

    参数:

    Report

    订阅的报表全名(包括路径,报表名).

    ExtensionSettings

    报表扩展设置定义,我们将创建文件共享传递的扩展设置.

    Description

    订阅的描述.

    EventType

    订阅触发事件,我们仅使用TimedSubscription.

    MatchData

    描述触发事件的XML,我们称之为The XML description of Schedule Definition.

    Parameters

    报表参数数组. 有些报表需要用户输入参数方可执行, 输入该值,使系统自动填充参数并运行报表.

    返回值:

    订阅ID,Reporing Services数据库描述订阅的唯一标识.

     

    更新订阅API

    [C#]

    public void SetSubscriptionProperties(

       string SubscriptionID,

       [Namespace].ExtensionSettings ExtensionSettings,

       string Description,

       string EventType,

       string MatchData,

       [Namespace].ParameterValue[] Parameters

    );

       Member of [Namespace].ReportingService

    参数:

    SubscriptionID

    订阅ID.

    ExtensionSettings

    报表扩展设置定义,我们将创建文件共享传递的扩展设置.

    Description

    订阅的描述.

    EventType

    订阅触发事件,我们仅使用TimedSubscription.

    MatchData

    描述触发事件的XML.

    Parameters

    报表参数数组. 有些报表需要用户输入参数方可执行, 输入该值,使系统自动填充参数并运行报表.

     

    文件共享传递

    GET ExtendSetting FROM UI

    文件共享传递需要七个参数,它们组成了一个设置数组, 如下:

    Microsoft.ReportingServices.Interfaces.Setting[] intSettings

    = new Microsoft.ReportingServices.Interfaces.Setting[7];

    参数数组需要参数实例填充:

    intSettings[0]=new Microsoft.ReportingServices.Interfaces.Setting();

    intSettings[0].Name=PARAMETER_NAME;

    intSettings[0].Value=PARAMETER_VALUE;

           分别为设置数组赋实例: "PATH", "FILENAME", "FILEEXTN", "USERNAME", "PASSWORD", "RENDER_FORMAT", "WRITEMODE", 并分别设置对应界面空间上的Value.

    SET UI FROM ExtendSetting

           当更新订阅时,界面必须根据订阅ID取得订阅设置, 并重新设置界面控件值,此时参数数组变成6,它不提供PASSWORD设置:

    foreach(ParameterValue paramValue in extSetting.ParameterValues)

    {

    switch(paramValue.Name)

    {

    case "PATH":

    SET_PATH_TEXTBOX_VALUE;

    break;

    …….

    }

                  }

     

    订阅事件描述

           由于我们仅关注 TimedSubscription事件,所以订阅事件描述也即任务计划描述”.

          GET ScheduleDefinition FROM UI

    由上面的API我们知道,任务计划最终时返回其XML描述串.

    计划定义包括:

    1)      开始时间

    2)      结束时间(如果指定)

    3)      重复规则(不指定则仅在开始时间执行)

            private string GetMatchData()

            {

                   ScheduleDefinition schedule = new ScheduleDefinition();

                   schedule.StartDateTime = _startTime;

                   if(_hasEndTime)

                   {

                          schedule.EndDateSpecified = true; 

                          schedule.EndDate=_endTime;

                   }

                   schedule.Item = GetPattern();  //将根据界面选择返回重复规则定义 

                   XmlDocument xmlDoc = GetScheduleAsXml(schedule);//返回任务计划的XML

                   return xmlDoc.OuterXml;

            }

           共有五中重复规则定义:

    1)      MinuteRecurrence: 需要指定MinutesInterval, 可描述每隔X小时X分钟执行的任务计划.

    2)      DailyRecurrence: 需要指定DaysInterval, 可描述每隔X,开始时间执行的任务计划.

    3)      WeeklyRecurrence: 需要指定DaysOfWeek, WeeksInterval, 可描述每隔X,每星期X1,星期X2,星期X3…开始时间执行的任务计划.

    4)      MonthlyRecurrence: 需要指定MonthsOfYear, Days, 可描述每X1,X2,X3…月的Y1,Y2,Y3, 开始时间执行的任务计划.

    5)      MonthlyDOWRecurrence: 需要指定MonthsOfYear, DaysOfWeek, WhichWeek(可选), 可描述 X1,X2,X3…月的第Y星期的星期Z1,Z2,Z3…开始时间执行的任务计划.

     

    值得注意的是,目前Reporting Services2000 SP2 仍然存在序列化任务计划的XML存在与Reporing Services APIWhichWeek定义不一致的情况, 需要进行如下处理:

    private XmlDocument GetScheduleAsXml(ScheduleDefinition schedule)

                       {

                                MemoryStream buffer = new MemoryStream();

                                XmlSerializer xmlSerializer = new XmlSerializer(typeof(ScheduleDefinition));

                                xmlSerializer.Serialize(buffer, schedule);

                                buffer.Seek(0, SeekOrigin.Begin);

                       

                                XmlDocument doc = new XmlDocument();       

                                doc.Load(buffer); 

                                // patch up WhichWeek

                                XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);

                                nsmgr.AddNamespace("rp","http://schemas.microsoft.com/sqlserver/2003/12/reporting/reportingservices");

                                XmlNode node =

    doc.SelectSingleNode("/ScheduleDefinition/rp:MonthlyDOWRecurrence/rp:WhichWeek", nsmgr);

                                if(node != null)

                                {

                                         switch (node.InnerXml)

                                         {

                                                   case "FirstWeek":

                                                            node.InnerXml = "FIRST_WEEK"; break;

                                                   case "SecondWeek":

                                                            node.InnerXml = "SECOND_WEEK"; break;

                                                   case "ThirdWeek":

                                                            node.InnerXml = "THIRD_WEEK"; break;

                                                   case "FourthWeek":

                                                            node.InnerXml = "FOURTH_WEEK"; break;

                                                   case "LastWeek":

                                                            node.InnerXml = "LAST_WEEK"; break;

                                         }

                                }

                                return doc;

                       }

     

          SET UI FROM ScheduleDefinition

    为了为界面控件加载数据,首先需要将API返回的MachData反序列化ScheduleDefinition:

    private ScheduleDefinition GetScheduleFromXml (string sMatchData)

                       {

                                MemoryStream vStream =

     new MemoryStream(System.Text.Encoding.Default.GetBytes(sMatchData));

                                XmlAttributes attrs = new XmlAttributes();

     

                                attrs.XmlElements.Add(

    new XmlElementAttribute("MinuteRecurrence",typeof(MinuteRecurrence)));

                                attrs.XmlElements.Add(

    new XmlElementAttribute("DailyRecurrence",typeof(DailyRecurrence)));

                                attrs.XmlElements.Add(

    new XmlElementAttribute("WeeklyRecurrence",typeof(WeeklyRecurrence)));

                                attrs.XmlElements.Add(

    new XmlElementAttribute("MonthlyRecurrence",typeof(MonthlyRecurrence)));

                                attrs.XmlElements.Add(

    new XmlElementAttribute("MonthlyDOWRecurrence",typeof(MonthlyDOWRecurrence)));

                                XmlAttributeOverrides attrOver=new XmlAttributeOverrides();

     

                                attrOver.Add(typeof(ScheduleDefinition),"ScheduleDefinition",attrs);

                                XmlSerializer newSr=new XmlSerializer(typeof(ScheduleDefinition),attrOver);

     

                                return (ScheduleDefinition)newSr.Deserialize(vStream);

                       }

     

    根据GetScheduleFromXml返回的字符串,需要再次Patch WhichWeek

                         if(matchData.IndexOf("WhichWeek")>-1)

                                {

                                         if(matchData.IndexOf("FIRST_WEEK")>-1)

                                                   matchData=matchData.Replace("FIRST_WEEK","FirstWeek");

                                         if(matchData.IndexOf("SECOND_WEEK")>-1)

                                                   matchData=matchData.Replace("SECOND_WEEK","SecondWeek");

                                         if(matchData.IndexOf("THIRD_WEEK")>-1)

                                                   matchData=matchData.Replace("THIRD_WEEK","ThirdWeek");

                                         if(matchData.IndexOf("FOURTH_WEEK")>-1)

                                                   matchData=matchData.Replace("FOURTH_WEEK","FourthWeek");

                                         if(matchData.IndexOf("LAST_WEEK")>-1)

                                                   matchData=matchData.Replace("LAST_WEEK","LastWeek");

                                }

    最后根据ScheduleDefinitionItem类型设置重复规则控件

    switch(_ScheduleDefinition.Item.GetType().Name)

    {

           case "MinuteRecurrence":

                  SET_MINUTE_CONTROL;

                  break;

           case ….

    }

     


    最新回复(0)