none
DatagridViewからグループ単位で抽出したデータをグループ毎の表として印刷したいのですが… RRS feed

  • 質問

  • グループが二つだけのときは次のようにして印刷できることを確認しています。
    
    private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    
    {
    
      グループAのデータを配列 dataA[i, j]に取り込む
    
      グループAのデータを配列 dataB[i, j]に取り込む
    
      //データ印刷部分のみが異なる描画部を二つ用意する
    
      ---------------------------------------------------------
    
      e.Graphics.DrawString(dataA[rnum, i], f, ・・・
    
      ---------------------------------------------------------
    
      e.Graphics.DrawString(dataB[rnum, i], f, ・・・
    
      ---------------------------------------------------------
    
    }
    しかし実際の場面では使用者毎にグループの数が異なるので上記のような方法を用いることができず悩んでいます。
    
    だめもとで次のようにしてみました。
    
    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    
      {
    
       //配列 hanmei[] の要素はグループ名
    
       y = 90; //表の描きだし位置指定
    
       for (int i = 0; i <hanmei.Length; i++)
    
       {
    
        //標題
    
        title = "会費収納簿[" + hanmei[i] + "]";
    
        //データ読込
    
        dvGroup.RowFilter = "group='" + hanmei[i] + "'";
    
        //suitoDataGridView.DataSource = dvGroup;
    
        toRead();  //データをdataA[ , ]に取り込む
    
        drawLine(e); //データの表を描く
    
        y += 100;
    
       }
    
      }
    
    
    
    当然でしょうけど,最初のグーループの表だけがきちんと印刷されましたが,他のグループは表にすらなっていませんでした。
    
    <対処法>(の前に drawLine(e); の記述場所が疑問ですが…)
    
     ● グループ毎にデータの配列名を変更する方法を考える
    
     ● 描画部でも異なる配列名に対応させる方法を考える
    
    
    
    このようなことは果たして可能なのでしょうか?。それとも別のほうほうがあるのでしょうか?。
    
    ご教授のほど,よろしくおねがいします。
    
    
    
    

    zen73
    2010年8月23日 0:34

回答

  • zen73 さん
    > 当然でしょうけど,最初のグーループの表だけがきちんと印刷されましたが,
    > 他のグループは表にすらなっていませんでした。

    当然の結果というわけではなく、drawLine メソッドに書かれたコード次第かと思いますし、別配列にすれば解決するという話でもないと思いました。

    現在の仕様ですが、以下のどれでしょうか?

    a) 全グループが1ページに収まる。
    b) 1グループは1ページに収まり、グループが変われば改ページする。
    c) 1グループが(表が)ページをまたがることもある。

    a の場合、drawLine メソッドの中身を変更すれば、現在の zen73 さんのアプローチで実現できると思います。
    b の場合、drawLine の変更に加え、PrintPage イベントハンドラ内のコードも変更する必要がありますが、少しの変更で対処できると思います。
    c の場合ですと、それなりに変更が必要そうです。

    上記はグループごとに表があるイメージで書いていますが、もしかして1グループは表の1行になるのでしょうか?
    (RowFilter でグループごとに絞り込み、配列に格納する際に行データを列データに変換して1行にされているとかですかね?)
    もしそうですと、c の可能性が高くなるかと想像しました。

    ちなみに、大きなお世話でしょうけど、次のことを思いました。
    現在はすべての印刷をコーディングされているようですが、もしも印刷結果のデザインに大きなこだわりがないようでしたら、Microsoft Report などのレポートコントロール(Microsoft Report は一例)の利用を検討されてはと思いました。
    もちろん、そのコントロールの使い方を習得する必要がありますし、場合によっては実現できないことも発生してしまう可能性もありますが、多くの場合において作成および保守が楽になると私は考えます。

    • 回答としてマーク zen73 2010年8月24日 1:43
    2010年8月23日 9:32

すべての返信

  • <対処法>(の前に drawLine(e); の記述場所が疑問ですが…)

     ● グループ毎にデータの配列名を変更する方法を考える

     ● 描画部でも異なる配列名に対応させる方法を考える

    このようなことは果たして可能なのでしょうか?。それとも別のほうほうがあるのでしょうか?。

    zen73


    toRead がどこからデータを読み込んでいるかはわかりませんが、

    • toRead メソッドは読み込んだデータを返すようにして、それをローカル変数に格納
    • drawLine に、e だけでなく、ローカル変数に格納してある toRead の戻り値も引数として渡す
    • drawLine 内では渡されたデータを使って描画する

    という感じで実装すればいいのではないでしょうか?

     


    なかむら(http://d.hatena.ne.jp/griefworker)
    2010年8月23日 3:23
  • zen73 さん
    > 当然でしょうけど,最初のグーループの表だけがきちんと印刷されましたが,
    > 他のグループは表にすらなっていませんでした。

    当然の結果というわけではなく、drawLine メソッドに書かれたコード次第かと思いますし、別配列にすれば解決するという話でもないと思いました。

    現在の仕様ですが、以下のどれでしょうか?

    a) 全グループが1ページに収まる。
    b) 1グループは1ページに収まり、グループが変われば改ページする。
    c) 1グループが(表が)ページをまたがることもある。

    a の場合、drawLine メソッドの中身を変更すれば、現在の zen73 さんのアプローチで実現できると思います。
    b の場合、drawLine の変更に加え、PrintPage イベントハンドラ内のコードも変更する必要がありますが、少しの変更で対処できると思います。
    c の場合ですと、それなりに変更が必要そうです。

    上記はグループごとに表があるイメージで書いていますが、もしかして1グループは表の1行になるのでしょうか?
    (RowFilter でグループごとに絞り込み、配列に格納する際に行データを列データに変換して1行にされているとかですかね?)
    もしそうですと、c の可能性が高くなるかと想像しました。

    ちなみに、大きなお世話でしょうけど、次のことを思いました。
    現在はすべての印刷をコーディングされているようですが、もしも印刷結果のデザインに大きなこだわりがないようでしたら、Microsoft Report などのレポートコントロール(Microsoft Report は一例)の利用を検討されてはと思いました。
    もちろん、そのコントロールの使い方を習得する必要がありますし、場合によっては実現できないことも発生してしまう可能性もありますが、多くの場合において作成および保守が楽になると私は考えます。

    • 回答としてマーク zen73 2010年8月24日 1:43
    2010年8月23日 9:32
  • 現在の仕様ですが、以下のどれでしょうか?

    C です。

    当然の結果というわけではなく、drawLine メソッドに書かれたコード次第かと思いますし、別配列にすれば解決するという話でもないと思いました。

    半ば諦めていたのですが,現在のコードを修正すればできるとの確信を得させていただきました。
    drawLine(e) を検討してみた結果,下のように2つの変数を初期化することによってグループ別の表を描くことができるようになりました。(改ページの条件を考えねばなりませんが)
    なかむらさん,TH01さん,ありがとうございました。

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
      //配列 hanmei[] の要素はグループ名
      y = 90; //表の描きだし位置指定
      //for (int i = 0; i <hanmei.Length; i++)
      for (int i = 0; i <3; i++)
      {
        //標題
        title = "会費収納簿[" + hanmei[i] + "]";
        //データ読込
        dvGroup.RowFilter = "group='" + hanmei[i] + "'";
        //suitoDataGridView.DataSource = dvGroup;
        toRead();    //データをdataA[ , ]に取り込む
    
        //描画するレコード数
        rowCnt = suitoDataGridView.RowCount + 1;
        //描画終了のレコード数
        rnum = 0; 
        
        drawLine(e);  //データの表を描く
        y += 200;
      }
    }

     


    zen73
    2010年8月24日 1:42