GrapeCity ActiveReports for .NET 14.0J
カスタムデータプロバイダ
ActiveReportsユーザーガイド > サンプルとチュートリアル > チュートリアル > ページレポート/RDLレポートのチュートリアル > カスタマイズ > カスタムデータプロバイダ

ページレポート/RDLレポートでは、カスタムデータプロバイダを使用し、実行時と設計時に正規以外のデータソースを使用することができます。このチュートリアルでは、カスタムデータプロバイダを使用したプロジェクトのソリューションを作成し、CSVファイルからデータを取得する方法を紹介します。

このトピックでは、以下のタスクを行います。

このチュートリアルを完了すると、CSVファイルから取得したデータを読み込んだレポートがデザイナ上に表示されます。

カスタムデータプロバイダのためのデザイナプロジェクトを作成する

  1. Visual Studioでは、Windowsフォームプロジェクトを作成し、名前を「CustomDataProviderDemo」に変更します。
  2. Visual Studioのツールボックスの[ActiveReports 14ページ]タブから[ReportExplorer]をドラッグし、デフォルトのWindowsフォーム上にドロップし、フォームのサイズを使いやすい大きさに変更します。
  3. [プロパティ]ウィンドウから、ReportExplorerのDockプロパティをLeftに設定します。
  4. 通常のツールボックスから[RichTextBox]コントロールをフォーム上にドラッグし、Dockプロパティを「Topに設定します。
  5. Textプロパティに以下のテキストを追加します(テキストボックスをドロップダウンし、テキスト全体が追加されたかを確認してください)。
    テキスト(RichTextBoxのTextプロパティに貼り付けます)
    コードのコピー
    1.レポートエクスプローラでは、データソースノードを右クリックし、[データソースの追加]を選択します。
    2.[レポートデータソース]ダイアログでは、全般のページに2つの種類ボックスをドロップダウンし、CSV Data Providerを選択してOKをクリックします。
    3.レポートエクスプローラで、DataSource1を右クリックし、[データセットの追加]を選択します。
    4.表示されるダイアログでは、クエリのページを選択します。
    5.クエリボックスをドロップダウンし、カスタムクエリエディタを表示します。
    6.CSVファイルの選択ボタンをクリックし、このプロジェクトにCategories.csvファイルを開きます。
    7.OKをクリックして設定を保存し、ダイアログを閉じます。
    8.プレビューをクリックし、CSVから取得したデータのレポートを表示します。
    
  6. Visual Studioのツールボックスの[ActiveReports 14ページ]タブから[Designer]コントロールをフォーム上の空いている部分にドラッグします。
  7. DockプロパティをFillに設定し、[Designer]コントロールを右クリックし、「最前面へ移動」を選択します。
  8. [ReportExplorer]コントロールを選択し、[プロパティ]ウィンドウからReportDesignerプロパティをドロップダウンし、Designer1を選択します。
  9. フォームのタイトルバーをダブルクリックし、Form Loadイベントのイベント処理メソッドを作成し、以下のコードを追加します。

    Visual Basic

    Visual Basicコード(クラスの上貼り付けます)
    コードのコピー
    Imports System.Xml
    Imports System.IO
    Imports GrapeCity.ActiveReports.Design
    

    C#

    C#コード(クラスの上貼り付けます)
    コードのコピー
    using System.Xml;
    using System.IO;
    using GrapeCity.ActiveReports.Design;
    
  10. Form Loadイベントに以下のコードを追加します。

    Visual Basic

    Visual Basicコード(Form_Loadイベント内に貼り付けます)
    コードのコピー
    Using reportStream = File.OpenRead("DemoReport.rdlx")
            Using reader = XmlReader.Create(reportStream)
                    Designer1.LoadReport(reader, DesignerReportType.Page)
            End Using
    End Using
    

    C#

    C#コード(Form_Loadイベント内に貼り付けます)
    コードのコピー
    using (var reportStream = File.OpenRead("DemoReport.rdlx"))
     {
         using (var reader = XmlReader.Create(reportStream))
          {
             designer1.LoadReport(reader, DesignerReportType.Page);
          }
     }
    

カスタムデータプロバイダを使用するためのプロジェクトを作成する

  1. ソリューションエクスプローラーから、プロジェクトを右クリックし、[追加]を選択した後、[新しい項目]を選択します。
  2. 表示されるダイアログでは、[テキストファイル]を選択し、ファイル名を[GrapeCity.ActiveReports.config]に変更し、[追加]をクリックします。 
  3. ソリューションエクスプローラーから、GrapeCity.ActiveReports.configを選択し、[プロパティ]ウィンドウから「出力ディレクトリにコピー」常にコピーするに設定します。
  4. 以下のテキストをファイルに貼り付けて保存します('Configuration' 要素が宣言されていません。と言う警告が表示されますが、無視してください)。
    Configファイルに貼り付けます
    コードのコピー
    <?xml version="1.0" encoding="utf-8" ?>
    <Configuration>
      <Extensions>
        <Data>
          <Extension Name="CSV" DisplayName="CSV Data Provider" 
            Type="CustomDataProvider.CsvDataProvider.CsvDataProviderFactory, 
              CustomDataProvider" 
              CommandTextEditorType="CustomDataProvider.CSVDataProvider.QueryEditor, 
            CustomDataProvider"/>
        </Data>
         </Extensions>
    </Configuration>
    
  5. ソリューションエクスプローラーから、プロジェクトを右クリックし、[追加]を選択した後、[新しい項目]を選択します。
  6. 表示されるダイアログでは、[テキストファイル]を選択し、ファイル名を「Categories.csv」に変更し、[追加]をクリックします。 
  7. ソリューションエクスプローラーから、Categories.csvを選択し、[プロパティ]ウィンドウから「出力ディレクトリにコピー」常にコピーするに変更します。
  8. 以下のテキストをファイルに貼り付けて保存します。
    テキストファイルに貼り付けます
    コードのコピー
    EmployeeID(int32),LastName,FirstName,Role,City
    1,James,Yolanda,Owner,Columbus
    7,Reed,Marvin,Manager,Newton
    9,Figg,Murray,Cashier,Columbus
    12,Snead,Lance,Store Keeper,Columbus
    15,Halm,Jeffry,Store Keeper,Columbus
    17,Hames,Alma,Store Keeper,Oak Bay
    18,Nicki,Aubrey,Store Keeper,Columbus
    24,Cliett,Vikki,Store Keeper,Newton
    

データを表示するためのレポートを追加する

  1. ソリューションエクスプローラーから、プロジェクトを右クリックし、[追加]を選択した後、[新しい項目]を選択します。
  2. 表示されるダイアログでは、[ActiveReports 14.0J RDL レポート]を選択し、ファイル名を「DemoReport」に変更し、[追加]をクリックします。 (RDLレポートでは、すべてのデータは1ページに表示されます。)
  3. ソリューションエクスプローラーから、DemoReportを選択し、[プロパティ]ウィンドウから「出力ディレクトリにコピー」常にコピーするに設定します。
  4. ActiveReports 14のRDLレポートのツールボックスから[Table]データ領域をレポートにドラッグします。
    メモ: ページレポートを使用する場合には、1つのページにすべてのデータを表示するためにFixedSizeプロパティを設定する必要があります。
  5. [Table]をクリックし、左端に行ハンドルを表示します。フッタ行の左端にある行ハンドルを右クリックし、[行の削除]を選択し、[Table]からフッタ行を削除します。
  6. レポートエクスプローラでは、各テキストボックスを選択し、以下のようにプロパティを設定します。(レポートエクスプローラが表示されていない場合は、[表示]メニューから、[その他のウインドウ]を選択し、[ActiveReports 14.0Jレポートエクスプローラ]を選択します。) 
    テキストボックス名 背景色
    TextBox1 名前 MediumSlateBlue
    TextBox2 地位 MediumSlateBlue
    TextBox3 都市 MediumSlateBlue
    TextBox4 =Fields!FirstName.Value & " " & Fields!LastName.Value
    TextBox5 =Fields!Role.Value
    TextBox6 =Fields!City.Value
  7. レポートエクスプローラから、[Table1]ノードを選択し、[プロパティ]ウィンドウからLocationプロパティを「0in, 1in」Sizeプロパティを「6in, 0.5in」に設定し、すべてのデータが表示されるように幅を調整します。
  8. [Table1]ノードを選択し、[プロパティ]ウィンドウからDataSetNameプロパティに「DataSet1を入力します。

カスタムデータプロバイダを格納するためのクラスライブラリプロジェクトを追加する

  1. ファイルメニューから[追加]を選択し、[新しいプロジェクト]を選択します。
  2. [新しいプロジェクトの追加]ダイアログでは、[クラスライブラリ]を選択し、プロジェクト名を「CustomDataProvider」に変更します。
  3. ソリューションエクスプローラーから、デフォルトで作成されたクラスを右クリックし、[削除]を選択します。
  4. CustomDataProviderプロジェクトを右クリックし、[参照の追加]を選択します。[参照の追加]ダイアログでは.NETタブから以下の参照を選択します。
    • GrapeCity ActiveReports for .NET (GrapeCity.ActiveReports.v14)
    • GrapeCity ActiveReports Extensibility Library (GrapeCity.ActiveReports.Extensibility.v14)
    • System.Drawing
    • System.Windows.Forms
  5. CustomDataProviderプロジェクトを右クリックし、[追加]を選択します。[新しいフォルダー]を選択し、フォルダ名を「CSVDataProvider」に変更します。
  6. 追加したフォルダを右クリックし、[追加]を選択します。[クラス]を選択し、ファイル名を「CsvColumn」に変更します。デフォルトスタブを以下のコードに置き換えます。

    Visual Basic

    Visual Basic コード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    Namespace CSVDataProvider
           'データソース内のフィールドに関する情報を表します。
            Friend Structure CsvColumn
                    Private ReadOnly _fieldName As String
                    Private ReadOnly _dataType As Type
    
                    ' CsvColumnクラスの新しいインスタンスを生成します。
                      ' fieldNameはCsvColumnのインスタンスによって表されるフィールドの名前です。
                      ' dataTypeはCsvColumnのインスタンスによって表されるフィールドの種類です。
                      Public Sub New(fieldName As String, dataType As Type)
                            If fieldName Is Nothing Then
                                    Throw New ArgumentNullException("fieldName")
                            End If
                            If dataType Is Nothing Then
                                    Throw New ArgumentNullException("dataType")
                            End If
                            _fieldName = fieldName
                            _dataType = dataType
                    End Sub
    
    
                    ' CsvColumnのインスタンスによって表されるフィールドの名前を取得します。
                      Public ReadOnly Property FieldName() As String
                            Get
                                    Return _fieldName
                            End Get
                    End Property
    
    
                    ' CsvColumnのインスタンスによって表されるフィールドの種類を取得します。
                      Public ReadOnly Property DataType() As Type
                            Get
                                    Return _dataType
                            End Get
                    End Property
    
    
                    ' CsvColumnのインスタンスを表わす文字列を返します。
                      Public Overrides Function ToString() As String
                            Return [String].Concat(New String() {FieldName, "(", DataType.ToString(), ")"})
                    End Function
    
    
                    ' 2つのCsvColumnのインスタンスが同じかどうかを判定します。
                      ' 指定されたCsvColumnが現在のCsvColumnと同じである場合はTrueを返し、そうではない場合はFalseを返します。
                      Public Overrides Function Equals(obj As Object) As Boolean
                            Dim flag As Boolean
    
                            If TypeOf obj Is CsvColumn Then
                                    flag = Equals(CType(obj, CsvColumn))
                            Else
                                    flag = False
                            End If
                            Return flag
                    End Function
    
                    Private Overloads Function Equals(column As CsvColumn) As Boolean
                            Return column.FieldName = FieldName
                    End Function
    
    
                    ' ハッシュテーブルのようなハッシュアルゴリズムやデータ構造での使用に適した、CsvColumnのハッシュ関数として機能します。
                      ' 現在のCsvColumnインスタンスにハッシュコードを返します。
                      Public Overrides Function GetHashCode() As Integer
                            Return (FieldName.GetHashCode() + DataType.GetHashCode())
                    End Function
            End Structure
    End Namespace
    

    C#

    C#コード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    using System;
    
    namespace CustomDataProvider.CSVDataProvider
    {
            // データソース内のフィールドに関する情報を表します。
            internal struct CsvColumn
            {
                    private readonly string _fieldName;
                    private readonly Type _dataType;
    
                    // CsvColumnクラスの新しいインスタンスを生成します。
                      // fieldNameはCsvColumnのインスタンスによって表されるフィールドの名前です。
                      // dataTypeはCsvColumnのインスタンスによって表されるフィールドの種類です。
                      public CsvColumn(string fieldName, Type dataType)
                    {
                            if (fieldName == null)
                                    throw new ArgumentNullException("fieldName");
                            if (dataType == null)
                                    throw new ArgumentNullException("dataType");
                            _fieldName = fieldName;
                            _dataType = dataType;
                    }
    
    
                    // CsvColumnのインスタンスによって表されるフィールドの名前を取得します。
                      public string FieldName
                    {
                            get { return _fieldName; }
                    }
    
    
                    //CsvColumnのインスタンスによって表されるフィールドの種類を取得します。
                      public Type DataType
                    {
                            get { return _dataType; }
                    }
    
    
                   //CsvColumnのインスタンスを表わす文字列を返します。
                      public override string ToString()
                    {
                            return String.Concat(new string[] {FieldName, "(", DataType.ToString(), ")"});
                    }
    
    
                    //2つのCsvColumnのインスタンスが同じかどうかを判定します。
                      //指定されたCsvColumnが現在のCsvColumnと同じである場合はTrueを返し、そうではない場合はFalseを返します。
                      public override bool Equals(object obj)
                    {
                            bool flag;
    
                            if (obj is CsvColumn)
                            {
                                    flag = Equals((CsvColumn) obj);
                            }
                            else
                            {
                                    flag = false;
                            }
                            return flag;
                    }
    
                    private bool Equals(CsvColumn column)
                    {
                            return column.FieldName == FieldName;
                    }
    
    
                    //ハッシュテーブルのようなハッシュアルゴリズムやデータ構造での使用に適した、CsvColumnのハッシュ関数として機能します。
                      //現在のCsvColumnインスタンスにハッシュコードを返します。
                      public override int GetHashCode()
                    {
                            return (FieldName.GetHashCode() + DataType.GetHashCode());
                    }
            }
    }
    
  7. CSVDataProviderフォルダを右クリックし、[追加]から[クラス]を選択し、ファイル名を「CsvDataReader」に変更します。デフォルトスタブを以下のコードに置き換えます。

    Visual Basic

    Visual Basicコード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    Imports System
    Imports System.Collections
    Imports System.Globalization
    Imports System.IO
    Imports System.Text.RegularExpressions
    Imports GrapeCity.ActiveReports.Extensibility.Data
    
    Namespace CSVDataProvider
    
       ' .NET Framework CSV Data ProviderのIDataReaderの実施を提供します。
        Friend Class CsvDataReader
            Implements IDataReader
           ' メモ:HashcodeProviderとComparerは大文字と小文字を区別します。
            Private _typeLookup As New Hashtable(StringComparer.Create(CultureInfo.InvariantCulture, False))
    
            Private _columnLookup As New Hashtable()
            Private _columns As Object()
            Private _textReader As TextReader
            Private _currentRow As Object()
    
    
           ' 正規表現は、高速化するためにコンパイル済みです。 
    ' マルチスレッドに関係するため、このオブジェクトのプロパティを変更できないように読み取り専用に設定しています。 Private Shared ReadOnly _rxDataRow As New Regex(",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))", RegexOptions.Compiled) 'データ行の解析に使用します。 Private Shared ReadOnly _rxHeaderRow As New Regex("(?<fieldName>(\w*\s*)*)\((?<fieldType>\w*)\)", RegexOptions.Compiled) 'ヘッダ行の解析に使用します。 ' CsvDataReaderクラスの新しいインスタンスを生成します。 ' textReaderはデータを読みこむTextReaderを表します。 Public Sub New(textReader As TextReader) _textReader = textReader ParseCommandText() End Sub ' 渡したコマンドテキストを解析します。 Private Sub ParseCommandText() If _textReader.Peek() = -1 Then Return End If ' コマンドテキストが空であるか、すでに終了している。 FillTypeLookup() Dim header As String = _textReader.ReadLine() header = AddDefaultTypeToHeader(header) If Not ParseHeader(header) Then Throw New InvalidOperationException( _ "Field names and types are not defined." & _ "The first line in the CommandText must contain the field names and data types. e.g FirstName(string)") End If End Sub ' ハッシュテーブルはヘッダテキストに使用される文字列のデータ型を返却するために使用します。 Private Sub FillTypeLookup() _typeLookup.Add("string", GetType([String])) _typeLookup.Add("byte", GetType([Byte])) _typeLookup.Add("boolean", GetType([Boolean])) _typeLookup.Add("datetime", GetType(DateTime)) _typeLookup.Add("decimal", GetType([Decimal])) _typeLookup.Add("double", GetType([Double])) _typeLookup.Add("int16", GetType(Int16)) _typeLookup.Add("int32", GetType(Int32)) _typeLookup.Add("int", GetType(Int32)) _typeLookup.Add("integer", GetType(Int32)) _typeLookup.Add("int64", GetType(Int64)) _typeLookup.Add("sbyte", GetType([SByte])) _typeLookup.Add("single", GetType([Single])) _typeLookup.Add("time", GetType(DateTime)) _typeLookup.Add("date", GetType(DateTime)) _typeLookup.Add("uint16", GetType(UInt16)) _typeLookup.Add("uint32", GetType(UInt32)) _typeLookup.Add("uint64", GetType(UInt64)) End Sub 'ヘッダテキストの文字列から渡された値に基づいてデータ型を返却します。適合しない場合は、文字列型を返却します。 ' fieldTypeパラメータはヘッダコマンドテキストStringのString値を代表します。 Private Function GetFieldTypeFromString(fieldType As String) As Type If _typeLookup.Contains(fieldType) Then Return TryCast(_typeLookup(fieldType), Type) End If Return GetType([String]) End Function ' 渡したコマンドテキストの最初の行を解析してフィールド名とフィールドデータ型を生成します。 ' フィールド情報はCsvColumn 構造体に保存し、列の情報アイテムはArrayListに保存します。 ' 後で参照しやすくするために、ハッシュテーブルに列名も付けます。 ' ヘッダパラメータはヘッダ文字列を表し、すべてのフィールドを含めます。 ' ヘッダ文字列を解析できる場合はTrueを返し、そうではない場合はFalseを返します。 Private Function ParseHeader(header As String) As Boolean Dim fieldName As String Dim index As Integer = 0 If header.IndexOf("(") = -1 Then Return False End If Dim matches As MatchCollection = _rxHeaderRow.Matches(header) _columns = New Object(matches.Count - 1) {} For Each match As Match In matches fieldName = match.Groups("fieldName").Value Dim fieldType As Type = GetFieldTypeFromString(match.Groups("fieldType").Value) _columns.SetValue(New CsvColumn(fieldName, fieldType), index) _columnLookup.Add(fieldName, index) index += 1 Next Return True End Function ' ヘッダに名前の形式の列が含まれていることを確認します。 ' lineパラメータはファイルから解析したに列ヘッダ行を表します。 ' カラム名に付加するデフォルト型の変更されたヘッダを返却します。 Private Shared Function AddDefaultTypeToHeader(line As String) As String Const ColumnWithDataTypeRegex As String = "[""]?\w+[\""]?\(.+\)" Dim columns As String() = line.Split(New String() {","}, StringSplitOptions.None) Dim ret As String = Nothing For Each column As String In columns If Not String.IsNullOrEmpty(ret) Then ret += "," End If If Not Regex.Match(column, ColumnWithDataTypeRegex).Success Then ret += column + "(string)" Else ret += column End If Next Return ret End Function ' 正規表現を使用して、データの行を解析し、データの現在の行にあるオブジェクト配列内の情報を格納します。 ' 行が正しいフィールド数でない場合、例外が発生します。 ' DataRowは、カンマ区切りのデータ行を表す文字列型(String)の値を表します。 ' データを解析できる場合はTrueを返し、そうではない場合はFalseを返します。 Private Function ParseDataRow(dataRow As String) As Boolean Dim index As Integer = 0 Dim tempData As String() = _rxDataRow.Split(dataRow) _currentRow = New Object(tempData.Length - 1) {} If tempData.Length <> _columns.Length Then Dim [error] As String = String.Format(CultureInfo.InvariantCulture, _ "Invalid row ""{0}"".The row does not contain the same number of data columns as the table header definition.", dataRow) Throw New InvalidOperationException([error]) End If For i As Integer = 0 To tempData.Length - 1 Dim value As String = tempData(i) If value.Length > 1 Then If value.IndexOf(""""c, 0) = 0 AndAlso value.IndexOf(""""c, 1) = value.Length - 1 Then value = value.Substring(1, value.Length - 2) End If End If _currentRow.SetValue(ConvertValue(GetFieldType(index), value), index) index += 1 Next Return True End Function ' コマンドテキストからの文字列値を、フィールドの種類によって適当なデータ型に変更します。 ' System.Data.DBNullのString.Emptyを返すかどうかを決めるのに文字列値の規則を確認します。 ' typeパラメータはデータが属する現在の列の種類を表します。 ' originalValueはコマンドテキストからの文字列値を表します。 ' 変更したStringからのオブジェクトを種類に応じて返します。 Private Function ConvertValue(type As Type, originalValue As String) As Object Dim fieldType As Type = type Dim invariantCulture As CultureInfo = CultureInfo.InvariantCulture Try If originalValue = """""" OrElse originalValue = " " Then Return String.Empty End If If originalValue = "" Then Return DBNull.Value End If If originalValue = "DBNull" Then Return DBNull.Value End If If fieldType.Equals(GetType([String])) Then Return originalValue.Trim() End If If fieldType.Equals(GetType(Int32)) Then Return Convert.ToInt32(originalValue, invariantCulture) End If If fieldType.Equals(GetType([Boolean])) Then Return Convert.ToBoolean(originalValue, invariantCulture) End If If fieldType.Equals(GetType(DateTime)) Then Return Convert.ToDateTime(originalValue, invariantCulture) End If If fieldType.Equals(GetType([Decimal])) Then Return Convert.ToDecimal(originalValue, invariantCulture) End If If fieldType.Equals(GetType([Double])) Then Return Convert.ToDouble(originalValue, invariantCulture) End If If fieldType.Equals(GetType(Int16)) Then Return Convert.ToInt16(originalValue, invariantCulture) End If If fieldType.Equals(GetType(Int64)) Then Return Convert.ToInt64(originalValue, invariantCulture) End If If fieldType.Equals(GetType([Single])) Then Return Convert.ToSingle(originalValue, invariantCulture) End If If fieldType.Equals(GetType([Byte])) Then Return Convert.ToByte(originalValue, invariantCulture) End If If fieldType.Equals(GetType([SByte])) Then Return Convert.ToSByte(originalValue, invariantCulture) End If If fieldType.Equals(GetType(UInt16)) Then Return Convert.ToUInt16(originalValue, invariantCulture) End If If fieldType.Equals(GetType(UInt32)) Then Return Convert.ToUInt32(originalValue, invariantCulture) End If If fieldType.Equals(GetType(UInt64)) Then Return Convert.ToUInt64(originalValue, invariantCulture) End If Catch e As Exception Throw New InvalidOperationException(String.Format("Input value '{0}' could not be converted to the type '{1}'.", originalValue, type), e) End Try ' 一致しない場合、DBNullを返します。 Return DBNull.Value End Function #Region "IDataReader Members" ' CsvDataReaderは次のレコードに進みます。 ' それ以上の行がある場合はTrueを返し、そうではない場合はFalseを返します。 Public Function Read() As Boolean Implements IDataReader.Read If _textReader.Peek() > -1 Then ParseDataRow(_textReader.ReadLine()) Else Return False End If Return True End Function #End Region #Region "IDisposable Members" ' CsvDataReaderに使用されるリソースを出します。 Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Private Sub Dispose(disposing As Boolean) If disposing Then If _textReader IsNot Nothing Then _textReader.Close() End If End If _typeLookup = Nothing _columnLookup = Nothing _columns = Nothing _currentRow = Nothing End Sub ' オブジェクトがガベージコレクションによってクリアされる前に、そのオブジェクトがリソースを解放し、 ' その他のクリーンアップ操作を実行できるようにします。 Protected Overrides Sub Finalize() Try Dispose(False) Finally MyBase.Finalize() End Try End Sub #End Region #Region "IDataRecord Members" ' 現在の行に列の数字を取得します。 Public ReadOnly Property FieldCount() As Integer Implements IDataRecord.FieldCount Get Return _columns.Length End Get End Property ' iは探すフィールドのインデックスを表します。 ' GetValueから返される、オブジェクトの型に対応する型の情報を返却します。 Public Function GetFieldType(i As Integer) As Type Implements IDataReader.GetFieldType If i > _columns.Length - 1 Then Return Nothing End If Return DirectCast(_columns.GetValue(i), CsvColumn).DataType End Function ' 探すフィールドの名前を取得します。 ' iは探すフィールドのインデックスを表します。 ' 返却する値がない場合は、フィールドの名前か、空文字 ("")を返します。 Public Function GetName(i As Integer) As String Implements IDataRecord.GetName If i > _columns.Length - 1 Then Return String.Empty End If Return DirectCast(_columns.GetValue(i), CsvColumn).FieldName End Function ' nameパラメータは探すフィールドの名前を表します。 ' 指定されたフィールドのインデックスを返却します。 Public Function GetOrdinal(name As String) As Integer Implements IDataRecord.GetOrdinal Dim value As Object = _columnLookup(name) If value Is Nothing Then Throw New IndexOutOfRangeException("name") End If Return CInt(value) End Function ' iは探すフィールドのインデックスを表します。 ' 指定されたフィールドの値を含むオブジェクトを返します。 Public Function GetValue(i As Integer) As Object Implements IDataRecord.GetValue If i > _columns.Length - 1 Then Return Nothing End If Return _currentRow.GetValue(i) End Function Public Overridable Function GetData(fieldIndex As Integer) As IDataReader Implements IDataReader.GetData Throw New NotSupportedException() End Function #End Region End Class End Namespace

    C#

    C#コード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    using System;
    using System.Collections;
    using System.Globalization;
    using System.IO;
    using System.Text.RegularExpressions;
    using GrapeCity.ActiveReports.Extensibility.Data;
    
    namespace CustomDataProvider.CSVDataProvider
    {
    
            //  .NET Framework CSV Data ProviderのIDataReaderの実施を提供します。
            internal class CsvDataReader :IDataReader
            {
                 //メモ:HashcodeProviderとComparerは大文字と小文字を区別します。
                   private Hashtable _typeLookup =
                            new Hashtable(StringComparer.Create(CultureInfo.InvariantCulture, false));
                 private Hashtable _columnLookup = new Hashtable();
                 private object[] _columns;
                 private TextReader _textReader;
                 private object[] _currentRow;
    
    
                 //正規表現は、高速化するためにコンパイル済みです。
    //マルチスレッドに関係するため、このオブジェクトのプロパティを変更できないように読み取り専用に設定しています
    。 private static readonly Regex _rxDataRow = new Regex(@",(?=(?:[^""]*""[^""]*"")*(?![^""]*""))", RegexOptions.Compiled); //データ行の解析に使用します。 private static readonly Regex _rxHeaderRow = new Regex(@"(?<fieldName>(\w*\s*)*)\((?<fieldType>\w*)\)", RegexOptions.Compiled); //ヘッダ行の解析に使用します。 // CsvDataReaderクラスの新しいインスタンスを生成します。 // textReaderはデータを読みこむTextReaderを表します。 public CsvDataReader(TextReader textReader) { _textReader = textReader; ParseCommandText(); } // 渡したコマンドテキストを解析します。 private void ParseCommandText() { if (_textReader.Peek() == -1) return; //Command text is empty or at the end already. FillTypeLookup(); string header = _textReader.ReadLine(); header = AddDefaultTypeToHeader(header); if (!ParseHeader(header)) throw new InvalidOperationException( "Field names and types are not defined.The first line in the CommandText must contain the field names and data types. e.g FirstName(string)"); } //ハッシュテーブルはヘッダテキストに使用される文字列のデータ型を返却するために使用します。 private void FillTypeLookup() { _typeLookup.Add("string", typeof (String)); _typeLookup.Add("byte", typeof (Byte)); _typeLookup.Add("boolean", typeof (Boolean)); _typeLookup.Add("datetime", typeof (DateTime)); _typeLookup.Add("decimal", typeof (Decimal)); _typeLookup.Add("double", typeof (Double)); _typeLookup.Add("int16", typeof (Int16)); _typeLookup.Add("int32", typeof (Int32)); _typeLookup.Add("int", typeof (Int32)); _typeLookup.Add("integer", typeof (Int32)); _typeLookup.Add("int64", typeof (Int64)); _typeLookup.Add("sbyte", typeof (SByte)); _typeLookup.Add("single", typeof (Single)); _typeLookup.Add("time", typeof (DateTime)); _typeLookup.Add("date", typeof (DateTime)); _typeLookup.Add("uint16", typeof (UInt16)); _typeLookup.Add("uint32", typeof (UInt32)); _typeLookup.Add("uint64", typeof (UInt64)); } // ヘッダテキストの文字列から渡された値に基づいてデータ型を返却します。適合しない場合は、文字列型を返却します。 // fieldTypeパラメータはヘッダコマンドテキストStringのString値を代表します。 private Type GetFieldTypeFromString(string fieldType) { if (_typeLookup.Contains(fieldType)) return _typeLookup[fieldType] as Type; return typeof (String); } // 渡したコマンドテキストの最初の行を解析してフィールド名とフィールドデータ型を生成します。 // フィールド情報はCsvColumn 構造体に保存し、列の情報アイテムはArrayListに保存します // 後で参照しやすくするために、ハッシュテーブルに列名も付けます。 // ヘッダパラメータはヘッダ文字列を表し、すべてのフィールドを含めます。 // ヘッダ文字列を解析できる場合はTrueを返し、そうではない場合はFalseを返します。 private bool ParseHeader(string header) { string fieldName; int index = 0; if (header.IndexOf("(") == -1) return false; MatchCollection matches = _rxHeaderRow.Matches(header); _columns = new object[matches.Count]; foreach (Match match in matches) { fieldName = match.Groups["fieldName"].Value; Type fieldType = GetFieldTypeFromString(match.Groups["fieldType"].Value); _columns.SetValue(new CsvColumn(fieldName, fieldType), index); _columnLookup.Add(fieldName, index); index++; } return true; } // ヘッダに名前の形式の列が含まれていることを確認します。 // lineパラメータはファイルから解析したに列ヘッダ行を表します。 // カラム名に付加するデフォルト型の変更されたヘッダを返却します。 private static string AddDefaultTypeToHeader(string line) { const string ColumnWithDataTypeRegex = @"[""]?\w+[\""]?\(.+\)"; string[] columns = line.Split(new string[] { "," }, StringSplitOptions.None); string ret = null; foreach (string column in columns) { if (!string.IsNullOrEmpty(ret)) ret += ","; if (!Regex.Match(column, ColumnWithDataTypeRegex).Success) { ret += column + "(string)"; } else { ret += column; } } return ret; } // 正規表現を使用して、データの行を解析し、データの現在の行にあるオブジェクト配列内の情報を格納します // 行が正しいフィールド数でない場合、例外が発生します。 // DataRowは、カンマ区切りのデータ行を表す文字列型(String)の値を表します。 // データを解析できる場合はTrueを返し、そうではない場合はFalseを返します。 private bool ParseDataRow(string dataRow) { int index = 0; string[] tempData = _rxDataRow.Split(dataRow); _currentRow = new object[tempData.Length]; if (tempData.Length != _columns.Length) { string error = string.Format(CultureInfo.InvariantCulture, "Invalid row \"{0}\".The row does not contain the same number of data columns as the table header definition.", dataRow); throw new InvalidOperationException(error); } for (int i = 0; i < tempData.Length; i++) { string value = tempData[i]; if (value.Length > 1) { if (value.IndexOf('"', 0) == 0 && value.IndexOf('"', 1) == value.Length - 1)
    value = value.Substring(1, value.Length - 2); } _currentRow.SetValue(ConvertValue(GetFieldType(index), value), index); index++; } return true; } // コマンドテキストからの文字列値を、フィールドの種類によって適当なデータ型に変更します。 // System.Data.DBNullのString.Emptyを返すかどうかを決めるのに文字列値の規則を確認します。 // typeパラメータはデータが属する現在の列の種類を表します。 // originalValueはコマンドテキストからの文字列値を表します。 // 変更したStringからのオブジェクトを種類に応じて返します。 private object ConvertValue(Type type, string originalValue) { Type fieldType = type; CultureInfo invariantCulture = CultureInfo.InvariantCulture; try { if (originalValue == "\"\"" || originalValue == " ") return string.Empty; if (originalValue == "") return DBNull.Value; if (originalValue == "DBNull") return DBNull.Value; if (fieldType.Equals(typeof (String))) return originalValue.Trim(); if (fieldType.Equals(typeof (Int32))) return Convert.ToInt32(originalValue, invariantCulture); if (fieldType.Equals(typeof (Boolean))) return Convert.ToBoolean(originalValue, invariantCulture); if (fieldType.Equals(typeof (DateTime))) return Convert.ToDateTime(originalValue, invariantCulture); if (fieldType.Equals(typeof (Decimal))) return Convert.ToDecimal(originalValue, invariantCulture); if (fieldType.Equals(typeof (Double))) return Convert.ToDouble(originalValue, invariantCulture); if (fieldType.Equals(typeof (Int16))) return Convert.ToInt16(originalValue, invariantCulture); if (fieldType.Equals(typeof (Int64))) return Convert.ToInt64(originalValue, invariantCulture); if (fieldType.Equals(typeof (Single))) return Convert.ToSingle(originalValue, invariantCulture); if (fieldType.Equals(typeof (Byte))) return Convert.ToByte(originalValue, invariantCulture); if (fieldType.Equals(typeof (SByte))) return Convert.ToSByte(originalValue, invariantCulture); if (fieldType.Equals(typeof (UInt16))) return Convert.ToUInt16(originalValue, invariantCulture); if (fieldType.Equals(typeof (UInt32))) return Convert.ToUInt32(originalValue, invariantCulture); if (fieldType.Equals(typeof (UInt64))) return Convert.ToUInt64(originalValue, invariantCulture); } catch (Exception e) { throw new InvalidOperationException( string.Format("Input value '{0}' could not be converted to the type '{1}'.", originalValue, type), e); } //一致しない場合、DBNullを返します。 return DBNull.Value; } #region IDataReader Members // CsvDataReaderは次のレコードに進みます。 // それ以上の行がある場合はTrueを返し、そうではない場合はFalseを返します。 public bool Read() { if (_textReader.Peek() > -1) ParseDataRow(_textReader.ReadLine()); else return false; return true; } #endregion #region IDisposable Members // CsvDataReaderに使用されるリソースを出します。 public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } private void Dispose(bool disposing) { if (disposing) { if (_textReader != null) _textReader.Close(); } _typeLookup = null; _columnLookup = null; _columns = null; _currentRow = null; } // オブジェクトがガベージコレクションによってクリアされる前に、そのオブジェクトがリソースを解放し、 // その他のクリーンアップ操作を実行できるようにします。 ~CsvDataReader() { Dispose(false); } #endregion #region IDataRecord Members // 現在の行に列の数字を取得します。 public int FieldCount { get { return _columns.Length; } } // iは探すフィールドのインデックスを表します。 // GetValueから返される、オブジェクトの型に対応する型の情報を返却します。 public Type GetFieldType(int i) { if (i > _columns.Length - 1) return null; return ((CsvColumn) _columns.GetValue(i)).DataType; } // 探すフィールドの名前を取得します。 // iは探すフィールドのインデックスを表します。 // 返却する値がない場合は、フィールドの名前か、空文字 ("")を返します。 public string GetName(int i) { if (i > _columns.Length - 1) return string.Empty; return ((CsvColumn) _columns.GetValue(i)).FieldName; } // nameパラメータは探すフィールドの名前を表します。 // 指定されたフィールドのインデックスを返却します。 public int GetOrdinal(string name) { object value = _columnLookup[name]; if (value == null) throw new IndexOutOfRangeException("name"); return (int) value; } // iは探すフィールドのインデックスを表します。 // 指定されたフィールドの値を含むオブジェクトを返します。 public object GetValue(int i) { if (i > _columns.Length - 1) return null; return _currentRow.GetValue(i); } public virtual IDataReader GetData(int fieldIndex) { throw new NotSupportedException(); } #endregion } }
  8. CSVDataProviderフォルダを右クリックし、[追加]から[クラス]を選択してファイル名を「CsvCommand」に変更します。デフォルトスタブを以下のコードに置き換えます。(この時点ではエラーが表示されますが、CsvConnectionクラスを追加した後に解消されます) 

    Visual Basic

    Visual Basicコード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    Imports System
    Imports System.IO
    Imports GrapeCity.ActiveReports.Extensibility.Data
    
    Namespace CSVDataProvider
    
        ' .NET Framework CSV Data ProviderのIDbDataReaderの実施を提供します。
        Public NotInheritable Class CsvCommand
            Implements IDbCommand
            Private _commandText As String
            Private _connection As IDbConnection
            Private _commandTimeout As Integer
            Private _commandType As CommandType
    
    
            ' CsvCommandクラスの新しいインスタンスを生成します。
            Public Sub New()
                Me.New(String.Empty)
            End Sub
    
    
           ' コマンドテキストのあるCsvCommandクラスの新しいインスタンスを生成します。
            ' commandTextパラメータはコマンドテキストを表します。
            Public Sub New(commandText As String)
                Me.New(commandText, Nothing)
            End Sub
    
    
           ' コマンドテキストとCsvConnectionがあるCsvCommandクラスの新しいインスタンスを生成します。
            ' commandTextパラメータは、コマンドテキストを表します。
            ' connectionパラメータは、データソースとCsvConnectionを表します。
            Public Sub New(commandText As String, connection As CsvConnection)
                _commandText = commandText
                _connection = connection
            End Sub
    
    
            ' データソースで実行するコマンドを取得、設定します。
            Public Property CommandText() As String Implements IDbCommand.CommandText
                Get
                    Return _commandText
                End Get
                Set(value As String)
                    _commandText = value
                End Set
            End Property
    
    
            ' コマンド実行の試行を終了し、エラーを生成するまでの待機時間を取得、設定します。
            Public Property CommandTimeout() As Integer Implements IDbCommand.CommandTimeout
                Get
                    Return _commandTimeout
                End Get
    
                Set(value As Integer)
                    _commandTimeout = value
                End Set
            End Property
    
    
           ' CommandTextプロパティの解放を指示する値を取得、設定します。
            Public Property CommandType() As CommandType Implements IDbCommand.CommandType
                Get
                    Return _commandType
                End Get
    
                Set(value As CommandType)
                    _commandType = value
                End Set
            End Property
    
    
            ' CsvCommandのインスタンスに使用するCsvConnectionの値を取得、設定します。
            Public Property Connection() As IDbConnection
                Get
                    Return _connection
                End Get
    
                Set(value As IDbConnection)
                    _connection = value
                End Set
            End Property
    
    
           ' CommandTextをCsvConnectionに送信し、いずれかのCommandBehavior値を使用し、CsvDataReaderをビルドします。
            ' behaviorパラメータはCommandBehaviorの値を表します。
            ' CsvDataReaderオブジェクトを返却。
            Public Function ExecuteReader(behavior As CommandBehavior) As IDataReader Implements IDbCommand.ExecuteReader
                Return New CsvDataReader(New StringReader(_commandText))
            End Function
    
    
            ' 定数に拡張パラメータを指定したコマンドテキストを表わす文字列を返却します。
            Public Function GenerateRewrittenCommandText() As String Implements IDbCommand.GenerateRewrittenCommandText
                Return _commandText
            End Function
    
    
           ' CommandTextをCsvConnectionに送信し、CsvDataReaderをビルドします。
            ' CsvDataReaderオブジェクトを返します。
            Public Function ExecuteReader() As IDataReader Implements IDbCommand.ExecuteReader
                Return ExecuteReader(CommandBehavior.SchemaOnly)
            End Function
    
    #Region "Non implemented IDbCommand Members"
    
            Public ReadOnly Property Parameters() As IDataParameterCollection Implements IDbCommand.Parameters
                Get
                    Throw New NotImplementedException()
                End Get
            End Property
    
            Public Property Transaction() As IDbTransaction Implements IDbCommand.Transaction
                Get
                    Throw New NotImplementedException()
                End Get
    
                Set(value As IDbTransaction)
                    Throw New NotImplementedException()
                End Set
            End Property
    
            Public Sub Cancel() Implements IDbCommand.Cancel
    
            End Sub
    
            Public Function CreateParameter() As IDataParameter Implements IDbCommand.CreateParameter
                Throw New NotImplementedException()
            End Function
    
    #End Region
    
    #Region "IDisposable Members"
    
    
            ' CsvCommandに使用するリソースを放出します。
            Public Sub Dispose() Implements IDisposable.Dispose
                Dispose(True)
                GC.SuppressFinalize(Me)
            End Sub
    
    
            Private Sub Dispose(disposing As Boolean)
                If disposing Then
                    If _connection IsNot Nothing Then
                        _connection.Dispose()
                        _connection = Nothing
                    End If
                End If
            End Sub
    
    #End Region
        End Class
    End Namespace
    

    C#

    C# コード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    using System;
    using System.IO;
    using GrapeCity.ActiveReports.Extensibility.Data;
    
    namespace CustomDataProvider.CSVDataProvider
    {
    
           // .NET Framework CSV Data ProviderのIDbCommandの実施を提供します。
            public sealed class CsvCommand :IDbCommand
            {
                    private string _commandText;
                    private IDbConnection _connection;
                    private int _commandTimeout;
                    private CommandType _commandType;
    
            
                    /// Creates a new instance of the CsvCommand class.
                    public CsvCommand()
                            : this(string.Empty)
                    {
                    }
    
            
                  // コマンドテキストのあるCsvCommandクラスの新しいインスタンスを生成します。
                    // commandTextパラメータはコマンドテキストを表します。
                    public CsvCommand(string commandText)
                            : this(commandText, null)
                    {
                    }
    
            
                  // コマンドテキストとCsvConnectionがあるCsvCommandクラスの新しいインスタンスを生成します。
                    // commandTextパラメータ、コマンドテキストを表します。
                    // connectionパラメータは、データソースとCsvConnectionを表します。
                    public CsvCommand(string commandText, CsvConnection connection)
                    {
                            _commandText = commandText;
                            _connection = connection;
                    }
    
            
                    // データソースで実行するコマンドを取得、設定します。
                    public string CommandText
                    {
                            get { return _commandText; }
                            set { _commandText = value; }
                    }
    
            
                    // コマンド実行の試行を終了し、エラーを生成するまでの待機時間を取得、設定します。
                    public int CommandTimeout
                    {
                            get { return _commandTimeout; }
    
                            set { _commandTimeout = value; }
                    }
    
            
                    // CommandTextプロパティの解放を指示する値を取得、設定します。
                    public CommandType CommandType
                    {
                            get { return _commandType; }
    
                            set { _commandType = value; }
                    }
    
            
                   // CsvCommandのインスタンスに使用するCsvConnectionの値を取得、設定します。
                    public IDbConnection Connection
                    {
                            get { return _connection; }
    
                            set { _connection = value; }
                    }
    
            
                  // CommandTextをCsvConnectionに送信し、いずれかのCommandBehavior値を使用し、CsvDataReaderをビルドします。
                    // behaviorパラメータはCommandBehaviorの値を表します。
                    // CsvDataReaderオブジェクトを返却。
                    public IDataReader ExecuteReader(CommandBehavior behavior)
                    {
                            return new CsvDataReader(new StringReader(_commandText));
                    }
    
            
                   // 定数に拡張パラメータを指定したコマンドテキストを表わす文字列を返却します。
                    public string GenerateRewrittenCommandText()
                    {
                            return _commandText;
                    }
    
            
                  // CommandTextをCsvConnectionに送信し、CsvDataReaderをビルドします。
                    // CsvDataReaderオブジェクトを返します。
                    public IDataReader ExecuteReader()
                    {
                            return ExecuteReader(CommandBehavior.SchemaOnly);
                    }
    
                    #region Non implemented IDbCommand Members
    
                    public IDataParameterCollection Parameters
                    {
                            get { throw new NotImplementedException(); }
                    }
    
                    public IDbTransaction Transaction
                    {
                            get { throw new NotImplementedException(); }
    
                            set { throw new NotImplementedException(); }
                    }
    
                    public void Cancel()
                    {
                            
                    }
    
                    public IDataParameter CreateParameter()
                    {
                            throw new NotImplementedException();
                    }
    
                    #endregion
    
                    #region IDisposable Members
    
            
                    // CsvCommandに使用するリソースを放出します。
                    public void Dispose()
                    {
                            Dispose(true);
                            GC.SuppressFinalize(this);
                    }
    
    
                    private void Dispose(bool disposing)
                    {
                            if (disposing)
                            {
                                    if (_connection != null)
                                    {
                                            _connection.Dispose();
                                            _connection = null;
                                    }
                            }
                    }
    
                    #endregion
            }
    }
    
  9. CSVDataProviderフォルダを右クリックし、[追加]から[クラス]を選択し、ファイル名を「CsvConnection」に変更します。デフォルトスタブを以下のコードに置き換えます。

    Visual Basic

    Visual Basicコード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    Imports System
    Imports System.Collections.Specialized
    Imports GrapeCity.ActiveReports.Extensibility.Data
    
    Namespace CSVDataProvider
    
        ' .NET Framework CSV Data ProviderのIDbConnectionの実施を提供します。
        Public NotInheritable Class CsvConnection
            Implements IDbConnection
            Private _localizedName As String
    
            ' CsvConnectionクラスの新しいインスタンスを生成します。
            Public Sub New()
                _localizedName = "Csv"
            End Sub
    
           ' CsvConnectionクラスの新しいインスタンスを生成します。
            ' localizedNameはCsvConnectionのインスタンスのローカライズ名を表します。
            Public Sub New(localizeName As String)
                _localizedName = localizeName
            End Sub
    
    #Region "IDbConnection Members"
    
           ' データソースに接続の開始に使用する文字列を取得、設定します。
           ' 備考:Csv Data Providerでは使いません。
            Public Property ConnectionString() As String Implements IDbConnection.ConnectionString
                Get
                    Return String.Empty
                End Get
    
                Set(value As String)
    
    
                End Set
            End Property
    
           ' 接続を確立する際の待機時間を取得、設定します。
           ' 備考:Csv Data Providerでは使いません。
            Public ReadOnly Property ConnectionTimeout() As Integer Implements IDbConnection.ConnectionTimeout
                Get
                    Throw New NotImplementedException()
                End Get
            End Property
    
           ' データソースとのトランザクションを開始します。  
            ' 新しいトランザクションを表わすオブジェクトを返します。
           ' 備考:Csv Data Providerでは使いません。
            Public Function BeginTransaction() As IDbTransaction Implements IDbConnection.BeginTransaction
                Return Nothing
            End Function
    
            ' データソースとの接続を開きます。     
            ' 備考:Csv Data Providerでは使いません。
            Public Sub Open() Implements IDbConnection.Open
    
    
            End Sub
    
            ' データソースとの接続を閉じます。これは、接続を閉じるために推奨される方法です。
            Public Sub Close() Implements IDbConnection.Close
                Dispose()
            End Sub
    
            ' CsvConnectionに関連付けたCsvCommandオブジェクトを生成し、返却します。
            Public Function CreateCommand() As IDbCommand Implements IDbConnection.CreateCommand
                Return New CsvCommand(String.Empty)
            End Function
    
            Public Property DataProviderService() As IDataProviderService Implements IDbConnection.DataProviderService
                Get
                    Return Nothing
                End Get
                Set(value As IDataProviderService)
                End Set
            End Property
    
    #End Region
    
    #Region "IDisposable Members"
    
            ' CsvConnectionに使用するリソースを解放します。
            Public Sub Dispose() Implements IDisposable.Dispose
                Dispose(True)
                GC.SuppressFinalize(Me)
            End Sub
    
            Private Sub Dispose(disposing As Boolean)
            End Sub
    
           ' オブジェクトがガベージコレクションによってクリアされる前に、そのオブジェクトがリソースを解放し、
        ' その他のクリーンアップ操作を実行できるようにします。
            Protected Overrides Sub Finalize()
                Try
                    Dispose(False)
                Finally
                    MyBase.Finalize()
                End Try
            End Sub
    
    #End Region
    
    #Region "IExtension Members"
    
           ' CsvConnectionのローカライズ名を取得します。
            Public ReadOnly Property LocalizedName() As String Implements IDbConnection.LocalizedName
                Get
                    Return _localizedName
                End Get
            End Property
    
           ' この拡張子の構成情報を指定します。
            ' configurationSettingsは設定のNameValueCollectionを表します。
            Public Sub SetConfiguration(configurationSettings As NameValueCollection) Implements IDbConnection.SetConfiguration
            End Sub
    
    #End Region
        End Class
    End Namespace
    

    C#

    C#コード(デフォルトスタブと置換するには貼り付けます)
    コードのコピー
    using System;
    using System.Collections.Specialized;
    using GrapeCity.ActiveReports.Extensibility.Data;
    
    namespace CustomDataProvider.CSVDataProvider
    {
    
            // .NET Framework CSV Data ProviderのIDbConnectionの実施を提供します。
            public sealed class CsvConnection :IDbConnection
            {
                    private string _localizedName;
    
            
                    // CsvConnectionクラスの新しいインスタンスを生成します。
                    public CsvConnection()
                    {
                            _localizedName = "Csv";
                    }
    
            
                    // CsvConnectionクラスの新しいインスタンスを生成します。
                    // ocalizedNameはCsvConnectionのインスタンスのローカライズ名を表します。
                    public CsvConnection(string localizeName)
                    {
                            _localizedName = localizeName;
                    }
    
                    #region IDbConnection Members
    
            
                  // データソースに接続の開始に使用する文字列を取得、設定します。
                    // 備考:Csv Data Providerでは使いません。
                    public string ConnectionString
                    {
                            get { return string.Empty; }
    
                            set { ; }
                    }
    
            
                    // 接続を確立する際の待機時間を取得、設定します。
                    // 備考:Csv Data Providerでは使いません。
                    public int ConnectionTimeout
                    {
                            get { throw new NotImplementedException(); }
                    }
    
            
                   // データソースとのトランザクションを開始します。 
                   // 新しいトランザクションを表わすオブジェクトを返します。
                   // 備考:Csv Data Providerには使いません。
                    public IDbTransaction BeginTransaction()
                    {
                            return null;
                    }
    
            
                   // データソースとの接続を開きます。     
                   // 備考:Csv Data Providerには使いません。
                    public void Open()
                    {
                            ;
                    }
    
            
                    // データソースとの接続を閉じます。これは、接続を閉じるために推奨される方法です。
                    public void Close()
                    {
                            Dispose();
                    }
    
            
                   // CsvConnectionに関連付けたCsvCommandオブジェクトを生成し、返却します。
                    public IDbCommand CreateCommand()
                    {
                            return new CsvCommand(string.Empty);
                    }
    
                    public IDataProviderService DataProviderService
                    {
                            get { return null; }
                            set { }
                    }
    
                    #endregion
    
                    #region IDisposable Members
    
            
                   // CsvConnectionに使用するリソースを解放します。
                    public void Dispose()
                    {
                            Dispose(true);
                            GC.SuppressFinalize(this);
                    }
    
                    private void Dispose(bool disposing)
                    {
                    }
    
            
                    // オブジェクトがガベージコレクションによってクリアされる前に、そのオブジェクトがリソースを解放し、
                    // その他のクリーンアップ操作を実行できるようにします。
                    ~CsvConnection()
                    {
                            Dispose(false);
                    }
    
                    #endregion
    
                    #region IExtension Members
    
            
                    // CsvConnectionのローカライズ名を取得します。
                    public string LocalizedName
                    {
                            get { return _localizedName; }
                    }
    
            
                    // この拡張子の構成情報を指定します。
                    // configurationSettingsは設定のNameValueCollectionを表します。
                    public void SetConfiguration(NameValueCollection configurationSettings)
                    {
                    }
    
                    #endregion
            }
    }
    
  10. CSVDataProviderフォルダを右クリックし、[追加]から[クラス]を選択し、ファイル名を「CsvDataProviderFactory」に変更します。デフォルトスタブを以下のコードに置き換えます。

    Visual Basic

    Visual Basicコード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    Imports GrapeCity.ActiveReports.Extensibility.Data
    Imports GrapeCity.BI.Data.DataProviders
    
    Namespace CSVDataProvider
    
           ' .NET Framework CSV Data ProviderのDataProviderFactoryを実施します。
            Public Class CsvDataProviderFactory
                    Inherits DataProviderFactory
    
                    ' CsvDataProviderFactoryクラスの新しいインスタンスを生成します。
                    Public Sub New()
                    End Sub
    
                   ' CsvCommandの新しいインスタンスを返します。
                    Public Overrides Function CreateCommand() As IDbCommand
                            Return New CsvCommand()
                    End Function
    
                    ' CsvConnectionの新しいインスタンスを返します。
                    Public Overrides Function CreateConnection() As IDbConnection
                            Return New CsvConnection()
                    End Function
            End Class
    End Namespace
    

    C#

    C#コード(クラスのデフォルトスタブと置き換えます)
    コードのコピー
    using GrapeCity.ActiveReports.Extensibility.Data;
    using GrapeCity.BI.Data.DataProviders;
    
    namespace CustomDataProvider.CSVDataProvider
    {
    
           // .NET Framework CSV Data ProviderのDataProviderFactoryを実施します。
            public class CsvDataProviderFactory :DataProviderFactory
            {
            
                    // CsvDataProviderFactoryクラスの新しいインスタンスを生成します。
                    public CsvDataProviderFactory()
                    {
                    }
            
                   // CsvCommandの新しいインスタンスを返します。
                    public override IDbCommand CreateCommand()
                    {
                            return new CsvCommand();
                    }
            
                   // CsvConnectionの新しいインスタンスを返します。
                    public override IDbConnection CreateConnection()
                    {
                            return new CsvConnection();
                    }
            }
    }
    

クエリエディタにボタンを追加する

  1. CSVDataProviderフォルダを右クリックし、[追加]から[クラス]を選択し、ファイル名を「QueryEditor」に変更します。デフォルトスタブを以下のコードに置き換えます。

    Visual Basic

    Visual Basicコード(クラスのデフォールトスタブと置き換えます)
    コードのコピー
    Imports System
    Imports System.Collections.Generic
    Imports System.Drawing.Design
    Imports System.IO
    Imports System.Linq
    Imports System.Text
    Imports System.Text.RegularExpressions
    Imports System.Windows.Forms
    Imports System.Windows.Forms.Design
    Namespace CSVDataProvider
        Public NotInheritable Class QueryEditor
            Inherits UITypeEditor
            Dim path = ""
            Friend WithEvents btn As New Button()
            Public Overrides Function GetEditStyle(context As System.ComponentModel.ITypeDescriptorContext) As UITypeEditorEditStyle
                Return UITypeEditorEditStyle.DropDown
            End Function
            Public Overrides Function EditValue(context As System.ComponentModel.ITypeDescriptorContext, provider As System.IServiceProvider, value As Object) As Object
                Dim edSvc As IWindowsFormsEditorService = DirectCast(provider.GetService(GetType(IWindowsFormsEditorService)), IWindowsFormsEditorService)
    
                btn.Text = "Select CSV File..."
                Dim pdg = btn.Padding
                pdg.Bottom += 2
                btn.Padding = pdg
                edSvc.DropDownControl(btn)
                If String.IsNullOrEmpty(path) Then
                    Return String.Empty
                End If
                If Not File.Exists(path) Then
                    Return String.Empty
                End If
                Return path
               
            End Function
    
            Private Sub btn_Click(sender As System.Object, e As System.EventArgs) Handles btn.Click
                Using openDlg = New OpenFileDialog()
                    openDlg.Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*"
                    If openDlg.ShowDialog() <> DialogResult.OK Then
                        path = ""
                    Else
                        path = openDlg.FileName
                    End If
                   
                End Using
            End Sub
        End Class
    End Namespace
    
    

    C#

    C#コード(デフォールトスタブと置換するには貼り付けます)
    コードのコピー
    using System;
    using System.Collections.Generic;
    using System.Drawing.Design;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Windows.Forms;
    using System.Windows.Forms.Design;
    
    namespace CustomDataProvider.CSVDataProvider
    {
            public sealed class QueryEditor :UITypeEditor
            {
                    public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
                    {
                            return UITypeEditorEditStyle.DropDown;
                    }
    
                    public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
                    {
                            IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
                            var path = "";
                            var btn = new Button();
                            btn.Text = "Select CSV File...";
                            var pdg = btn.Padding;
                            pdg.Bottom += 2;
                            btn.Padding = pdg;
    
                            btn.Click += delegate
                                            {
                                                    using (var openDlg = new OpenFileDialog())
                                                    {
                                                            openDlg.Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*";
                                                            if (openDlg.ShowDialog() != DialogResult.OK)
                                                                    path = "";
                                                            else
                                                                    path = openDlg.FileName;
                                                    }
                                            };
                            
    
                            edSvc.DropDownControl(btn);
    
                            if (string.IsNullOrEmpty(path)) return string.Empty;
                            if (!File.Exists(path)) return string.Empty;
                            
                            return path;
                    }
            }
    }
    
    
  2. CustomDataProviderDemoプロジェクトを右クリックし、[参照の追加]を選択します。[参照の追加]ダイアログでは[プロジェクト]タブから、CustomDataProviderを選択し、OKをクリックします。
  3. プロジェクトを実行し、RichTextBoxに表示されている手順に沿って、カスタムデータプロバイダを設定します。