none
印刷時に、前頁の小計金額を次ページの繰り越し行に正しく表示できず困っています RRS feed

  • 質問

  • zen73です。今年もどうぞよろしくお願いします。

    以前につくったアプリケーションの不具合を解消したいと思っています。

    DataGridViewのデータを3ページに分けて印刷しようとしています。

    trapemiyaさんに教えていただいて、完成と思っていたのですが

    私の点検が甘く下記のような不具合が生じております。

    年をとるのは悲しいもので、半年前に書いた自分のコードすらが理解できずに

    困り果てています。ぜひともお助け願います。

    <DataGridViewのデータ>

    月 日 大科目 小科目 適用 伝票 入金  出金   残高

    4 1 会費  会費     No1    10,000                 10,000 

    4 2 予備費 予備費    No2                  1,501      8,499

    4 3 総務部 会議費    No3                  1,100      7,399

    5 1 会費  会費     No4    15,000                22.399

    5 2 予備費 予備費    No5                     209   22,190   

    6 1 会費  会費     No6     7,000                29,190

    6 2 予備費 予備費    No7                 1,190    28,000

    <これを印刷すると次のようになってしまいます>

    --------- 1ページめ --------------------------------------------------------------------

    月 日 大科目 小科目 適用  伝票  入金  出金   残高

    4 1 会費  会費     No1      10,000                 10,000 

    4 2 予備費 予備費    No2                    1,501      8,499

    4 3 総務部 会議費    No3                    1,100      7,399

                小計             10,000      2,501      7,399  

     

    --------- 2ページめ --------------------------------------------------------------------

    月 日 大科目 小科目 適用  伝票  入金  出金   残高

                前ページより      42,000    6,601     35,399

    5 1 会費  会費     No4          15,000                 22.399

    5 2 予備費 予備費    No5                          209     22,190   

                小計                   57,000    6,810     50,190  

     

    --------- 3ページめ --------------------------------------------------------------------

    月 日 大科目 小科目 適用  伝票  入金  出金   残高

                前ページより      89,000    10,810    78,190

    6 1 会費  会費     No6            7,000                 29,190

    6 2 予備費 予備費    No7                         1,190    28,000

                小計                  96,000      12,000   84,000        

     

    --------- 4ページめ --------------------------------------------------------------------

    月 日 大科目 小科目 適用  伝票  入金  出金   残高

                前ページより       128,000  16,000   112,000

                合計          128,000  16,000   112,000  

     

     

    Code Snippet

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Drawing.Drawing2D;
    using System.Text;
    using System.Windows.Forms;

    namespace a_book
    {
        public partial class frm2SuitoPrt : Form
        {
            //印刷データ
            private string[,] hyoji = new string[500, 9];
            private int rowCnt = 0;
            private int page = 1;
            //改ページ変数
            int rnum;
            int maxRow = 4;
            int idx = 0;
            private int[] sLen = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            private int[] strLen = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            private int[] sum = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0 };

            public frm2SuitoPrt()
            {
                InitializeComponent();
            }

            //frm0Menuの変数値を参照する
            public frm0Menu frmMain;

            private void frm2SuitoPrt_Load(object sender, EventArgs e)
            {
                // データを 'suitoPrtDataSet.suito' テーブルに読み込む。
                this.suitoTableAdapter.Fill(this.suitoPrtDataSet.suito);
                //フォームの大きさを画面の解像度に合わせる
                this.Width = Screen.GetWorkingArea(this).Width - 5;
                this.Height = Screen.GetWorkingArea(this).Height - 2;
                this.Location = new Point(2, 2);
                //コントロールの配置位置調整
                btnPrint.Left = suitoDataGridView.Left;
                btnMenu.Left = suitoDataGridView.Right - btnMenu.Width;

                //ソート機能を無効にする
                for (int i = 0; i < 9; i++)
                {
                    suitoDataGridView.ColumnsIdea.SortMode = DataGridViewColumnSortMode.NotSortable;
                }

                suitoDataGridView.CurrentCell = null;
            }

            private void setArray(int i)
            {
                hyoji[i + idx + 1, 0] = "";
                hyoji[i + idx + 1, 1] = "";
                hyoji[i + idx + 1, 2] = "";
                hyoji[i + idx + 1, 3] = "";
                hyoji[i + idx + 1, 4] = "次頁へ繰越";
                hyoji[i + idx + 1, 5] = "小計";
                hyoji[i + idx + 1, 6] = sumDevil.ToString("#,###").PadLeft(10);
                hyoji[i + idx + 1, 7] = sum[7].ToString("#,###").PadLeft(10);
                hyoji[i + idx + 1, 8] = (sumDevil - sum[7]).ToString("#,###").PadLeft(10);
                hyoji[i + idx + 2, 0] = "";
                hyoji[i + idx + 2, 1] = "";
                hyoji[i + idx + 2, 2] = "";
                hyoji[i + idx + 2, 3] = "";
                hyoji[i + idx + 2, 4] = "前頁より繰越";
                hyoji[i + idx + 2, 5] = "";
                hyoji[i + idx + 2, 6] = sumDevil.ToString("#,###").PadLeft(10);
                hyoji[i + idx + 2, 7] = sum[7].ToString("#,###").PadLeft(10);
                hyoji[i + idx + 2, 8] = (sumDevil - sum[7]).ToString("#,###").PadLeft(10);
            }
            private void setHyoji(int i, int j)
            {
                int iVal;
                if (suitoDataGridView[j + 1, i].Value != DBNull.Value)
                {
                    iVal = Convert.ToInt32(suitoDataGridView[j + 1, i].Value);
                    hyoji[i + idx, j] = iVal.ToString("#,###").PadLeft(10);
                    sum[j] += iVal;
                }
                else
                {
                    hyoji[i + idx, j] = suitoDataGridView[j + 1, i].Value.ToString();
                }
            }
            private void leftPad(int i, int j)
            {
                hyoji[i + idx, j] = suitoDataGridView[j + 1, i].Value.ToString().PadLeft(2);
            }
            private void btnPrint_Click(object sender, EventArgs e)
            {
                //----------------------------------------------------
                //// VS PreviewDialog  ///////////////
                //PrintPreviewDialog prv = new PrintPreviewDialog();
                //prv.Document = printDocument1;
                //prv.Width = 500;
                //prv.Height = 500;
                //prv.ShowDialog();
                //----------------------------------------------------
                //// CanonPrintDialog  ///////////////
                    System.Drawing.Printing.PrintDocument pd =
                        new System.Drawing.Printing.PrintDocument();
                    pd.PrintPage +=
                        new System.Drawing.Printing.PrintPageEventHandler(printDocument1_PrintPage);
                    PrintDialog pdlg = new PrintDialog();
                    pdlg.Document = printDocument1;
                    if (pdlg.ShowDialog() == DialogResult.OK)
                        printDocument1.Print();
            }

            private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
            {
               
                int i;
                int num = 0;
                idx = 0;
                Encoding sjisEnc = Encoding.GetEncoding("Shift_JIS");
                rowCnt = suitoDataGridView.RowCount - 1;
                for (i = 0; i < rowCnt; i++)
                {
                    for (int j = 0; j < 9; j++)
                    {
                        switch (j)
                        {
                            case 0:
                                leftPad(i, j);
                                break;
                            case 1:
                                leftPad(i, j);
                                break;
                            case 6:
                            case 7:
                            case 8:
                                setHyoji(i, j);
                                break;
                            default:
                                hyoji[i + idx, j] = suitoDataGridView[j + 1, i].Value.ToString();
                                break;
                        }
                        //文字列の長さ(Byte単位)
                        num = sjisEnc.GetByteCount(hyoji[i + idx, j]);
                        if (sLen[j] < num) sLen[j] = num;
                        if (strLen[j] < hyoji[i + idx, j].Length) strLen[j] = hyoji[i + idx, j].Length;
                    }

                    if (i != 0 && (i % (maxRow - 2) == 0))
                    {
                        setArray(i);
                        idx += 2;
                    }
                }
                hyoji[i + idx, 0] = "";
                hyoji[i + idx, 1] = "";
                hyoji[i + idx, 2] = "";
                hyoji[i + idx, 3] = "";
                hyoji[i + idx, 4] = "合 計";
                hyoji[i + idx, 5] = "";
                hyoji[i + idx, 6] = sumDevil.ToString("#,###").PadLeft(10);
                hyoji[i + idx, 7] = sum[7].ToString("#,###").PadLeft(10);
                hyoji[i + idx, 8] = (sumDevil - sum[7]).ToString("#,###").PadLeft(10);
                //増やした列数
                rowCnt += idx + 1;

                //標題
                string title = "出 納 帳";
                int strX = 0;
                //フォント
                Font f = new Font("MS ゴシック", 11);
                int x = 50, y = 90;         //印刷開始位置
                int pitch = f.Height + 3;   //行ピッチ
                int Apage;                  //ページ番号
                int cnt = 0;                //印刷開始行
                //-----表罫線-------------------------------
                int topX = x;
                int topY;
                int[] moveX = new int[9];   //縦罫線の位置
                int[] moveS = new int[9];   //文字列の位置
                //セルの色(収入/支出&大科目/小科目&見出し)
                //小計
                HatchBrush hBrushOs = new HatchBrush(HatchStyle.LightDownwardDiagonal, Color.MistyRose, Color.White);
                //1行置き
                HatchBrush hBrushOg = new HatchBrush(HatchStyle.LightDownwardDiagonal, Color.Honeydew, Color.White);
                //総計
                HatchBrush hBrushOt = new HatchBrush(HatchStyle.LightDownwardDiagonal, Color.Lavender, Color.White);
                //ヘッダー
                HatchBrush hBrushOO = new HatchBrush(HatchStyle.LightDownwardDiagonal, Color.DarkSeaGreen, Color.White);
                moveX[0] = x;
                moveX[1] = moveX[0] + 23;
                moveX[2] = moveX[1] + 23;
                moveX[3] = moveX[2] + sLen[2] * 9;
                moveX[4] = moveX[3] + sLen[3] * 9;
                moveX[5] = moveX[4] + sLen[4] * 9;
                moveXDevil = moveX[5] + 46;
                moveX[7] = moveXDevil + 88;
                moveXMusic = moveX[7] + 88;
                int rectWidth = moveXMusic + 38;
                int leftX = topX + rectWidth;
                int rectHeight;
                int botomY;
                for (i = 0; i < 9; i++)
                {
                    moveSIdea = moveXIdea + 2;
                }
                string[] head = new string[]
                { "月", "日", "大科目", "小科目", "   摘    要", "伝票", "  入  金", "  出  金", "  残  高" };
                string[] headW = new string[] { "月", "日", "大 科 目", "小 科 目" };
                int lastMoneyLineY = 0;
                //------------------------------------------
                //下に罫線を引くときのペン
                Pen underlinePen = new Pen(Color.Black, 0.3F);
                //標題
                e.Graphics.DrawString(title, f, Brushes.Black, x + 50, y - 27);
                //日付
                f = new Font("MS 明朝", 9);
                System.Globalization.CultureInfo ci = new System.Globalization.CultureInfo("ja-JP");
                System.Globalization.DateTimeFormatInfo dtfi = ci.DateTimeFormat;
                dtfi.Calendar = new System.Globalization.JapaneseCalendar();
                System.DateTime dTime = System.DateTime.Now;
                e.Graphics.DrawString(dTime.ToString("ggy年M月d日 現在", dtfi), f, Brushes.Black, leftX - 138, y - 17);
                //ページ番号
                f = new Font("MS ゴシック", 10);
                Apage = (rowCnt % maxRow == 0) ? rowCnt / maxRow : rowCnt / maxRow + 1;
                e.Graphics.DrawString(page + "/" + Apage + "page", f, Brushes.Black, leftX - 55, y - 35);

                //見出し
                f = new Font("MS ゴシック", 11);
                string hedStr;
                //int strX;

                //セルの色
                int y1 = y + f.Height - 1;
                int headlineY = y1;
                e.Graphics.FillRectangle(hBrushOO, topX, y1 - 20, leftX - topX, pitch - 2);
                //セル小計前頁より
                if (page > 1)
                    e.Graphics.FillRectangle(hBrushOs, topX, y1, leftX - topX, pitch);
                for (i = 0; i < 9; i++)
                {
                    switch (i)
                    {
                        case 2:
                        case 3:
                            switch (strLenIdea)
                            {
                                case 1:
                                case 2:
                                case 3:
                                    strX = 0;
                                    hedStr = headIdea;
                                    break;
                                case 4:
                                    strX = 7;
                                    hedStr = headIdea;
                                    break;
                                case 5:
                                    strX = 7;
                                    hedStr = headWIdea;
                                    break;
                                default:
                                    strX = 15;
                                    hedStr = headWIdea;
                                    break;
                            }
                            e.Graphics.DrawString(hedStr, f, Brushes.Black, moveSIdea + strX, y);
                            break;
                        case 5:
                            strX = 2;
                            e.Graphics.DrawString(headIdea, f, Brushes.Black, moveSIdea + strX, y);
                            break;
                        default :
                            strX = 0;
                            e.Graphics.DrawString(headIdea, f, Brushes.Black, moveSIdea + strX, y);
                            break;
                    }
                    //e.Graphics.DrawString(hedStr , f, Brushes.Black, moveSIdea + strX, y);
                }
                //見出しの下の直線
                //int y1 = y + f.Height - 1;
                //int headlineY = y1;
                e.Graphics.DrawLine(Pens.Black, topX, y1, leftX, y1);
                y += pitch;
                topY = y - pitch - 2;
                lastMoneyLineY = topY;

                f = new Font("MS 明朝", 11);
                do
                {
                    if (rnum <= rowCnt)
                    {
                        //セルの色
                        y1 = y + ((cnt + 1) * pitch) - 3;
                        //セル1行置き
                        if (cnt % 2 == 0 && cnt < maxRow - 1 && rnum < rowCnt -1)
                            e.Graphics.FillRectangle(hBrushOg, topX, y1, leftX - topX, pitch);
                        //小計セル次頁へ
                        if (cnt == maxRow - 2)
                            e.Graphics.FillRectangle(hBrushOs, topX, y1, leftX - topX, pitch);
                        //総計セル
                        if (rnum == rowCnt - 2)
                            e.Graphics.FillRectangle(hBrushOt, topX, y1, leftX - topX, pitch);
                        for (i = 0; i < 9; i++)
                        {
                            e.Graphics.DrawString(hyoji[rnum, i], f, Brushes.Black, moveSIdea, y + cnt * pitch);
                        }
                        //下に横罫線
                        y1 = y + ((cnt + 1) * pitch) - 3;
                        e.Graphics.DrawLine(underlinePen, topX, y1, leftX, y1);
                        lastMoneyLineY = y1;
                    }

                    //行番号の更新
                    rnum++;
                    cnt++;
                    //改ページの確認
                    if (cnt >= maxRow)
                    {
                        //枠罫線
                        rectHeight = pitch * (maxRow + 1) - 1;
                        e.Graphics.DrawRectangle(Pens.Black, topX, topY, rectWidth, rectHeight);
                        //縦罫線
                        botomY = topY + rectHeight;
                        for (i = 0; i < 9; i++)
                        {
                            e.Graphics.DrawLine(underlinePen, moveXIdea, topY, moveXIdea, lastMoneyLineY);
                        }
                        e.HasMorePages = true;
                        page++;
                        break;
                    }
                } while (rnum != rowCnt);
                //最終ページの罫線
                if (rnum == rowCnt)
                {
                    //枠罫線
                    rectHeight = pitch * (rnum % maxRow + 1) - 1;
                    e.Graphics.DrawRectangle(Pens.Black, topX, topY, rectWidth, rectHeight);
                    //縦罫線
                    botomY = topY + rectHeight;
                    for (i = 0; i < 9; i++)
                    {
                        e.Graphics.DrawLine(underlinePen, moveXIdea, topY, moveXIdea, lastMoneyLineY);
                    }
                }
            }

            private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
            {
                rnum = 0;
                page = 1;
            }

            private void printPreviewDialog1_FormClosed(object sender, FormClosedEventArgs e)
            {
                //rnum = 0;
            }

            private void btnMenu_Click(object sender, EventArgs e)
            {
                frmMain.TopMost = true;
                this.Close();
                frmMain.TopMost = false;
            }

            //列幅変更のときの処理
            private void suitoDataGridView_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
            {
                DataGridView dgv = (DataGridView)sender;
                //ヘッダーの幅(0)+スクロールバーの幅(28)
                int dgvWidth = 20;
                for (int i = 1; i < 10; i++)
                {
                    dgvWidth += dgv.ColumnsIdea.Width;
                }
                dgv.Width = dgvWidth;
                dgvToCenter();
            }
            //左右中央配置
            private void dgvToCenter()
            {
                suitoDataGridView.Left = (this.ClientSize.Width - suitoDataGridView.Width) / 2;
                btnPrint.Left = suitoDataGridView.Left;
                btnMenu.Left = suitoDataGridView.Right - btnMenu.Width;
            }

            private void printDocument1_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
            {
               
            }

            private void frm2SuitoPrt_Resize(object sender, EventArgs e)
            {
                dgvToCenter();
            }

            private void suitoDataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
            {
                if (suitoDataGridView[e.ColumnIndex, e.RowIndex].Selected)
                    e.CellStyle.SelectionBackColor = suitoDataGridView.CurrentCell.Style.BackColor;
            }
        }
    }

     

     

    2009年1月11日 6:40

回答

  •  zen73 さんからの引用

    年をとるのは悲しいもので、半年前に書いた自分のコードすらが理解できずに

    困り果てています。ぜひともお助け願います。

    ソースを読んで、不具合を解析しろということを求めているのでしょうか?

    回答者は仕事の請負人ではありませんので、コードをぺたっと貼り付けて、「お願いします」と書かれても困ります。

    ご自身で読み解き、不具合を見つけるやり方を身につけて下さい。

     

    また、昔のコードが読めないということはよくある話ですが、この部分は何をするために書いているか等、コメントを書いておくと良いでしょう。

     

    -----

    実行結果を整理すると法則性が見えませんか?

     

    2ページ目の前ページより 42,000 - 1ページ目の小計 10,000 = 32,000

    3ページ目の前ページより 89,000 - 2ページ目の小計 57,000 = 32,000

    4ページ目の前ページより 128,000 - 3ページ目の小計 96,000 = 32,000

     

    このことから、余計な足し算が行われているのであろうことが推測できます。

    32,000は本来の入金額の合計ですよね。

    このあたりから、調べてみては?

     

    なお、デバッグでブレークポイントを置いたり、ウォッチを使って変数の値を見ることは重要です。

    意図した動きと異なるような数値の動きをしていたら、なぜそうなったかを追えるようにデバッグ機能を使い込んで下さい。

     

    2009年1月11日 7:58
    モデレータ

すべての返信

  •  zen73 さんからの引用

    年をとるのは悲しいもので、半年前に書いた自分のコードすらが理解できずに

    困り果てています。ぜひともお助け願います。

    ソースを読んで、不具合を解析しろということを求めているのでしょうか?

    回答者は仕事の請負人ではありませんので、コードをぺたっと貼り付けて、「お願いします」と書かれても困ります。

    ご自身で読み解き、不具合を見つけるやり方を身につけて下さい。

     

    また、昔のコードが読めないということはよくある話ですが、この部分は何をするために書いているか等、コメントを書いておくと良いでしょう。

     

    -----

    実行結果を整理すると法則性が見えませんか?

     

    2ページ目の前ページより 42,000 - 1ページ目の小計 10,000 = 32,000

    3ページ目の前ページより 89,000 - 2ページ目の小計 57,000 = 32,000

    4ページ目の前ページより 128,000 - 3ページ目の小計 96,000 = 32,000

     

    このことから、余計な足し算が行われているのであろうことが推測できます。

    32,000は本来の入金額の合計ですよね。

    このあたりから、調べてみては?

     

    なお、デバッグでブレークポイントを置いたり、ウォッチを使って変数の値を見ることは重要です。

    意図した動きと異なるような数値の動きをしていたら、なぜそうなったかを追えるようにデバッグ機能を使い込んで下さい。

     

    2009年1月11日 7:58
    モデレータ
  • Azuleanさん、ありがとうございました。なんとか解決することができました。

     Azulean さんからの引用

    実行結果を整理すると法則性が見えませんか?

     

    2ページ目の前ページより 42,000 - 1ページ目の小計 10,000 = 32,000

    3ページ目の前ページより 89,000 - 2ページ目の小計 57,000 = 32,000

    4ページ目の前ページより 128,000 - 3ページ目の小計 96,000 = 32,000

     

    このことから、余計な足し算が行われているのであろうことが推測できます。

    32,000は本来の入金額の合計ですよね。

    このあたりから、調べてみては?

    このアドバイスを頂いて、コードを修正してみました。

    bool firstPage = true; という変数を用いてページの小計計算をダブらないよう下のように修正することで解決することができました。

     Azulean さんからの引用

    ソースを読んで、不具合を解析しろということを求めているのでしょうか?

    回答者は仕事の請負人ではありませんので、コードをぺたっと貼り付けて、「お願いします」と書かれても困ります。

    ご自身で読み解き、不具合を見つけるやり方を身につけて下さい。

    お叱りを受けるのは当然でした。反省しております。おかげさまで、高価なソフトを買わなくてもDataGridViewのデータを罫線付きで複数ページに印刷することができるようになりました。

     

    Code Snippet

            private void setArray(int i)
            {
                if (firstPage == true)
                {
                    hyoji[i + idx + 1, 0] = "";
                    hyoji[i + idx + 1, 1] = "";
                    hyoji[i + idx + 1, 2] = "";
                    hyoji[i + idx + 1, 3] = "";
                    hyoji[i + idx + 1, 4] = "次頁へ繰越";
                    //------------------------------------------------------

                    //------------------------------------------------------
                    hyoji[i + idx + 2, 7] = sum[7].ToString("#,###").PadLeft(10);
                    hyoji[i + idx + 2, 8] = (sum[6] - sum[7]).ToString("#,###").PadLeft(10);
                }
            }

     

                if (firstPage == true)
                {
                    hyoji[i + idx, 0] = "";
                    hyoji[i + idx, 1] = "";
                    //-----------------------------------------------------

                    hyoji[i + idx, 7] = sum[7].ToString("#,###").PadLeft(10);
                    hyoji[i + idx, 8] = (sum[6] - sum[7]).ToString("#,###").PadLeft(10);
                }

                rowCnt += idx + 1;

     

                do
                {
                    if (rnum <= rowCnt)
                    {

                       //---------------------------------------
                    }

                    //行番号の更新
                    rnum++;
                    cnt++;
                    //改ページの確認
                    if (cnt >= maxRow)
                    {
                        firstPage = false;

                        e.HasMorePages = true;
                        page++;
                        break;
                    }
                } while (rnum != rowCnt);

     

     

    2009年1月11日 11:55