none
Micorosoft Reportの複数列の設定を後で変更したい RRS feed

  • 質問

  • VisualStudio2015で、Micorosoft Reportから、エーワンとかコクヨとかの2列×5段のラベルに印刷できるものを作りたいと思っています。
    主にExcelで作った表を取り込んで、ラベル出力ができるようにしたくて、ClosedXMLというライブラリを使って取り込んでDataSetにコピーして、Reportのデータソースにしています。

    デザイナから、レポートのColumnsを2にして、本文のSizeを変更したら、それらしきデザインができるのですが、これを後で、プログラム(C#)から設定したいのですが、やり方がわかりません。やりたいのは、Sizeプロパティ(WidthとHeight)とColumnsプロパティのColumnSpacingです。MSDNライブラリを結構探し回ったのですが、Columnsプロパティ自体がMicrosoft.Reporting.ReportingServices.ReportRendering.Reportにはあるようですが、私がやりたいのはサーバーレポートではなくてローカルレポートなので、当てはまりません。

    ライブラリ内をくまなく探したらわかるのかもしれませんが、ご存知の方いらっしゃたら教えてもらえませんか?

    2017年6月10日 16:07

回答

  • RDLCファイルはXML形式で記述されているので、XMLを書き換えてやれば変更できます。
    書き換える場所は仕様書から探すか、デザイナで変更してみて変化した個所を探すなりしてください。

    using System;
    using System.Data;
    using System.Windows.Forms;
    
    namespace ReportsApplication1
    {
        public partial class Form1 : Form
        {
            Microsoft.Reporting.WinForms.ReportViewer viewer;
            public Form1()
            {
                InitializeComponent();
    
                viewer = new Microsoft.Reporting.WinForms.ReportViewer();
                viewer.Dock = DockStyle.Fill;
                this.Controls.Add(viewer);
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                string dir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                string rdlcFile = System.IO.Path.Combine(dir, "Report1.rdlc");
                if (!System.IO.File.Exists(rdlcFile))
                {
                    MessageBox.Show("実行ファイルと同じディレクトリにReport1.rdlcが見つかりませんでした");
                }
    
                //RDLCファイルをXMLファイルとして読み込む
                using (System.IO.Stream fs = System.IO.File.OpenRead(rdlcFile))
                {
                    System.IO.Stream  streamModified = RDLCTool.SetReportColumns(fs, 3, 0.5);
    
                    //変更を適用したRDLCを読み込む
                    this.viewer .LocalReport.LoadReportDefinition(streamModified);
                }
                
                //レポートのデータソース設定
                DataTable dt=new DataTable();
                dt.Columns.Add(new DataColumn("DataColumn1", typeof(string)));
                for(int i=0;i<100;i++)
                {
                    System.Data.DataRow row= dt.NewRow();
                    row[0]="Data"+i.ToString();
                    dt.Rows.Add(row);
                }
                this.viewer.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", dt));
    
                //ReportViewer表示更新
                this.viewer.SetDisplayMode(Microsoft.Reporting.WinForms.DisplayMode.PrintLayout);
                this.viewer.RefreshReport();
            }
        }
    
    
        class RDLCTool
        {
            public static System.IO.Stream SetReportColumns(System.IO.Stream rdlcFile, int columns, double columnSpacingMM)
            {
                if (columns <= 0) { throw new ArgumentException("columns"); }
                if (columnSpacingMM < 0) { throw new ArgumentException("columnSpacingMM"); };
    
                System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                doc.Load(rdlcFile);
    
                string xmlns = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition";
                System.Xml.XmlNamespaceManager manager = new System.Xml.XmlNamespaceManager(doc.NameTable);
                manager.AddNamespace("q", xmlns);
    
                //<Report><Page><Columns>列数</Columns></Page></Report>を検索
                System.Xml.XmlNode nodePage = doc.SelectSingleNode("q:Report/q:Page", manager);
                System.Xml.XmlNode nodeColumns = nodePage.SelectSingleNode("q:Columns", manager);
                if (nodeColumns == null)
                {
                    //設定が無い場合はノードを追加
                    nodeColumns = doc.CreateNode(System.Xml.XmlNodeType.Element, "Columns", xmlns);
                    nodePage.AppendChild(nodeColumns);
                }
    
                //<Report><Page><ColumnSpacing>列の隙間</ColumnSpacing></Page></Report>を検索
                System.Xml.XmlNode nodeSpacing = nodePage.SelectSingleNode("q:ColumnSpacing", manager);
                if (nodeSpacing == null)
                {
                    nodeSpacing = doc.CreateNode(System.Xml.XmlNodeType.Element, "ColumnSpacing", xmlns);
                    nodePage.AppendChild(nodeSpacing);
                }
    
                //設定を書き換える
                nodeColumns.InnerText = columns.ToString();
                nodeSpacing.InnerText = columnSpacingMM.ToString() + "mm";//単位をつけて。cmやインチ(in)でも可能だけど判り易くmm
    
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                doc.Save(ms);
                ms.Position = 0;
                return ms;
            }
        }
    }
    Imports System
    Imports System.Data
    Imports System.Windows.Forms
    
    Namespace ReportsApplication1
    
        Partial Public Class Form1
            Inherits Form
    
            Private viewer As Microsoft.Reporting.WinForms.ReportViewer
    
            Public Sub New()
                InitializeComponent()
    
                viewer = New Microsoft.Reporting.WinForms.ReportViewer()
                viewer.Dock = DockStyle.Fill
                Me.Controls.Add(viewer)
            End Sub
    
            Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) handles Me.Load
                Dim dir As String = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
                Dim rdlcFile As String = System.IO.Path.Combine(dir, "Report1.rdlc")
                If Not (System.IO.File.Exists(rdlcFile)) Then
                    MessageBox.Show("実行ファイルと同じディレクトリにReport1.rdlcが見つかりませんでした")
                End If
    
                Using fs As System.IO.Stream = System.IO.File.OpenRead(rdlcFile)
                    Dim streamModified As System.IO.Stream = RDLCTool.SetReportColumns(fs, 3, 0.5)
                    Me.viewer.LocalReport.LoadReportDefinition(streamModified)
                End Using
    
                'レポートのデータソース設定
                Dim dt As DataTable = New DataTable()
                dt.Columns.Add(New DataColumn("DataColumn1", GetType(String)))
    
                For i As Integer = 0 To 100
                    Dim row As System.Data.DataRow = dt.NewRow()
                    row(0) = "Data" + i.ToString()
                    dt.Rows.Add(row)
                Next
    
                Me.viewer.LocalReport.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", dt))
                Me.viewer.SetDisplayMode(Microsoft.Reporting.WinForms.DisplayMode.PrintLayout)
                Me.viewer.RefreshReport()
            End Sub
        End Class
    
        Friend Class RDLCTool
    
            Public Shared Function SetReportColumns(ByVal rdlcFile As System.IO.Stream, ByVal columns As Integer, ByVal columnSpacingMM As Double) As System.IO.Stream
                If columns <= 0 Then
                    Throw New ArgumentException("columns")
                End If
    
                If columnSpacingMM < 0 Then
                    Throw New ArgumentException("columnSpacingMM")
                End If
    
                Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument()
                doc.Load(rdlcFile)
                Dim xmlns As String = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition"
                Dim manager As System.Xml.XmlNamespaceManager = New System.Xml.XmlNamespaceManager(doc.NameTable)
                manager.AddNamespace("q", xmlns)
                '<Report><Page><Columns>列数</Columns></Page></Report>を検索
                Dim nodePage As System.Xml.XmlNode = doc.SelectSingleNode("q:Report/q:Page", manager)
                Dim nodeColumns As System.Xml.XmlNode = nodePage.SelectSingleNode("q:Columns", manager)
                If nodeColumns Is Nothing Then
                    nodeColumns = doc.CreateNode(System.Xml.XmlNodeType.Element, "Columns", xmlns)
                    nodePage.AppendChild(nodeColumns)
                End If
    
                '<Report><Page><ColumnSpacing>列の隙間</ColumnSpacing></Page></Report>を検索
                Dim nodeSpacing As System.Xml.XmlNode = nodePage.SelectSingleNode("q:ColumnSpacing", manager)
                If nodeSpacing Is Nothing Then
                    nodeSpacing = doc.CreateNode(System.Xml.XmlNodeType.Element, "ColumnSpacing", xmlns)
                    nodePage.AppendChild(nodeSpacing)
                End If
    
                nodeColumns.InnerText = columns.ToString()
                nodeSpacing.InnerText = columnSpacingMM.ToString() + "mm"
                Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream()
                doc.Save(ms)
                ms.Position = 0
                Return ms
            End Function
        End Class
    End Namespace
    

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク Takuya1971 2017年6月11日 4:15
    2017年6月10日 20:10

すべての返信

  • RDLCファイルはXML形式で記述されているので、XMLを書き換えてやれば変更できます。
    書き換える場所は仕様書から探すか、デザイナで変更してみて変化した個所を探すなりしてください。

    using System;
    using System.Data;
    using System.Windows.Forms;
    
    namespace ReportsApplication1
    {
        public partial class Form1 : Form
        {
            Microsoft.Reporting.WinForms.ReportViewer viewer;
            public Form1()
            {
                InitializeComponent();
    
                viewer = new Microsoft.Reporting.WinForms.ReportViewer();
                viewer.Dock = DockStyle.Fill;
                this.Controls.Add(viewer);
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                string dir = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
                string rdlcFile = System.IO.Path.Combine(dir, "Report1.rdlc");
                if (!System.IO.File.Exists(rdlcFile))
                {
                    MessageBox.Show("実行ファイルと同じディレクトリにReport1.rdlcが見つかりませんでした");
                }
    
                //RDLCファイルをXMLファイルとして読み込む
                using (System.IO.Stream fs = System.IO.File.OpenRead(rdlcFile))
                {
                    System.IO.Stream  streamModified = RDLCTool.SetReportColumns(fs, 3, 0.5);
    
                    //変更を適用したRDLCを読み込む
                    this.viewer .LocalReport.LoadReportDefinition(streamModified);
                }
                
                //レポートのデータソース設定
                DataTable dt=new DataTable();
                dt.Columns.Add(new DataColumn("DataColumn1", typeof(string)));
                for(int i=0;i<100;i++)
                {
                    System.Data.DataRow row= dt.NewRow();
                    row[0]="Data"+i.ToString();
                    dt.Rows.Add(row);
                }
                this.viewer.LocalReport.DataSources.Add(new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", dt));
    
                //ReportViewer表示更新
                this.viewer.SetDisplayMode(Microsoft.Reporting.WinForms.DisplayMode.PrintLayout);
                this.viewer.RefreshReport();
            }
        }
    
    
        class RDLCTool
        {
            public static System.IO.Stream SetReportColumns(System.IO.Stream rdlcFile, int columns, double columnSpacingMM)
            {
                if (columns <= 0) { throw new ArgumentException("columns"); }
                if (columnSpacingMM < 0) { throw new ArgumentException("columnSpacingMM"); };
    
                System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
                doc.Load(rdlcFile);
    
                string xmlns = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition";
                System.Xml.XmlNamespaceManager manager = new System.Xml.XmlNamespaceManager(doc.NameTable);
                manager.AddNamespace("q", xmlns);
    
                //<Report><Page><Columns>列数</Columns></Page></Report>を検索
                System.Xml.XmlNode nodePage = doc.SelectSingleNode("q:Report/q:Page", manager);
                System.Xml.XmlNode nodeColumns = nodePage.SelectSingleNode("q:Columns", manager);
                if (nodeColumns == null)
                {
                    //設定が無い場合はノードを追加
                    nodeColumns = doc.CreateNode(System.Xml.XmlNodeType.Element, "Columns", xmlns);
                    nodePage.AppendChild(nodeColumns);
                }
    
                //<Report><Page><ColumnSpacing>列の隙間</ColumnSpacing></Page></Report>を検索
                System.Xml.XmlNode nodeSpacing = nodePage.SelectSingleNode("q:ColumnSpacing", manager);
                if (nodeSpacing == null)
                {
                    nodeSpacing = doc.CreateNode(System.Xml.XmlNodeType.Element, "ColumnSpacing", xmlns);
                    nodePage.AppendChild(nodeSpacing);
                }
    
                //設定を書き換える
                nodeColumns.InnerText = columns.ToString();
                nodeSpacing.InnerText = columnSpacingMM.ToString() + "mm";//単位をつけて。cmやインチ(in)でも可能だけど判り易くmm
    
                System.IO.MemoryStream ms = new System.IO.MemoryStream();
                doc.Save(ms);
                ms.Position = 0;
                return ms;
            }
        }
    }
    Imports System
    Imports System.Data
    Imports System.Windows.Forms
    
    Namespace ReportsApplication1
    
        Partial Public Class Form1
            Inherits Form
    
            Private viewer As Microsoft.Reporting.WinForms.ReportViewer
    
            Public Sub New()
                InitializeComponent()
    
                viewer = New Microsoft.Reporting.WinForms.ReportViewer()
                viewer.Dock = DockStyle.Fill
                Me.Controls.Add(viewer)
            End Sub
    
            Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) handles Me.Load
                Dim dir As String = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
                Dim rdlcFile As String = System.IO.Path.Combine(dir, "Report1.rdlc")
                If Not (System.IO.File.Exists(rdlcFile)) Then
                    MessageBox.Show("実行ファイルと同じディレクトリにReport1.rdlcが見つかりませんでした")
                End If
    
                Using fs As System.IO.Stream = System.IO.File.OpenRead(rdlcFile)
                    Dim streamModified As System.IO.Stream = RDLCTool.SetReportColumns(fs, 3, 0.5)
                    Me.viewer.LocalReport.LoadReportDefinition(streamModified)
                End Using
    
                'レポートのデータソース設定
                Dim dt As DataTable = New DataTable()
                dt.Columns.Add(New DataColumn("DataColumn1", GetType(String)))
    
                For i As Integer = 0 To 100
                    Dim row As System.Data.DataRow = dt.NewRow()
                    row(0) = "Data" + i.ToString()
                    dt.Rows.Add(row)
                Next
    
                Me.viewer.LocalReport.DataSources.Add(New Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", dt))
                Me.viewer.SetDisplayMode(Microsoft.Reporting.WinForms.DisplayMode.PrintLayout)
                Me.viewer.RefreshReport()
            End Sub
        End Class
    
        Friend Class RDLCTool
    
            Public Shared Function SetReportColumns(ByVal rdlcFile As System.IO.Stream, ByVal columns As Integer, ByVal columnSpacingMM As Double) As System.IO.Stream
                If columns <= 0 Then
                    Throw New ArgumentException("columns")
                End If
    
                If columnSpacingMM < 0 Then
                    Throw New ArgumentException("columnSpacingMM")
                End If
    
                Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument()
                doc.Load(rdlcFile)
                Dim xmlns As String = "http://schemas.microsoft.com/sqlserver/reporting/2008/01/reportdefinition"
                Dim manager As System.Xml.XmlNamespaceManager = New System.Xml.XmlNamespaceManager(doc.NameTable)
                manager.AddNamespace("q", xmlns)
                '<Report><Page><Columns>列数</Columns></Page></Report>を検索
                Dim nodePage As System.Xml.XmlNode = doc.SelectSingleNode("q:Report/q:Page", manager)
                Dim nodeColumns As System.Xml.XmlNode = nodePage.SelectSingleNode("q:Columns", manager)
                If nodeColumns Is Nothing Then
                    nodeColumns = doc.CreateNode(System.Xml.XmlNodeType.Element, "Columns", xmlns)
                    nodePage.AppendChild(nodeColumns)
                End If
    
                '<Report><Page><ColumnSpacing>列の隙間</ColumnSpacing></Page></Report>を検索
                Dim nodeSpacing As System.Xml.XmlNode = nodePage.SelectSingleNode("q:ColumnSpacing", manager)
                If nodeSpacing Is Nothing Then
                    nodeSpacing = doc.CreateNode(System.Xml.XmlNodeType.Element, "ColumnSpacing", xmlns)
                    nodePage.AppendChild(nodeSpacing)
                End If
    
                nodeColumns.InnerText = columns.ToString()
                nodeSpacing.InnerText = columnSpacingMM.ToString() + "mm"
                Dim ms As System.IO.MemoryStream = New System.IO.MemoryStream()
                doc.Save(ms)
                ms.Position = 0
                Return ms
            End Function
        End Class
    End Namespace
    

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    • 回答としてマーク Takuya1971 2017年6月11日 4:15
    2017年6月10日 20:10
  • xmlを書き換えるとできるのですね。
    実力的にハードルがちょっと高いですが(xmlはさわったことがない、というか避けてきた!!)、勉強がてらやってみます。
    rdlcファイルをテキストで開いてみたら、述べられているようにラベルのHeight, Width, ColumnSpacingのタグが見つかりました。SetReportColumnsのところを改変してやってみます。

    2017年6月11日 4:29