IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Récupérer la requête d'un DataSource depuis un RLDC, lui passer des paramètres, et l'exécuter


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut Récupérer la requête d'un DataSource depuis un RLDC, lui passer des paramètres, et l'exécuter
    Bonjour,

    Je travaille sur une librairie qui puisse permettre, depuis une page ASPX, de générer à la volée un document PDF en lui passant en paramètre :
    - Une série de paramètres
    - Le nom d'un rapport RDLC ou RDL présent sur le serveur

    Pour le moment, j'ai fait un truc qui marche plutôt pas mal, mais il est à mon avis largement perfectible.

    Le code en l'état :

    PageRDLtoPDF.aspx
    Code html : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    <%@ Page Language="C#" AutoEventWireup="true" Inherits="CustomPages.PageRDLtoPDF" %>

    PageRDLtoPDF.aspx.cs
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    using My.Editions;
    using System;
    using System.IO;
    using update.Web.Pages;
     
    namespace CustomPages
    {
        public class PageRDLtoPDF : BasePage
        {
            public PageRDLtoPDF()
            {
            }
     
            protected void Page_Load(object sender, EventArgs e)
            {
                Response.Clear();
                Response.ContentType = "application/pdf";
                IniFile iniFile = new IniFile(Server.MapPath("~/system/sys/mmdb.ini"));
                MemoryStream memoryStream = new MemoryStream();
                RDLtoPDF edition = new RDLtoPDF(iniFile.keys["CnxString"], iniFile.keys["TblPrefix"], Server.MapPath("~/"), Request.Form["Records"], Request.Form["ReportName"]);
                edition.Edition(memoryStream);
                memoryStream.WriteTo(Response.OutputStream);
                Response.Flush();
                Response.Close();
                Response.End();
            }
        }
    }

    RDLtoPDF.cs
    Code csharp : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    using System.Collections.Generic;
    using System.Data;
    using System.Data.Odbc;
    using System.IO;
    using Microsoft.Reporting.WinForms;
     
    namespace My.Editions
    {
        public class RDLtoPDF : IEdition
        {
            private readonly string CnxString;
            private readonly string TblPrefix;
            private readonly string Path;
            private readonly string ReportName;
            private readonly string RecordsId;
     
            public RDLtoPDF(string cnxString, string tblPrefix, string path, string recordsId, string reportName)
            {
                CnxString = cnxString;
                TblPrefix = tblPrefix;
                Path = path;
                ReportName = $"{Path}\\my_ssrs\\{reportName}";
                RecordsId = recordsId;
            }
     
            public void Edition(Stream output)
            {
                if (RecordsId.Length > 0)
                {
                    using (OdbcConnection cnx = new OdbcConnection(CnxString))
                    {
                        cnx.Open();
                        using (OdbcCommand cmd = cnx.CreateCommand())
                        {
                            ReportViewer viewer = new ReportViewer();
                            viewer.LocalReport.Refresh();
                            viewer.LocalReport.ReportPath = ReportName;
     
                            IList<string> Queries = viewer.LocalReport.GetDataSourceNames();
     
                            cmd.CommandTimeout = 120;
     
                            foreach (string query in Queries)
                            {
                                cmd.CommandText = string.Format(File.ReadAllText(string.Concat($"{Path}\\my_ssrs\\{query}.sql")), TblPrefix, RecordsId);
                                cmd.Prepare();
                                DataSet ds = new DataSet();
                                OdbcDataAdapter da = new OdbcDataAdapter(cmd);
                                da.Fill(ds);
     
                                ReportDataSource rds = new ReportDataSource(query, ds.Tables[0]);
                                viewer.LocalReport.DataSources.Add(rds);
                            }
     
                            viewer.LocalReport.SubreportProcessing += LocalReport_SubreportProcessing;
     
                            byte[] bytes = viewer.LocalReport.Render("PDF", null, out string mimeType, out string encoding, out string extension, out string[] streamIds, out Warning[] warnings);
                            output.Write(bytes, 0, bytes.Length);
                        }
                        cnx.Close();
                    }
                }
            }
     
            private void LocalReport_SubreportProcessing(object sender, SubreportProcessingEventArgs e)
            {
                using (OdbcConnection cnx = new OdbcConnection(CnxString))
                {
                    cnx.Open();
                    using (OdbcCommand cmd = cnx.CreateCommand())
                    {
                        foreach (ReportParameterInfo p in e.Parameters)
                        {
                            cmd.Parameters.AddWithValue(p.Name, p.Values[0]);
                        }
     
                        foreach (string query in e.DataSourceNames)
                        {
                            cmd.CommandText = string.Format(File.ReadAllText(string.Concat($"{Path}\\my_ssrs\\{query}.sql")), TblPrefix);
                            cmd.Prepare();
                            DataSet ds = new DataSet();
                            OdbcDataAdapter da = new OdbcDataAdapter(cmd);
                            da.Fill(ds);
                            ReportDataSource rds = new ReportDataSource(query, ds.Tables[0]);
                            e.DataSources.Add(rds);
                        }
                    }
                    cnx.Close();
                }
            }
        }
    }

    La partie sur les sous-rapport, pour le moment je ne l'ai pas testée.
    En revanche, le reste fonctionne.

    Si j'ai un rapport avec 3 datasource, ma page arrive à retrouver le nom de ces trois datasource, ainsi que les paramètres.

    En revanche, je n'arrive pas à récupérer le SQL des datasources présents dans le rapport.
    Du coup je suis obligé de passer par des fichiers SQL stockés à côté, portant le nom des datasets.

    C'est un peu crade, et j'aimerais plutôt récupérer les requêtes telles qu'existantes dans le rapport.

    Avez-vous une idée de comment faire ?

    Autre solution, mais pas forcément meilleure pour moi : exécuter directement le rapport en lui passant les paramètres, sans avoir à me soucier de la liaison aux données.
    Seul hic, entre DEV, TEST et PROD ça m'obligerait à maintenir 3 versions différentes des mêmes rapports, ce qui ne me semble pas terrible !
    (Là, je retrouve la chaîne de connexion à la base à partir d'un fichier INI trouvé dans un dossier de l'application appelante).

  2. #2
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2007
    Messages
    8
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 8
    Par défaut
    Bonjour,

    J'espère ne pas dire de bêtises et avoir bien compris ta question qui est simplement de savoir comment récupérer les requêtes SQL des Datasources présents dans ton (ou tes) rapport(s).

    De ce que j'ai pu voir de ton code, outre le fait que tes requêtes soient présente sous forme de fichier sur ton serveur, ta solution utilisée n'est pas mauvaise.
    Il est certain (à mon sens, mais je peux me tromper) que tes rapports ne connaissent pas du tout les requêtes qui doivent permettre le chargement de leurs Datasources car ces dernier ne sont implémenter que lorsque tu leur renseigne le Dataset déjà précharger (la requête est déjà exécuter à ce moment et seules les données sont envoyées au datasource. je me trompe ?

    De ce fait, a part peut-être continuer à utiliser tes fichiers INI, ou alors à mettre ton SQL en dur dans une ressource dédiée du projet, ou encore à créer des procédures stockées directement dans ta base de données, je pense que ton raisonnement n'est pas mauvais, en utilisant un identificateur commun entre la requête et le nom du datasource de chaque rapport.

    ...et si, en fait, je n'ai pas compris ta question originel... DSL pour ce blabla inutile ;-)

    bonne journée

  3. #3
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 197
    Billets dans le blog
    1
    Par défaut
    Bonjour fox15145,

    En fait, les fichier RDLC contiennent les requêtes qui ont été utilisées lors de l'élaboration des fichiers dans le designer, et qui sont utilisées lorsqu'on fait une preview dans ce dernier.

    Par contre, je n'arrive pas à les retrouver dans l'objet.

    C'est pour cette raison que j'ai été obligé de les dupliquer dans des fichiers qui se baladent dans le même dossier.

    Outre les soucis de nommage et de maintenance des fichiers, je trouve ça très moyen comme solution "finale".

    Je cherche donc un moyen d'interroger le RDLC pour qu'il me communique la requête SQL utilisée.

    Dans le pire des cas, dans un éclair de lucidité ce week-end je me suis dit qu'il me suffit de parser le fichier (c'est du XML) mais bon, ce serait quand même plus propre de passer par la librairie...

Discussions similaires

  1. [AC-2007] passer des paramètres à une requête en VBA
    Par symbabeauchat dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 08/11/2011, 22h38
  2. Comment passer des paramètres dans une requête XPATH
    Par SyLvErStOrM dans le forum BIRT
    Réponses: 18
    Dernier message: 29/04/2011, 11h08
  3. Réponses: 3
    Dernier message: 05/08/2009, 19h53
  4. passer des paramétres d'un formulaire à une requête
    Par lasmarmann dans le forum Access
    Réponses: 1
    Dernier message: 24/10/2006, 09h37
  5. Réponses: 1
    Dernier message: 21/03/2006, 14h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo