Groupヘッダ・フッタのTextBoxの値を明細データによって制御したい [ActiveReports] [ActiveReports]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005

ActiveReports 2.0J Standard

----------------------------------------------------------

 

タイトルの文言では、いまいち何を言いたいかわかりにくい。。。

語彙不足。。。

 

さて、何がしたいかと申しますと。

 明細データを項目の属性別に値を集計するときに、その属性毎にGroupHeader(又はFooter)のTextBoxの文字を変えたいような場合、ですね。

言い換えると、項目の属性別にグルーピングして、グループごと名前の表示を変えたいってことです。

(例えば・・・コーラ、オレンジジュース、お茶・・・飲料合計金額、パン、おにぎり、カップ麺・・・食料品合計金額、みたいな。伝わった?汗)

 

ActiveReportsは、めんどくさい(のか楽チンなのかよくわからない)ことに、データの数だけ勝手にレポートに出力してくれるんですが、各Sectionのデータの出力タイミングがどうにも制御しずらく、Detail SectionのTextBoxのデータをGroupFooter のFormatイベントで引っ張ってきても、データ行が一つズレていたりして、Groupの制御がうまくいかなかったんです。

 なので、色々あーだこーだ試行錯誤した結果、 やっと自分なりに汎用的(?)な解決策が。

 

 制御したいGroupのSectionにTextBoxを置いて、Visible = False とする。

 このTextBoxをInitializeフィールドで、属性のデータを持つDataFieldsにバインドする。

属性TextBoxの値によって行う制御を、各SectionのFormatイベントに記述する。

 

これでどーにか、Group別にうまく制御することができましたとさ。

まぁ気づけばどうってことないんですけどね。。。

 

(今更ですが)文章が下手ですいません。

 

ActiveReports、うだうだ悩むよりガチャガチャイジって、理屈より経験的に覚えようかと思います。



TextBox に数字しか入力できないようにしたい  ~AddHandlerでイベント追加~ [コントロール]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005

----------------------------------------------------------

DBのデータ型が数値型なのに、文字列が入力できたり、数値で集計するデータに文字列が入るとマズいわけで。

 

TextBoxに数字以外の入力制限をかけたいわけです。

 

TextBoxのKeyPress イベントにて、

    数値であるか否か
         http://jeanne.wankuma.com/tips/vb.net/char/isdigit.html      

    制御文字であるか否か(EnterとかTabとか)    

を判断し、数値と制御文字でなければ、処理をキャンセルします。

 

以下、ソース。

     If (Not (Char.IsDigit(e.KeyChar) _
            Or Char.IsControl(e.KeyChar) _
            Or (e.KeyChar = Chr(46)))) Then

            e.Handled = True
        End If
 

 

chr(46)は「.」。

http://higasumi.blog100.fc2.com/blog-category-17.html

今回は整数だけど、小数点使うなら、

   「.」が文字の中に存在するか否か(二個以上「.」を出したくない)

   先頭が「.」じゃないか

の制御も必要になってきますね。

 

 

e.Handled = True で、イベントのキャンセル。

http://d.hatena.ne.jp/annin102/20070303/1172936508

 

 

 

さて、実装。

自分、今までは作業をするたびにイベントを実行していたのですが。。。

イベントプロシージャのHandles以下を消去してあげる。

       Private Sub TextBox_KeyPress( _
                 ByVal sender As System.Object, _
                 ByVal e As System.Windows.Forms.KeyPressEventArgs)
 

 

こいつを、AddHandlerステートメントをFormのLoadイベント等で追加してあげる。

   AddHandler TextBox1.KeyPress, AddressOf TextBox_KeyPress

 

 

こうすると、Load時にイベントプロシージャを通るだけで、イベントごとにいちいち処理を通さない。

なんかよさげ☆

 (追記:勘違いだったっぽい。。普通のサブルーチンと同じような扱い方ができる、ってメリットがあるかな。)

 

そして、AddHandlerステートメントを呼び出す関数をグローバルで(共通モジュール等で)もってあげれば、

イベントをグローバル(共通)関数として、色んな場所から同じ処理を呼んであげられる。

 

今までイベントは全部ローカルでやっていたので。。。

これからはもう少しサクサク作れるようになるぞぃ♪

 

 

以下、参考。

http://dobon.net/vb/dotnet/beginner/eventhandle.html

 

こんなんもあったけど、はてさて。。。?

http://dobon.net/vb/dotnet/control/numerictextbox.html

 


FormとDialog [コントロール]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005

----------------------------------------------------------

 プロジェクトに新しい項目を追加する画面には、Windowsフォームとダイアログがありますが、

大元は同じもののようですね。

ダイアログの方は初めからDialogとして使いやすい(?) ような設定がされているようですが、

なんにしてもあのボタンをそのまま流用しにくい。。

 

てことで結局WindowsフォームからDialog作るんだよねw

 

唯一つ注意が。

今回、DialogがActiveなときにEscキーで呼び出し元に戻るように、FormのCancelButtonプロパティに、

「戻る」ボタンを設定しておいたんです(これでEscキーで画面を閉じれます) 。

 

これを当初の仕様と少し変えたんです。

 「戻る」ボタン押下時に「戻ってよいか?」メッセージを出すことにしたので、当然Escキーでの画面Close処理は不要となり、

CancelButtonプロパティから「戻る」ボタンを外したんです。

 

でも。。

「戻ってよいか?」メッセージ で「いいえ」を選択しても画面が閉じてしまう!!

 

頑張って探してやっとわかった。

一度CancelButtonプロパティに設定したButtonコントロールは、DialogResultプロパティが勝手にCancelになってしまうみたい。

CancelButton プロパティから外してもそのまま残るため、そのボタンを押すと、Clickイベントを抜けた後に画面を閉じてしまう。。

 

試してないから確かなことは言えないが、AcceptButtonプロパティも多分同様の挙動を示すんだろうな。

不毛な時間を過ごすから、注意しないといけませんね。


ActiveReportsのページフッタにページ番号を印字する [ActiveReports]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005

ActiveReports 2.0J Standard

----------------------------------------------------------

 

 作成したレポートのページフッタに、「現在ページ/総ページ」を尋常に出力する場合は、以下のコードをレポートの作成する最初(ReportStartイベントとか)に宣言し、TextBoxに適用すればいいらしい。

(今回はやってないから知らんけど)

    'カレントページ数
    Me.txtPage.SummaryRunning = SummaryRunning.All
    Me.txtPage.SummaryType = SummaryType.PageCount
    '総ページ数
    Me.txtPages.SummaryRunning = SummaryRunning.None
    Me.txtPages.SummaryType = SummaryType.PageCount
 

 

今回やろうとしたのは、作成するレポートの中でも、キー項目が変更されたら改ページして、ページ番号を1にリセットする、というもの。

つまり、レポートで出力するページ数が10ページあっても、毎ページキー項目が変更になったら、全てのページ番号が1となるし、10ページ全て同じキー項目であれば、1~10を振る、ということ。

総ページの出力はしなかった。

 

ActiveReportsに出力するデータを格納した配列の、各レコードにページ番号も持たせ、DataInitializeイベントでアンバウンドフィールド(バウンドフィールド? ごめんなさい、よく言葉を知らない。。)を作ってレポート上のTextBoxと紐付け。

FetchDataイベントで配列の値をバウンドフィールドに当てるという、データの出力方法と同様に、ページ番号もページフッタに出力しようと試みた。

 

・・・が、配列のデータは正しく作れているのに、ページ番号がズレて表示される。。。

 

どうもページヘッダ・フッタには、変化するデータの値を使ってはいけないらしい。。。

http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=37912&forum=7

https://www.grapecity.com/Japan/Support/Search/FaqContent.asp?id=13371

 

Detailやグループヘッダ・フッタと違って、ページヘッダは配列がまわる度に値を入れてくれないらしい。。

グループフッタにすると、1ページ目と2ページ目以降で出力位置がビミョーに変わるからそこに置きたくなく。。。 (レイアウトが変わるので)

 

あまりきれいな方法じゃないんだろうけど、DetailFormatイベントで、新しいページに変わるときに(If文による制御)、ページ番号のTextBoxのTextプロパティに、配列の値を入れていくことにした。

 

でも今回これで完成でもないし、どうなることやら。。

 他にいい方法知ってる方いたら教えてください。

(その前に拙い文章ですいません。。)

 

ActiveReports・・・

クリレポと全然違うし、難しいな~。。


ActiveReportsでの印刷時にイベントをとる [ActiveReports]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005

ActiveReports 2.0J Standard

----------------------------------------------------------

 

ActiveReports(AC)による帳票印刷時に、印刷フラグを立てる場合など。

CrystalReports(CR)を使うと、プレビューを出す場合はプレビュー表示以後、OSでの処理になって

イベントがとれなかった。

よって、プレビュー画面に自分で印刷ボタンを用意して対応せざるを得なかったが・・・。

 

ACでは、印刷プレビューから呼んだ印刷ダイアログのOKボタン押下時にイベントをとれるんです。

 

   OnEndPrintイベント

 

素敵☆

 

プレビュー画面のLord時に以下でイベントに関連付け。

 

            AddHandler .Document.Printer.EndPrint, AddressOf onEndPrint

 

 そして、以下のイベント処理。

 

    Private Sub onEndPrint(ByVal sender As Object, ByVal e As _ System.Drawing.Printing.PrintEventArgs)

  ~~~~~~~~~~~~

   End Sub

 

GrapeCityのHPから「サポート」→「よくある質問」で探せます。

 http://www.grapecity.com/japan/support/

 

 


CheckBoxのReadOnlyプロパティ [VB.NET]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005
----------------------------------------------------------

 

vb.netには、CheckBoxコントロールにReadOnlyプロパティがついていません。

 CheckBoxイジれなくしたいのに・・・

どげんすっとか!

 

enableプロパティをfalseにするのも色が見えなくなるから嫌だし・・・。

 

でも実は簡単にできる事を発見。

 

    AutoCheckプロパティ = false

 

こんだけ。

 らくちん♪

なんでこんな名前なんやろ。。。


色のカスタム   ~便利ツール♪  そして目を大事に・・・~ [Break]

 

グリッドなんか特にそうだけど、 背景色をカスタムしたいとき

の便利ツール。

 

http://tomari.org/main/applets/iro/gen.html

 

まったく同じ色にはなんないけど、これでアタリつけてから、

デバッグして微調整。

 超便利[るんるん]

 

 

今回の要望が「目に優しい色」っていわれたんでググッてみると・・・

 面白かったですわw

 

http://pc11.2ch.net/test/read.cgi/desktop/1122045367/

http://yukitachi.cool.ne.jp/column/c010menotsukare.html

 

 

ちなみに以下で、グリッドの奇数行だけカスタム色に設定。

 p_Grd.AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(190, 255, 190)

 

 

でも結局、コアユーザーじゃないふつーの人は(オレも含め)、

明るい画面を求めるんだよね。

このブログももう少し目に優しい配色にしようかしら。。。


画面Load時、controlへのFocus [コントロール]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005
----------------------------------------------------------

 (課題)

 画面Load時、

(control).Focus

してもFocusしてくれない!

 

(解決法)

同じ悩みを持った人、割と多い気がするんだけど。

(オレだけ?)

初期化するときとか。

(前開いたときの情報が残ってたり。。ちょっと古い?作り方してるもんで。。)

 

以下のようにすればFocusしてくれます。

 

       Me.ActiveControl = Me.(control)

 

LoadされるまではControlがアクティブになってないのかしらね~。

ちなみにMeはいらないけど、あった方がコーディングしやすいでしょ。

 


DataGridViewのイベント [DataGridView]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005
----------------------------------------------------------

 

DataGridView上のデータの条件によって、

グリッドの色を変えたり、データを別のとこに表示したりする際に

使うイベントについて。

 

一番使えるのはDataGridView.CellEnterイベントでしょうか。

 

今回やりたかったのは、行のデータを明細部に表示するといったもので、

はじめはDataGridView.RowEnterイベントでやろうと思ってて。

ただ、RowEnterだと、画面ロード時にNullReferenceのエラーが出るの。

 

なぜか。

 

CellEnterイベントは「現在のセルが変更になったとき発生」

RowEnterイベントは「行が入力フォーカスを受け取り、現在の行になる前に発生」

 

似たような名前なのに違うタイミングで起こるなんて・・・紛らわしぃ。。。

まぁFormの初期化をちゃんとしとけば大丈夫なんだろうけど・・・

CellEnterで済ませました。

 

 

しかし、DataGridViewはメンバが多いから大変だぁ~~。

http://msdn.microsoft.com/ja-jp/library/system.windows.forms.datagridview_members.aspx


DataGridViewを使った検索データの表示と削除 [DataGridView]

----------------------------------------------------------
(開発・実行環境)

Microsoft Visual Studio 2005 Tools for Applications

Microsoft Visual Basic 2005
----------------------------------------------------------

(課題)

DataGridViewにDBの検索結果を表示する。

また、それをクリアする。

 

(解決法)

DB内の検索データをDataGridViewに表示する際、

DataSourceを使わずに行なった。

DataSourceを当ててる場合は、DataSourceをClearか何か

すれば良いらしいけど。 

 

表示は、検索結果の入ったDataSetを一度配列に入れて、

その配列内のデータを行毎にDataGridViewに流す。

(配列はDataGridViewのColumn数を要素数とする)

 これを行数回分まわす。

(グリッドのColumu数が検索結果の列の数と違う場合は1列ずつ入れました。。)

 

削除する場合は一気にClearできなかったので、

行数を数えて、その回数分行削除処理をまわす。

 

ちなみにこのとき使ったメソッドは、

「DataGridView.Rows.RemoveAt()」。

DataGridView.Rows.Remove()じゃダメやった。。

行を”コレクション”から削除するメソッドなんだけど、

うまく全行消えてくれず。。。

たぶん、消した分だけコレクションが変化した(行数が減った)からだと思うけど。。

(しかし、コレクションってなんかいまいちピンとこん。。。)

ちなみに以下が”上手くいかなかった”ソース。。

 

(p_GrdはDataGridViewのオブジェクト)

 'グリッドの行数の取得
        Dim rowCnt As Integer = p_Grd.Rows.Count

        行の削除()
        For Each row As DataGridViewRow In p_Grd.Rows
            If row.Cells(0).Value.ToString IsNot Nothing Then
                p_Grd.Rows.Remove(row)
            End If
        Next

 

 

行の位置を指定して削除する「RemoveAt()」メソッドを使いましたとさ。

 

ちなみにグリッドデータを削除する場合は下から(行番号の大きい方から)消すよう注意!

消してったら行数減ってくからね。


この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。