2008年2月6日水曜日

初期化の大切さ改めて実感

初期化していないがためのバグ
コンパイル時の最適化と合わさって
検出にえらい時間がかかってしまった…

問題になったコードの要点だけ抜き出してみた。
C++/CLIでは変数宣言すると勝手に初期化してくれるという
前提やのに。。。動いてなかってん。
------------------------
int i = 0;
for(i = 0; i < 20; ++i) {
int b; // ゼロで自動的に初期化されてるねん♪
b++;
printf("%d\n", b);// 必ず1が出力されることを期待
}
------------------------

ループの中で変数を宣言すると、毎回メモリ確保やん。
効率悪いってのでコンパイラが自動的にループの外で宣言してくれるねん。

↓コンパイル後はこのような意味のコードになってる
------------------------
int i = 0;
int b; // ゼロで自動的に初期化されてるねん♪
for(i = 0; i < 20; ++i) {
b++;
printf("%d\n", b);// 必ず1が出力されることを期待
}
------------------------
そりゃ期待する結果が得られるわけ無いやん…。


変数宣言時に初期化するように修正したコード
------------------------
int i = 0;
for(i = 0; i < 20; ++i) {
int b = 0; // 明示的にゼロで初期化してやった!
b++;
printf("%d\n", b);// 必ず1が出力されることを期待
}
------------------------

コンパイルするとこのような意味のコードになってる
------------------------
int i = 0;
int b; // ゼロで自動的に初期化されてるねん♪
for(i = 0; i < 20; ++i) {
b = 0; // ここが違う!
b++;
printf("%d\n", b);// 必ず1が出力されることを期待
}
------------------------
これで修正完了っと。
他にもコンパイル時の最適化はいろいろあるので覚えておいて損は無いかも。
WikiPedia「コンパイラ最適化」


教訓:
初期化し忘れで出たバグは非常に見つけ難い…(^^;
変数宣言時は初期化する癖をつけよう!

.

2008年1月22日火曜日

VBより呼び出したExcelが終了しない

VBより呼び出したExcelを終了させてもタスクに残る場合があります。
その場合は次のようなことをしたら幸せになれるかも

Dim App As Object

App = CreateObject("Excel.Application")

App.quit() 'エクセルの終了
App = nothing 'オブジェクトの開放
System.GC.Collect() ’ガベレージコレクションを強制的に行う

2008年1月17日木曜日

IMEモードの設定方法

ControlクラスのImeModeのプロパティで設定できます。
数値入力だけして欲しいときやカナ入力のみの場合などで使えます。

TextBox textBox1 = new TextBox;
textBox1.ImeMode = System.Windows.Forms.ImeMode.On;


おまけ
・IMEとはWindowsの日本語入力補助システムのこと。

・IMEと同義で使われていたFEPってのも調べてみた。
> 古くからのパソコンユーザーの一部は昔の名残で今でもFEPと呼ぶ者がいるが、これは誤用である。
という事がWikiPediaのFEPのページに書いてありました。

.

2008年1月16日水曜日

ガベージコレクション(GC)

ガベージコレクションについてのサイトを見つけたのでメモメモ。

GCアルゴリズム詳細解説
いくつかのアルゴリズムがわかりやすくかいてあります。

上記サイトを見た後で前に読んだ
.NETのガベージコレクションについての記事を読み直しました。
http://www.microsoft.com/japan/msdn/net/mag00/GCI.aspx
かなり詳しく書いてありますので一度読んでみてはどうでしょうか?

僕の頭のなかでのまとめ。
ガベージコレクションはあくまでも new したオブジェクトを解放してくれるもので
ファイルリソースやネットワーク接続リソースについては
明示的に解放する処理を記述する必要があります。


メモリ管理は非常に大切ですね。
.

DataGridViewのセルに複数行表示させる

プロパティより設定可能
コードはこんな感じ
dataGridView1.Columns[0].DefaultCellStyle.WrapMode = DataGridViewTriState.True

あとは表示データに改行を入れてやればおk

2008年1月8日火曜日

クリスタルレポートに表示する値を渡す

クリスタルレポートに固定の表示する値をVBから渡す方法。

まず、レポートにパラメータフィールドを追加。
適当な名前をつける。今回はTEXTとつける。
次にVBのコード側に次の式を記入

CrystalReport.SetParameterValue("TEXT", "適当")

これで、レポート側に適当と表示される。

なお、これはdatasetからデータをセットした後に記入すること
データセット前に行うと表示されない。
初期化されてるのかな・・・

クリレポの行数指定改ページ

クリスタルレポートの行数を指定して改ページする方法。

ページヘッダに「式フィールド」を追加して次の式を記入
WhilePrintingRecords;
numberVar line := 0;

次に詳細(行数を指定するセクション)に式フィールドを追加して次の式を記入
WhilePrintingRecords;
numberVar line;
line := line + 1;

最後に詳細のセクションエキスパートにある「出力後改ページ」にチェックして、式を追加
WhilePrintingRecords;
numberVar line;
line = (出力したい行数を記入)

最初がページ毎に行数を初期化
二つ目はラインが1つ増えるごとに1足す処理
最後がラインが特定になったときに改ページする条件
のはず

ラベル