none
クリスタルレポートへのパラメータフィールドの設定について RRS feed

  • 質問

  • クリスタルレポートへのパラメータフィールドの設定でエラーが出てしまいます。(ラジオボタン1のテキスト名がクリスタルレポートに表示されません。)

    Imports CrystalDecisions.CrystalReports.Engine
    Imports CrystalDecisions.Shared
    Imports CrystalDecisions.ReportSource
    Imports CrystalDecisions.Windows.Forms
    Imports System.Data.OleDb
    Imports System.Data.SqlClient
    Imports System.Configuration

    Public Class Form3 '(フォームクラスのメンバとして宣言)
        Dim instance As InvalidCastException
        Dim count As Integer
        Dim dt As DataTable = New DataTable '敬称以外
        Dim dt1 As DataTable '敬称のみ

      Private Sub Button9_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button9.Click
            'プログラムコード  (印刷枚数と敬称以外)
            Dim Cn As New OleDbConnection
            Dim Command As OleDbCommand = New OleDbCommand
            Dim OLEDBCon As OleDb.OleDbConnection = _
                    New OleDb.OleDbConnection
            OLEDBCon.ConnectionString = _
             "Provider=Microsoft.Jet.OLEDB.4.0;" & _
             "Data Source=" & Form1.TextBox1.Text & ";" & _
             "Persist Security Info=False"
            Command.Connection = OLEDBCon
            'データテーブルに印刷枚数を保持する列
            Command.CommandText = "select 郵便番号,住所1,住所2,得意先コード,得意先名,0 as 印刷枚数  from 得意先T where 得意先コード = @得意先コード "
            Command.Parameters.AddWithValue("@得意先コード", TextBox1.Text)
            Dim Adapter As OleDbDataAdapter = New OleDbDataAdapter
            Adapter.SelectCommand = Command
            Adapter.Fill(dt)
            '敬称の列作成
            Dim b As DataColumn = dt.Columns.Item("敬称")
            If b Is Nothing Then
                dt.Columns.Add("敬称", GetType(String))
            End If
            'レコード取得
            TextBox3.Text = CStr(dt.Rows(dt.Rows.Count - 1).Item(0))
            TextBox4.Text = CStr(dt.Rows(dt.Rows.Count - 1).Item(1))
            TextBox5.Text = CStr(dt.Rows(dt.Rows.Count - 1).Item(2))
            TextBox6.Text = CStr(dt.Rows(dt.Rows.Count - 1).Item(3))
            TextBox7.Text = CStr(dt.Rows(dt.Rows.Count - 1).Item(4))
            '印刷枚数(メソッドの中)
            Dim Row As DataRow = dt.Rows(count)
            Row("印刷枚数") = TextBox2.Text
            count = count + 1
            'ラジオボタンの選択
            If RadioButton1.Checked = True Then
                Row("敬称") = RadioButton1.Text
            ElseIf RadioButton2.Checked = True Then
                Row("敬称") = RadioButton2.Text
            ElseIf RadioButton3.Checked = True Then
                Row("敬称") = RadioButton3.Text
                    End If
            '閉
            dt.Dispose()
            Adapter.Dispose()
            Cn.Dispose()
        End Sub
        Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
            '印刷枚数と敬称
            dt1 = dt.Clone
            '印刷枚数
            Dim d As String = TextBox2.Text
            TextBox8.Text = d
            '敬称
            If RadioButton1.Checked = True Then
                TextBox9.Text = RadioButton1.Text
            ElseIf RadioButton2.Checked = True Then
                TextBox9.Text = RadioButton2.Text
            ElseIf RadioButton3.Checked = True Then
                TextBox9.Text = RadioButton3.Text
                   End If
            For Each dr In dt.Rows
                For i = 1 To dr("印刷枚数")
                    dt1.ImportRow(dr)
                Next
            Next
    'データグリッドビューでの表示
            DataGridView2.DataSource = dt1
        End Sub
        Private Sub Button4_Click(sender As System.Object, e As System.EventArgs) Handles Button4.Click
            Form4.Show()
            Form4.Activate()
            Dim report As ReportClass = Form4.CrystalReportViewer1.ReportSource
            report.SetDataSource(dt1)
            report.SetParameterValue("PARAM", "radiobutton1.text") →ここで止まります
            report.Refresh()
        End Sub
    COMExceptionはハンドルされませんでした。
    インデックスが無効です。 (HRESULT からの例外: 0x8002000B (DISP_E_BADINDEX))

    VS2010PROとバンドル版のクリレポを使っています。ご教授ください

                    
    2013年1月28日 3:52

回答

  • nullということは、おそらく「敬称」の指定が誤っていると思います。

    DataGridView1.Columns("敬称").Index の部分の「敬称」は、以下のSQL文における"敬称"と一致していなければなりません。

    select ID, 氏名, '様' as 敬称, 住所, 0 as 印刷枚数 from 名簿


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク とももと 2013年1月31日 5:50
    2013年1月30日 3:02
    モデレータ

すべての返信

  • ブレークポイントを
    report.SetParameterValue("PARAM", "radiobutton1.text")
    の行で止め、
    イミディエイトウインドウで、
    report.ParameterFieldsプロパティを表示し、本当にPARAMという名前のパラメーターが存在しているのか確認してみて下さい。
    パラメーターが一つしかなければ、report.ParameterFields(0)がPARAMという名前になっていることの確認になります。

    なお、"radiobutton1.text"ではなく、radiobutton1.textの誤りだと思います。


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2013年1月28日 4:54
    モデレータ
  •    trapemiya様

    ありがとうございます。

    イミディエイトウインドウには下記が表示されます。

    System.Runtime.InteropServices.COMException' の初回例外が CrystalDecisions.CrystalReports.Engine.dll で発生しました。

    と表示されます。

    よろしくお願いいたします


    2013年1月28日 5:27
  • クリスタルレポートのデザイナ画面でフィールドエクスプローラを表示させ、そこにあるパラメータフィールドには「PARAM」というパラメータが本当に存在しているのでしょうか? おそらく無いために、以下のエラーが出ていると思うのですが・・・

    インデックスが無効です。 (HRESULT からの例外: 0x8002000B (DISP_E_BADINDEX))


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2013年1月28日 6:47
    モデレータ
  • trapemiya様

    ありがとうございました。パラメータフィールドを作成しなおして解決しました。ありがとうございました。

    別件で質問をいたします。今回はラジオボタン1のテキスト名を表示させることができましたが、dt1にある得意先の敬称を

    表示させることはできますでしょうか?得意先ごとに敬称が異なります。

    たとえば、A会社なら御中、B商社なら様、C会社なら殿 になります。                              現状どの得意先もラジオボタン1の敬称のみになってしまっているからです。

    得意先ごとに敬称を変えたい場合はどうすればよいでしょうか?

    (パラメータのように入力しないで行いたいのですが)


    2013年1月29日 2:56
  • まず、とももとさんも印刷枚数を可変にされたいようですので、以下に私がサンプルコードを載せているようにして、印刷用データテーブルを別に作成された方がシンプルで考えやすいと思います。
    このコードでは個別に印刷枚数を変えていますが、敬称も同様に変更すれば良いでしょう。基本的にはデータテーブルの値の変更になります。変更するためのユーザーインターフェースはいろいろ考えらえますが、そこはとももとさんの設計になります。一番簡単なのは、DataGridViewにおいて、敬称を文字列で直接入力してもらう方法だと思いますが、それでは使い勝手が悪そうですので、DataGridViewの各行にコンボボックスを配置し、そこで選ぶようにするのが現実的かもしれません。

    VS2010PROでtextbox2.textに入力した数値だけ同じレコードのコピーをDataTableに追加したい
    http://social.msdn.microsoft.com/Forums/ja-JP/vbgeneralja/thread/832689c9-9581-4634-bbf3-a93569365a27


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    2013年1月29日 4:54
    モデレータ
  • trapemiyaさま 

    ありがとうございます

    敬称の選択をコンボボックスで配置しないとできないでしょうか?ラジオボタンでは無理でしょうか?データテーブルをデータグリッドビューで表示させた際に、敬称は得意先ごとに表示されていますので、何とか生かしたいのですが、厳しいでしょうか?

    参考すべきURLを見ました。敬称ですが、SQLの中に組み込んでいますね。                                3つの敬称の中から1つを選択いたしたく思います。どのようにすればよいでしょうか?                           敬称の選択をデータグリッドビューで各行にコンボボックスを配置した場合、クリスタルレポート上で得意先ごとに異なる敬称を印刷できるのでしょうか?

    質問が多く、恐縮です

    2013年1月29日 8:11
  • 敬称の選択をコンボボックスで配置しないとできないでしょうか?ラジオボタンでは無理でしょうか?

    DataGridViewの各行にラジオボタンを配置することは無理ではありませんが、敷居はかなり高くなります。

    (参考)
    Build a Custom RadioButton Cell and Column for the DataGridView Control
    http://msdn.microsoft.com/en-us/library/aa730882(VS.80).aspx

    敬称の選択をデータグリッドビューで各行にコンボボックスを配置した場合、クリスタルレポート上で得意先ごとに異なる敬称を印刷できるのでしょうか?

    とりあえず、私が先に示したサンプルコードを少し改造し、DataGridViewの各行にコンボボックスを表示するようにしてみました。

    Imports System.Data.OleDb
    
    Public Class 名簿印刷3
    
        Dim dt名簿 As DataTable = New DataTable()
        Dim dt印刷用 As DataTable
    
        Private Sub cbttn_名簿データ読み込み_Click(sender As System.Object, e As System.EventArgs) Handles cbttn_名簿データ読み込み.Click
    
            Dim cnn = New OleDbConnection
            Dim cmd = New OleDbCommand()
            Dim adapter = New OleDbDataAdapter
    
    
            cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\db1.mdb;Persist Security Info=Fals"
            cmd.Connection = cnn
    
            'データテーブルに印刷枚数を保持する列
            cmd.CommandText = "select ID, 氏名, '様' as 敬称, 住所, 0 as 印刷枚数 from 名簿"
    
            adapter.SelectCommand = cmd
            adapter.Fill(dt名簿)
    
            '「敬称」列の作成
            Dim 敬称col As New DataGridViewComboBoxColumn
            敬称col.HeaderText = "敬称"
            敬称col.Items.AddRange("様", "殿", "御中")
            敬称col.DataPropertyName = "敬称"
            敬称col.Name = "敬称comb"
    
            DataGridView1.DataSource = dt名簿
    
            '「敬称」列をComboBox列に置き換える。
            DataGridView1.Columns.Insert(DataGridView1.Columns("敬称").Index, 敬称col)
            DataGridView1.Columns.Remove("敬称")
    
            '「敬称」列の設定
            敬称col.FlatStyle = FlatStyle.Popup
            敬称col.DisplayStyleForCurrentCellOnly = True  'クリック後にコンボ表示を表示する。
    
    
        End Sub
    
        Private Sub cbttn_印刷データ作成_Click(sender As System.Object, e As System.EventArgs) Handles cbttn_印刷データ作成.Click
    
            dt印刷用 = dt名簿.Clone
    
            For Each dr In dt名簿.Rows
    
                For i = 1 To dr("印刷枚数")
                    dt印刷用.ImportRow(dr)
                Next
    
            Next
    
            DataGridView2.DataSource = dt印刷用
    
        End Sub
    
    End Class



    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/


    2013年1月30日 1:06
    モデレータ
  • trapemiya様

    ありがとうございます

    DataGridView1.Columns.Insert(DataGridView1.Columns("敬称").Index, 敬称col)          この部分で以下のエラーが出ます
    オブジェクト参照がオブジェクト インスタンスに設定されていません。と表示されます

    null を参照しようとして例外が発生しているとは思うのですが。

    お手数ですがご教授ください




    2013年1月30日 2:50
  • nullということは、おそらく「敬称」の指定が誤っていると思います。

    DataGridView1.Columns("敬称").Index の部分の「敬称」は、以下のSQL文における"敬称"と一致していなければなりません。

    select ID, 氏名, '様' as 敬称, 住所, 0 as 印刷枚数 from 名簿


    ★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/

    • 回答としてマーク とももと 2013年1月31日 5:50
    2013年1月30日 3:02
    モデレータ
  • trapemiya様

    ありがとうございました。ほかの方法を試してみます。

    2013年1月31日 3:29