zoukankan      html  css  js  c++  java
  • 水晶报表使用,解决相同数据库不同服务器使用同一个水晶报表模板问题?

          在使用asp.net时,做ERP系统时,水晶报表是经常被使用的,在asp.net 上有水晶报表的控件,那个网上有很多,这里就不多讲了,水晶报表有两种模式即push模式和pull模式,pull模式是:使用设计报表时的链接数据库驱动获取打印表格,这个不需要写sql语句,代码量非常少,push模式即自己构造需要sql语句,代码量大,扩展报表的功能。

           在一次项目中,我遇到需要使用水晶报表的api,这里水晶报表主要使用的api是:

        using CrystalDecisions.CrystalReports.Engine;
        using CrystalDecisions.ReportSource;
        using CrystalDecisions.Shared;

          有经验的知道打印报表需要使用Engine.ReportDocument.setdatabaseLogon(string,string,string,string);这只是其中的一个重载。这就是配置pull模式,设计连接的数据库。但是在下遇到了一个需求是:有个水晶报表模板,比如说是在A数据库上设计的,但是B服务器有一个和A服务器一样的数据库结构,为了以后维护客户资料方便,必须实现更改配置实现,水晶模板在两个A、B之间的切换,但是水晶报表模板不变。

         分析:这个需求显然是你不能使用sql语句进行push模式的操作。但是使用上面给出的api配置发现,直接报错:database log error;这个是我很是纠结,但是这个功能必须要实现,我也在网上找了很多资料,没有合理的解决。

         我的分析(不对的地方请指正),我想这个配置服务器的函数内部是怎么实现的呢,我在网上找了一个C# 反编译工具,进行查看,看看Sap公司在里面封装了何方神圣。我把图片贴出来方便大家理解:首先找到这个api函数,也就是CrystalDecisions.CrystalReports.Engine-》ReportDocument-》setdatabaseLogon。

             可以看到里面有个调用自身。继续往下面走,就发现:

          调用了一个表格登录,这是什么东西,莫着急,继续点击往下看。

       

    到这里你应该明白了,原来这个登录数据库设置是在pull模式下,调用了默认的数据库服务器名和数据库,这也就明白了为什么在函数setdatabaselogon();上更改服务器名,虽然数据库一样,提示登录数据库失败的原因。

    说了这么多,问题的根源终于找到了,但是怎么解决呢,这才是重点,从第三个图中可以看出它是 把信息应用到没哟个数据中,既然这样我们可以模仿他的方法进行重写自己的链接数据。

           

     1   #region 转换服务器连接
     2             ConnectionInfo connectinfo = new ConnectionInfo()
     3                {
     4                    ServerName = sqlhelper.CrystalStrServer,
     5                    DatabaseName = sqlhelper.CrystalDatabase,
     6                    UserID = sqlhelper.CrystalStrUser,
     7                    Password = sqlhelper.CrystalStrPwd
     8                };
     9             foreach (CrystalDecisions.CrystalReports.Engine.Table tb1 in rd.Database.Tables)
    10             {
    11                 tb1.LogOnInfo.ConnectionInfo = connectinfo;
    12                 tb1.ApplyLogOnInfo(tb1.LogOnInfo);
    13             }

    这个代码使用可以解决你的问题,但是它会出现一点小BUG。什么bug呢,当你使用更改配置后假设使用A,使用默认水晶报表下载,下载的数据仍然是B的数据。怎么办呢,不要着急,在加一行代码就可以搞定了。

     CrystalDecisions.CrystalReports.Engine.ReportDocument rd = new ReportDocument();
                string rpt1 = Context.Server.MapPath("/CrystalReportsPath/" + StrGuid.Trim() + reportPath);
                rd.Load(rpt1);
    
                #region 转换服务器连接
                ConnectionInfo connectinfo = new ConnectionInfo()
                   {
                       ServerName = sqlhelper.CrystalStrServer,
                       DatabaseName = sqlhelper.CrystalDatabase,
                       UserID = sqlhelper.CrystalStrUser,
                       Password = sqlhelper.CrystalStrPwd
                   };
                foreach (CrystalDecisions.CrystalReports.Engine.Table tb1 in rd.Database.Tables)
                {
                    tb1.LogOnInfo.ConnectionInfo = connectinfo;
                    tb1.ApplyLogOnInfo(tb1.LogOnInfo);
                }
                //一定要刷新
                rd.Refresh();
                #endregion
    

      到这里问题就解决了。

  • 相关阅读:
    WinForm 防止因为各种因素的操作导致主窗体冻结、卡死的解决方法
    winform常用知识点
    数字金额转为大写金额(C#)
    中关村网站产品参数页的参数纠错的制作
    牛腩自制TXT文本分割工具
    delphi连接SQL2005做的数据库管理系统的一些部署问题
    我的WIN7 RC+汉化安装步骤
    求一整数的所有拆分方式
    全角字符与半角字符的相互转换(C#)
    一道.NET题
  • 原文地址:https://www.cnblogs.com/fandong90/p/4933916.html
Copyright © 2011-2022 走看看