2011年12月17日土曜日

【Android】ウィジェットを確実に更新させる

Androidのウィジェットの内容を更新する場合、以下のように
updateAppWidgetとすると思います。

  1. private void updateAppWidget(Context context, RemoteViews remoteViews) {  
  2.     ComponentName thisWidget = new ComponentName(context, ClockAppWidgetProvider.class);  
  3.     AppWidgetManager manager = AppWidgetManager.getInstance(context);  
  4.     manager.updateAppWidget(thisWidget, remoteViews);  
  5. }  

ただ、複数配置した時など、各ウィジェットへ確実に更新が行われないようです。
特に時計ウィジェットだと顕著です。

その場合、

  1. int[] appWidgetIds = manager.getAppWidgetIds(thisWidget);  
  2. for (int i : appWidgetIds) {  
  3.     manager.updateAppWidget(i, remoteViews);  
  4. }  

のように各ウィジェットIDに対して更新するようにすると、確実に更新されるようです。

ただし、重いです。。何が原因で重いのかはまだわからないですが、、、

2011年12月16日金曜日

【Android】ダイアログで画面外を触った場合に閉じる

ダイアログは2種類ある。

通常の Dialog を継承しているもの。
Activityにtheme (@android:style/Theme.Dialog など) を設定してDialog風にしているもの。

指定の方法がそれぞれ違う。



1. 通常の Dialog を継承しているもの。
  1. final AlertDialog dialog = alertinformation.create();  
  2. dialog.setCanceledOnTouchOutside(true);  

Dialog に対して、setCanceledOnTouchOutside を設定してやるといい。

2. Activityにtheme (@android:style/Theme.Dialog など) を設定してDialog風にしているもの。
  1. // ウィンドウ外を触った場合、閉じる  
  2. @Override  
  3. public boolean dispatchTouchEvent(MotionEvent ev) {  
  4.     Rect dialogBounds = new Rect();  
  5.     getWindow().getDecorView().getHitRect(dialogBounds);  
  6.   
  7.     if (!dialogBounds.contains((int) ev.getX(), (int) ev.getY())) {  
  8.         this.finish();  
  9.     }  
  10.     return super.dispatchTouchEvent(ev);  
  11. }  

イベントで画面外をタッチしている場合に画面を終了する。

2011年12月15日木曜日

【Android】Proguard使用時の注意点

Proguard使用時の注意

元々Android用ではないため、Javaのソースのみを難読化し、
XMLは無視する様子。

そのため、難読化しないクラスを除外設定しないといけない。

proguard.cfg に設定があるので編集する。

1. クラス名の難読化除外。

おすすめ
  1. -keep public class * extends android.app.Activity  
  2. -keep public class * extends android.app.Application  
  3. -keep public class * extends android.app.Service  
  4. -keep public class * extends android.content.BroadcastReceiver  
  5. -keep public class * extends android.content.ContentProvider  
  6. -keep public class * extends android.app.backup.BackupAgentHelper  
  7. -keep public class * extends android.preference.Preference  
  8. -keep public class com.android.vending.licensing.ILicensingService  
  9. -keep public class * extends android.view.View  
  10. -keep public class * extends android.support.v4.app.Fragment  

この場合、クラス名は何でもよくてandroid.view.View、またはその子を継承しているもの
-keep public class * extends android.view.View

2. メソッド名の難読化除外

xml に android:onClick がある場合、xmlは難読化しないのでjavaのメソッド名も除外に指定する。

  1. -keepclassmembers class * {  
  2. public void On*Click(android.view.View);  
  3. public void on*Click(android.view.View);  
  4. }  

そのため、onClickメソッドはやっぱり on*Click という命名規則にした方が良い。

2011年11月4日金曜日

【Android】ProgressBarをコードで作成時にバー状態にする

ProgressBarをコードで作ると style が変更できないように見えます。
どうやら以下の方法で変えれるみたいです。
styleと名のつくものは全てそうかも。ていうかこれはテーマってことかな?

ProgressBar progress = new ProgressBar(this,null,android.R.attr.progressBarStyleHorizontal);

コンストラクタの第3引数で設定したらいいみたい。
android.R.attr.progressBar~ に他のスタイルもあります。

他に xml でProgressBarを定義して Inflate する方法でもいいですね。

2011年8月16日火曜日

【Chrome】Google Chrome拡張の保存先

Windows XPだと

C:\Documents and Settings\[ユーザー名]\Local Settings\Application Data\Google\Chrome\User Data\Default\Extensions

というところにある。

まあ、他のOSでも、 background.html とかで検索するときっとどっかに大量のファイルがヒットします。
そこに拡張のソースが見れる形であるので、参考になります。

2011年7月28日木曜日

第3回SHARPハッカソンに行ってきました

7月23日、24日の土日にて 第3回SHARPハッカソンに行ってきました。

私としては初めてのハッカソンだったため、ドキドキしながら行ってきました。
場所は広島の八本松。
名古屋から広島まで新幹線に乗っていき、そこから鈍行に乗り、八本松までという長い道のりでした。


参加者はテレビで見たならぬ、ネットで見たことある!という豪華メンバー多数。
今まで会ってみたいなって思ってた人にも会えました。
こんなすごい人達と一緒に参加できることが大変ありがたかったです!

ハッカソンでは
SHARPさんから2011年夏モデルの最新端末をお借りし、
チームで2日間の期間を使い、アイデア出しからアプリを完成するところまでするというものでした。

自分たちのチームは、   TEAM びすこ。
メンバーは、
デザイナー
 @korowan
 @rie05
開発者
 @itog
 @dd0125 (自分)
という構成でした。

デザイナーさんがいるということは新鮮でした!

アイデアとしては色々候補はあったのですが
せっかくSHARPのイベントなので、SHARP API と使おうということで、

歩数計APIでコインを貯め、開閉通知APIで動かすスロットということで決定。
@rie05 さんの ウキウキノコ というキャラクターを使わせてもらいました。

1日目、1日目の夜、2日目と開発を頑張った結果がこれ。


うちのチームは39分から!



最後に一番面白かったチームはということで投票をするのですが、
な、な、なんと準優勝を頂けました。
頑張ったことは確かですが、皆さんすごかったのでいいのかなーって思いながらでした。
すごく嬉しかったです。





帰りは広島焼きを食べて帰りました。

よし、最後に広島らしいことした!



・今回感じたこと

デザイナーと開発者が混ざると科学反応が起きるということ。

開発者はデザイナーさんが作った綺麗な画像を動かせることに感動。
デザイナーさんは自分が作ったものが動くことに感動。
双方いい影響を与えてる!

またハッカソン参加したいなーって思いました。^^

SHARPのみなさん、ブリリアントサービスのみなさん!
そして参加者のみなさん、メンバーのみなさん、ありがとうございました!


イベントについて更に詳しくはこちらのブリリアントサービスさんのブログで
http://d.hatena.ne.jp/bs-android/20110727

2011年7月21日木曜日

【Android】他パッケージのActivityを呼び出すには

例えば電池使用量の画面を出すには、結論から言うと、
  1. Intent intent = new Intent(Intent.ACTION_MAIN);  
  2.         ComponentName compo = new ComponentName("com.android.settings","com.android.settings.fuelgauge.PowerUsageSummary");  
  3.         intent.setComponent(compo);  
  4.         startActivity(intent);  

・ComponentName に パッケージ名とクラス名を設定しています。

他の画面はどうやって出すの?って気になった場合は

なにか画面を起動したときに出る、
LogCatの
07-21 02:47:06.246: INFO/ActivityManager(116): Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.android.contacts/.DialtactsActivity bnds=[5,244][115,362] } from pid 1016
を参照し、 cmp=com.android.contacts/.DialtactsActivity となってるのが、
パッケージ名とクラス名。ちなみにこれは電話アプリ。

この場合は、
  1. ComponentName("com.android.contacts","com.android.contacts.DialtactsActivity");  
となる。

これで電話アプリが起動する。

2011年7月19日火曜日

【Android】文字列から id(int型) を取得する

現在のActivityのパッケージリソースから取得する場合は、

R.string.XXXXX というリソースでは、

int resid = getResources().getIdentifier("XXXXX","string",this.getPackageName());

と取得。

R.drawable.YYYY では、

int resid = getResources().getIdentifier("YYYY","drawable",this.getPackageName());

で取れる!

2011年6月29日水曜日

【Android】viewのidからid名を取得する

  1. Context.getResources().getResourceEntryName(view.getId())  

コードハイライト使う必要ないねw

2011年6月23日木曜日

【ブログ】ファイルのアップロード

ブログでファイル(ソースコードや実行ファイル)をアップロードしたい時、
どうしようかなと困っていたけども解決策を発見。

DropBoxのPublic機能を使えばいいんだと思った!

全体公開のフォルダを作成し、その中にファイルを置き、
全体公開フォルダの操作から 「共有リンクを入手」

取得した共有リンクをブラウザからアクセスし、
ファイルのリンク先をブログに使用!

ブログを見ているユーザーがリンクをクリックすると
1クッション画面を挟んでくれるし、便利ー。

うちの共有だとこんな感じ


DropBoxだとエクスプローラからファイルいじれたりもするしね^^

2011年6月22日水曜日

【Windows】PuTTYの画面を最大化する方法

普通に使ってて、起動したばかりの標準のウィンドウの大きさは小さい。
毎回大きくするのは面倒。

どうすればいいかとPuTTYの設定を見直していたが、
そこにはない。

というか、通常のWindowsのショートカットのプロパティで
"実行時の大きさ" を "最大化" にすれば良かっただけだった。

簡単なことでした。

他のショートカットもそういえばそうだなー。

2011年6月21日火曜日

configure: error: mysql_query missing!?

centos に pdo_mysql を入れる時に
./configure すると
configure: error: mysql_query missing!?
が出てすごい困ってたのだが、

yum install mysql-devel で

mysql-devel をインストールしてから
./configure すると
うまくいった!

【VB.NET】Windowsの起動と終了の時間を表示

会社で勤怠を付け忘れると、
昨日の出社時間と退社時間がいつだっけ・・って忘れる時がある。

出社と同時にPCつけ、退社と同時にPCを消しているという条件であれば、
そんな時には Windowsのイベントログを見ると起動と終了時間がすぐにわかる。

イベントID 6005 と 6006 を見ればいいみたい。

VB.NET のソースではこんな感じ。

  1. Dim logs() As System.Diagnostics.EventLog  
  2.         logs = System.Diagnostics.EventLog.GetEventLogs()  
  3.         For Each log As EventLog In logs  
  4.             If log.LogDisplayName <> "システム" Then  
  5.                 Continue For  
  6.             End If  
  7.   
  8.             For Each entry As EventLogEntry In log.Entries  
  9.                 Select Case entry.EventID  
  10.                     Case 6005 ' 起動  
  11.                         Console.WriteLine("起動 " & entry.TimeWritten)  
  12.                     Case 6006 ' 終了  
  13.                         Console.WriteLine("終了 " & entry.TimeWritten)  
  14.                         Console.WriteLine()  
  15.   
  16.                     Case Else  
  17.                         Continue For  
  18.                 End Select  
  19.             Next entry  
  20.         Next log  

作ったものはこれ。
ここをクリック


実行するとWindowsの起動時間と終了時間を教えてくれます。
GUIとか作ったって仕方ないのでコマンドラインアプリケーションですが、
便利だと思われ。

2011年6月19日日曜日

【Chrome】URL 1up

Chrome Store に拡張を初めて出してみました。

すっごく簡単な拡張ですが、
私、昔はSleipnirユーザーで(今もサブで使っていますが)して、
「一つ上のフォルダへ」というボタンを結構重宝していました。

あれは色んなサイトでHOMEに移動する時などに便利なんですよねー。

ただし、現在よく使ってるChromeにはそのボタンがない!

まぁ、ないのが普通だとは思うんですけど。笑

ないなら作ろうということで作ってみました!

URL 1up

ソースコードは10行くらい?

簡単ですが、自分は使います。

まさに俺得。

いいんじゃないでしょうか。

使いたい人はよしなに使ってくださいな。

【垂れ流し】ニコニコ動画用の小さなChrome拡張を作る

ニコニコ動画用の小さなChrome拡張を作ろうとしている。

マイリスト連続再生時にブラウザを終了して、
そしてブラウザを再起動するとマイリスト連続再生は最初からになってしまう。

これはどうにか続きの動画から再生するようになる拡張を作りたい。

ニコニコ動画のHTMLソース内には
「この動画から連続再生」を選んだ場合のマイリストfromIDが保存されている。
しかし、現在の再生中の動画のマイリストfromIDは保存されていない。取得できない。

ニコニコ動画のプレイヤーはFLASHであり、
そこから値が取得出来ればいいが、よくやり方がわからない。

マイリスト再生中に
「とりあえずマイリスト一発登録」を押すと、
再生中の動画がマイリスト登録された。

と、いうことは。
FLASHで再生中の動画IDが取得できていることになる。

ソースを解析していると
BTN_add_deflist というボタンを押して addVideoToDeflistという関数が動き、
マイリスト登録されている。

そのなかで注目すべきは、
cur_thread_id。 これが動画の情報な気がする。

この値が操作されているのが、
changePlayingVideo という関数。

いかにも再生中の動画が切り替わった時に動きそうな関数。

これがどこから呼び出されているかはソース内には見つからない。

むぅ。とりあえず今日はここまで。

2011年6月15日水曜日

Chromeで入れたらいいと思うよの拡張まとめ

まとめてみましたよっと。
Chromeに入れるべき拡張。


Google Mail Checker


安心のGoogle品質!
Gmailの新着を通知してくれ、ワンクリックでGMailにアクセス。




Google Calendar Checker


安心のGoogle品質!
直近の予定をアイコンで示してくれるので便利。




Send to Google Docs


現在見ているWebページをGoogleDocsにPDFでキャプチャしてくれます。
キャプチャ結果を確認してから保存できます。




Google Quick Scroll


Googleで検索した後、ページの中で検索した語句の場所に一気にスクロールできるので便利。




Bubble Translate


Ctrlを押しながら語句を選択するだけで翻訳してくれます。




AutoPatchWork


page=1,page=2 などがあるページだと「次ページへ」をクリックしなくても勝手に1ページにつなげてくれる。
Googleやニコニコ動画などでも対応。




SmoothScroll


スクロールが気持よくなる。この微妙な感覚は入れてみないとわからない。




MyShortCuts


各種Googleサービスへのショートカットが詰まっている。




はてなブックマーク GoogleChrome 拡張


便利なソーシャルブックマーク。




英辞郎


翻訳Extension。ひとつの英単語につき、複数の意味を教えてくれるので便利。




Create Link


「 Google http://www.google.com 」 のように現在見ているページのタイトル、URLを簡単にコピーできる。
カスタマイズも可能。




Web2PDFConverter


現在見ているページをPDFに変換してダウンロードできる。





goo.gl URL Shortener


短縮URLを簡単に作成。コピーも簡単。


2011年6月7日火曜日

【EGit】Push時の設定でプロトコルに 「git + ssh」 が選べない

どこの説明のページにも git+ssh を選べって書いてあるのですが、
プロトコルのドロップダウンリストには選択肢がありませんでした。

http://www.eclipse.org/forums/index.php?t=tree&th=197431&S=60c2d429a68e03ee4836a39d94a685aa#page_top

ここに書いてある通り、
git+ssh から ssh になったようです。

ややこしや。

2011年6月2日木曜日

【Git】git show でファイルの内容確認

git show <リビジョン番号>:<ファイルパス>

で特定リビジョンのファイルが確認できる。

git show xxxxx:src/xx/xx/xx/xx/xxxx.java

みたいな感じ。

リビジョン番号はリビジョン名でもいいんじゃないかな。

2011年5月16日月曜日

【Android】日齢計算アプリ更新

日齢計算アプリを更新しました。

・入力した誕生日を保存
・TwitterなどにShareできる
・カレンダーに登録できる

そんな機能を追加しました。

でもデザインは手抜き。
もっと力を入れてやらないといけんっちゃいけんのだけど、
家にいて気が抜けるのともっと力を入れないといけないのもあるのでねぇ。。。

とりあえずやりたいとこまではできた感じ。

HandMemoのマルチタッチ時のおかしな動作も直さないといけないなー。。

2011年3月15日火曜日

【Android】祝!アンドロイダー掲載

アンドロイダーに初めて掲載されました。

レトロライツアウト!

http://androider.jp/a/601db07b8ec543c0/

実は最初のテストアプリを覗いて、一番時間をかけていないアプリなんですが、
これが掲載されました。

他のアプリも掲載されたらなぁー、って思ってます^^

2011年3月3日木曜日

【VB.NET】実行しているメソッド名を取得する

  1. New StackFrame(0).GetMethod.Name  

で取得できます。

ただやっぱり関数化したいですよね。
ログ出力に使うと思いますので。
そういう場合は、

  1. New StackFrame(1).GetMethod.Name  

ってしたらいいです。

単純。

2011年2月18日金曜日

【VB.NET】ソートされたとしてもDataGridViewの行に対応するDataRowを取得する

DataGridViewのDataSourceに BindingSource や DataTable を関連付けした場合に
DataGridViewの4行目に当たるDataTableの行を取得したい、とかやりたい時ありますよね。

通常はそのまま同じ4行目が対応する行になるのですが、
ソートをしてしまうとDataGridViewはソートされますが、DataTableはソートされず、
行番号が食い違うようになってしまいます。
その場合、下記関数をご利用ください。

  1. #Region "DataGridViewのRowIndexからDataTableのDataRowを取得する"  
  2.         ''' <summary>  
  3.         ''' DataGridViewのRowIndexからDataTableのDataRowを取得する  
  4.         ''' </summary>  
  5.         ''' <param name="RowIdx">''' <returns></returns>  
  6.         ''' <remarks>ソート時など、DataGridViewのRowIndexが必ずしもDataTableのRowIndexとマッチしないため</remarks>  
  7.         Public Function GetDataRow_ByDataGridViewRowIdx(ByVal RowIdx As IntegerAs DataRow  
  8.             Try  
  9.                 If Me.Rows(RowIdx).DataBoundItem Is Nothing Then  
  10.                     Return Nothing  
  11.                 End If  
  12.             Catch ex As IndexOutOfRangeException  
  13.                 Return Nothing  
  14.             End Try  
  15.   
  16.             Dim Dr As DataRow  
  17.             Dim Drv As DataRowView = CType(Me.Rows(RowIdx).DataBoundItem, System.Data.DataRowView)  
  18.             Dr = CType(Drv.Row, System.Data.DataRow)  
  19.   
  20.             Return Dr  
  21.         End Function  
  22.  
  23.  
  24. #End Region  

対応するDataRowが取得できます。
これで行移動時に値の編集するなど、DataRowをいじっちゃってください。

2011年2月17日木曜日

【SQLServer】同一列名なのに桁数や列説明が食い違う他テーブルの列を抽出

同じ列名なのに他テーブルでは列説明が違ったり、
型が違ったり、桁数が違ったりする列ってちらほら出てきますよね。

発見するのが難しかったりするのでSQLを作成しました。

  1. SELECT DISTINCT  
  2.   COL1.TABLE_NAME  AS テーブル名  
  3. ,( select b.value from sys.tables a  
  4.    left join sys.extended_properties b on a.object_id = b.major_id and a.parent_object_id = b.minor_id   
  5.    where a.name =COL1.TABLE_NAME) AS テーブル説明  
  6. , COL1.COLUMN_NAME AS 列名  
  7. , COL1.DATA_TYPE AS 型  
  8. , COL1.CHARACTER_MAXIMUM_LENGTH AS 文字桁  
  9. , COL1.NUMERIC_PRECISION AS 整数桁  
  10. , COL1.NUMERIC_SCALE AS 小数桁  
  11. , COL1.IS_NULLABLE AS NULL許容  
  12. , COMMENT.COLUMN_COMMENT AS 列説明  
  13.   
  14. FROM INFORMATION_SCHEMA.COLUMNS COL1  
  15. -- コメントを取得  
  16. INNER JOIN(  
  17. select   
  18.      t.name as TABLE_NAME  
  19.     ,c.name as COLUMN_NAME  
  20.     ,ep.value as COLUMN_COMMENT  
  21. from  
  22.       sys.tables              t  
  23.      ,sys.columns             c  
  24.      ,sys.extended_properties ep  
  25. where  
  26.       t.object_id = c.object_id  
  27. and c.object_id = ep.major_id  
  28. and c.column_id = ep.minor_id) COMMENT  
  29. ON COMMENT.TABLE_NAME = COL1.TABLE_NAME  
  30. AND COMMENT.COLUMN_NAME = COL1.COLUMN_NAME  
  31.   
  32. -- 列の情報が食い違うもの  
  33. LEFT JOIN INFORMATION_SCHEMA.COLUMNS COL2  
  34. ON COL1.COLUMN_NAME = COL2.COLUMN_NAME   
  35. AND (COL1.DATA_TYPE <> COL2.DATA_TYPE   
  36.   OR COL1.CHARACTER_MAXIMUM_LENGTH <> COL2.CHARACTER_MAXIMUM_LENGTH   
  37.   OR COL1.NUMERIC_PRECISION <> COL2.NUMERIC_PRECISION   
  38.   OR COL1.NUMERIC_SCALE  <> COL2.NUMERIC_SCALE   
  39.   )  
  40. WHERE   
  41. (  
  42.        -- 列のコメントが食い違うもの  
  43.        (  
  44.               select  COUNT(distinct ep.value )--c.name AS COLUMN_NAME  
  45.   
  46.               from  
  47.                        sys.tables              t  
  48.                      ,sys.columns             c  
  49.                      ,sys.extended_properties ep  
  50.               where  
  51.                      t.object_id = c.object_id  
  52.               and c.object_id = ep.major_id  
  53.               and c.column_id = ep.minor_id  
  54.               and c.name = COL1.COLUMN_NAME   
  55.        group by c.name  
  56.        ) > 1  
  57.        -- 列の情報が食い違うもの のJOIN がヒットした  
  58. OR COL2.COLUMN_NAME IS NOT NULL  
  59. )  
  60.   
  61. -- 列名指定する場合はここに条件  
  62. --WHERE COL1.COLUMN_NAME = 'HIN_CD'  
  63.   
  64. ORDER BY COL1.COLUMN_NAME ASC  

実行すると修正の必要性がある列のみ抽出されます。

Oracleでも似たようなの作っておくと便利!

※ちなみにSQLはインデントなどちゃんと直してません。

2011年2月13日日曜日

【Windows】Skypeを2重起動させる方法

2つのアカウントを使用する場合など、
Skypeは標準に起動すると2重起動できません。

もし起動させたい場合は、

"C:\Program Files\Skype\Phone\Skype.exe" /secondary

のように /secondary というオプションをつけます。

ただし、これだけだと自動ログインがきかなくなるのです。

まぁ、アカウントが複数なのでもちろんそうなのですが。

そこで起動オプションを増やします。

"C:\Program Files\Skype\Phone\Skype.exe" /secondary /username:【username】 /password:【password】

/username , /password オプションで自動ログインが可能です。
これらを含めてショートカットを作成すると、複数アカウントにて自動起動が可能です。

ただしパスワードをショートカットに書いてしまうことになるので、
そこだけ気をつけてくださいね。

2011年2月12日土曜日

【VB.NET】Date型の定数の宣言

Date型の定数の宣言は以下の通りです。

  1. Public Const HogeDate As Date = #2/12/2011 12:00:00 PM#  

# で囲んだ日付で宣言します。
中はアメリカの日付表記ですね。

ちなみに

  1. Public Shared ReadOnly HogeDate As Date = #2/12/2011 12:00:00 PM#  
のような感じでも定数みたいなやつが作れるよな感じですけど、どうなんでしょうねぇ。。

まぁ、Constでいいと思います。

2011年2月11日金曜日

【Windows】ショートカット作成時「~へのショートカット」をつけなくする

※XPにて確認しています。

Windowsにてショートカット作成した場合、

「【ファイル名】へのショートカット」
という風に勝手に へのショートカット と名前がついてしまいます。

私はこの へのショートカットは消してしまうタチです。

初めからつけなくしたらいいのではないか、ということでレジストリを変更してしまいましょう。

-------------------------------------------------------------
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer]
"link"=hex:00,00,00,00
-------------------------------------------------------------

パッチは ここ に置いておきます。

実行するだけでショートカット作成時に へのショートカット という名前がつかなくなります。

2011年2月10日木曜日

【VB.NET】メソッドのステップ実行をスルーさせる

CellValueChangedの中にある自作の決まりきったメソッドなど、
ステップ実行する必要はもうないのにステップ実行の中に入ってしまう時ありますよね。

その時はメソッドの前に

<System.Diagnostics.DebuggerStepThrough()>

という属性をつけてください。

付け方としましては、
  1. <System.Diagnostics.DebuggerStepThrough()> _  
  2. Public Sub XXXX()  
  3.     ' 処理  
  4. End Sub  

となります。

ちなみに、VB2010では、属性の後の次の行につながるための _ がいらなくなりますね。

2011年2月9日水曜日

【VB.NET】Formの自動TabIndex設定

フォームのコントロールのタブインデックス設定は結構面倒です。
自分的には決まり切った規則があるにも関わらず、
同じ作業の繰り返しなのでかなり面倒です。

決まり切った規則とは以下の通りです。
-----------------------------------------------------
第1条件 Top値の少ないコントロール
第2条件 Left値の少ないコントロール
※子コントロールを持つコントロールは内部も設定する
-----------------------------------------------------
この並び順でTabIndexを自動で設定してあげれば解決するんでないの、ということです。

ということで、以下の関数とプロパティを作成しました。
継承元のFormに設置してみてください。

  1. #Region "自動タブインデックス設定"  
  2.   
  3.     Private _SetAutoTabIndex As Boolean  
  4.     <System.ComponentModel.Category("追加プロパティ")> _  
  5.     <System.ComponentModel.DefaultValue(GetType(Boolean), "False")> _  
  6.     <System.ComponentModel.Description("Trueにすると画面の全コントロールのタブインデックスを自動で設定します。")> _  
  7.     Public Property SetAutoTabIndex() As Boolean  
  8.         Get  
  9.             Return _SetAutoTabIndex  
  10.         End Get  
  11.         Set(ByVal value As Boolean)  
  12.             _SetAutoTabIndex = value  
  13.             If _SetAutoTabIndex Then  
  14.                 Dim UpdateCount As Integer  
  15.                 UpdateCount = SettingAutoTabIndex(Me)  
  16.                 MessageBox.Show(UpdateCount & "件のタブインデックスを自動設定しました。""自動設定", MessageBoxButtons.OK, MessageBoxIcon.Information)  
  17.                 _SetAutoTabIndex = False  
  18.             End If  
  19.         End Set  
  20.     End Property  
  21.   
  22.   
  23.     ''' <summary>  
  24.     ''' タブインデックスを自動で設定します。  
  25.     ''' </summary>  
  26.     ''' <param name="ControlsInObject">引数で渡されたコントロール(省略した場合はフォーム)</param>  
  27.     ''' <remarks></remarks>  
  28.     Public Function SettingAutoTabIndex(Optional ByVal ControlsInObject As Control = NothingAs Integer  
  29.         If ControlsInObject Is Nothing Then  
  30.             ControlsInObject = Me  
  31.         End If  
  32.         Dim UpdateCount As Integer = 0  
  33.         Dim sl As New System.Collections.SortedList()  
  34.   
  35.         ' ポジションが左上に近いコントロールから順にタブインデックスを設定する.優先順位は上、左の順  
  36.         For Each Ctrl As Control In ControlsInObject.Controls  
  37.             Try  
  38.                 Select Case True  
  39.                     ' 子コントロールを持てるコントロール(タブ、パネル、グループボックス...)  
  40.                     Case HasChildControls(Ctrl)  
  41.                         sl.Add(Ctrl.Top.ToString.PadLeft(10, "0") & Ctrl.Left.ToString.PadLeft(10, "0"), Ctrl)  
  42.                         UpdateCount += SettingAutoTabIndex(Ctrl)  
  43.   
  44.                     Case Else  
  45.                         sl.Add(Ctrl.Top.ToString.PadLeft(10, "0") & Ctrl.Left.ToString.PadLeft(10, "0"), Ctrl)  
  46.   
  47.                 End Select  
  48.             Catch ex As Exception  
  49.   
  50.             End Try  
  51.         Next Ctrl  
  52.         ' タブインデックスを設定する  
  53.         For Idx As Integer = 0 To sl.Count - 1  
  54.             If CType(sl.GetByIndex(Idx), Control).TabIndex <> Idx Then  
  55.                 CType(sl.GetByIndex(Idx), Control).TabIndex = Idx  
  56.                 UpdateCount += 1  
  57.             End If  
  58.         Next Idx  
  59.   
  60.         Return UpdateCount  
  61.     End Function  
  62. #End Region  
  63. #Region "子コントロールを持てるコントロールかどうかチェック"  
  64.     ''' <summary>  
  65.     ''' 子コントロールを持てるコントロールかどうかチェック  
  66.     ''' </summary>  
  67.     ''' <param name="Ctrl"></param>  
  68.     ''' <returns></returns>  
  69.     ''' <remarks>子コントロールを持てる場合、True。持てない場合、False</remarks>  
  70.     Public Function HasChildControls(ByVal Ctrl As Control) As Boolean  
  71.         Select Case True  
  72.             Case TypeOf Ctrl Is Panel, TypeOf Ctrl Is GroupBox, TypeOf Ctrl Is TabControl, TypeOf Ctrl Is UserControl  
  73.                 Return True  
  74.             Case Else  
  75.                 Return False  
  76.         End Select  
  77.     End Function  
  78. #End Region  

-----------------------------------------------------
・SettingAutoTabIndex
タブインデックスを設定します。引数としてGroupBoxなど渡せばその内部のみTabIndexを設定します。

・HasChildControls
子コントロールを持っているコントロールかどうかチェックします。

・SetAutoTabIndex
プロパティとして実装しました。Booleanで持っていることに特に意味はありませんが、
Trueにしてみるとタブインデックスを自動設定し、Falseに戻ります。
(本当はプロパティグリッドにボタンを置きたいです)
-----------------------------------------------------



FormのSetAutoTabIndex のプロパティをいじくるだけで自動でタブインデックスがデザイナ上で設定します。

2011年1月28日金曜日

【VB.NET】フォームがコードのようなアイコン表示になりデザインが開けなくなった

ありますよね。時々。原因は不明ですが。

その時の原因はプロジェクトがクラスをフォームとして認識していない場合です。
VBからは直接直せないので、 vbproj のファイルをテキストエディタやメモ帳で開きましょう。

クラスはこのように記述されています、
  1. <compile Include="clsUpdate.vb" />  

フォームの場合は通常、このように記述されています。
  1. <compile Include="frmMain.vb">  
  2.       <subtype>Form</SubType>  
  3. </Compile>  

原因はこのフォームの中の

<subtype>Form</SubType>

がいつの間にか消えてしまうことが原因なんです。

確認してみてくださいね。

2011年1月24日月曜日

【VB.NET】Formを継承した場合にデザイン時でも継承元のLoadイベント実行への対処

Formを継承すると
なんと、継承元のFormに存在するLoadイベントが
継承したFormのデザイン時に自動実行されてしまいます。
これは私もハマりました。。


継承元のLoadイベントにて、ユーザー名の取得や画面名の取得、権限コードの取得など
データベースのデータを取得するコードを記述していると具合が悪いです。

その場合、デザイン時は処理したくないので、以下のコードを継承元FormのLoadイベントの最初に挿入します。

  1. Private Sub FormName_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load  
  2.         'デザイン時は処理しない  
  3.         If AppDomain.CurrentDomain.FriendlyName = "DefaultDomain" Then  
  4.             Exit Sub  
  5.         End If  
  6. End Sub  

これで継承元のLoadイベントがデザイン時に動きません。

2011年1月23日日曜日

【VB.NET】プログラムリファレンス作成のSandCastle

Java でいう JavaDoc のようなプログラムリファレンスを作るためのソフト。
SandCastle





SandCastle を使用するために見ればいいリンクを羅列。

・まずSandcastle本体。

Sandcastle-June 2010 Release (Version 2.6.1062.1)
http://sandcastle.codeplex.com/releases/view/47665

・パッチをあてておこう

Sandcastle June 2010 (2.6.10621.1) Patch - Rev 1
http://sandcastlestyles.codeplex.com/releases/view/47767

・GUI環境を導入しよう

Sandcastle Help File Builder
http://shfb.codeplex.com/

・使い方を説明して頂いているリンク
http://blogs.wankuma.com/esten/archive/2007/09/12/95500.aspx
http://d.hatena.ne.jp/Wacky/20071007/1191782352


・通常に出力するとかなり時間がかかるのでMSDNへのリンクを切って高速化
http://narista.cocolog-nifty.com/gk/2007/06/sandcastle_f67f.html
※SdkLinkType が○○SdkLinkTypeとたくさんあるので注意


このソフトを使わない場合、プログラムのコメントはバラバラだわ、
プログラム内容の説明資料は作らないといけないだわ、
作った後も同期化しないといけないだわ、
と良いことなしですが、

メンバーにコメントをつける癖も付けられそうですし、すこぶる楽になりますね。

自分もリンクを忘れないようメモです。

GUIを使うやり方でやりましたが、CUIのコマンドラインでできるようになれば、
Windowsのタスクに組み込んで定期的に更新されるよう作れたりしますね。
非常に便利!

2011年1月22日土曜日

【VB.NET】PixivDownLoadBrowser ver.1.3 Update!

PixivDownLoadBrowser ver.1.3 を更新しました。
http://www.vector.co.jp/soft/winnt/net/se484370.html
【更新内容】
・R-18漫画のダウンロードエラーを修正
・画面レイアウトの修正
・コメント情報取得を修正
・イラストタイトルの最後にスペースが入っているダウンロード不具合を修正
・イラスト名に ? が入っている場合にエラーになる不具合修正
・Ctrl + D でダウンロードショートカット
・コピーや貼り付けなどのショートカット制限を解除
・自動ログインを修正


また全国誌である iP! 2月号に載りました!
小さいですが、これも一歩です!

2011年1月21日金曜日

【VB.NET】データテーブルのRowStateで変更されていないデータはUnChangedに設定する

DataTable にて、一度編集して、
また元の値に戻した場合RowStateが Modified になってしまいます。
一度編集したとはいえ、やはり全く同じ値ならばUpdateは走らせたくありませんよね!

その場合は、以下の関数をコピペして使ってみてください。

  1. Public Sub RowStateSetUnChanged(ByVal dt As DataTable)  
  2.   
  3.         If IsNothing(dt) Then  
  4.             Return  
  5.         End If  
  6.   
  7.         For RowIdx As Integer = 0 To dt.Rows.Count - 1  
  8.             Dim dr As DataRow = dt.Rows(RowIdx)  
  9.   
  10.             If dr.RowState <> DataRowState.Modified Then  
  11.                 Continue For  
  12.             End If  
  13.   
  14.   
  15.             Dim IsUnChanged As Boolean  
  16.             IsUnChanged = True  
  17.   
  18.   
  19.             For ColIdx As Integer = 0 To dt.Columns.Count - 1  
  20.                 If Not dr.Item(ColIdx, DataRowVersion.Current).Equals(dr.Item(ColIdx, DataRowVersion.Original)) Then  
  21.                     IsUnChanged = False  
  22.                     Exit For  
  23.                 End If  
  24.   
  25.             Next ColIdx  
  26.   
  27.             ' 変更されていなかった場合、UnChangedに設定する  
  28.             If IsUnChanged Then  
  29.                 dr.AcceptChanges()  
  30.             End If  
  31.         Next RowIdx  
  32.     End Sub  

よろしくどうぞー。

【VB.NET】DataGridViewのTextBoxCellで入力バイト数制限をする

今回はDataGridViewについてです。

DataGridView は通常文字数での入力制限です。
しかし、対してデータベースはバイト数の桁数となっていますので、
バイト数の入力制限がDataGridViewにも必要です。

その場合、以下のコードでバイト数制限が可能です。

  1. #Region "バイト数文字制限"  
  2.     ''' <summary>  
  3.     ''' テキスト変更時のイベントハンドラを追加  
  4.     ''' </summary>  
  5.     ''' <param name="sender">''' <param name="e">''' <remarks>EditingControlが表示された時の処理</remarks>  
  6.     Private Sub CommonDataGridView_EditingControlShowing(ByVal sender As ObjectByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles Me.EditingControlShowing  
  7.         Select Case True  
  8.             Case TypeOf e.Control Is DataGridViewTextBoxEditingControl, TypeOf e.Control Is DataGridViewComboBoxEditingControl  
  9.                 'TextChangedイベントハンドラを追加  
  10.                 AddHandler EditingControl.TextChanged, AddressOf EditingControl_TextChanged  
  11.   
  12.   
  13.         End Select  
  14.     End Sub  
  15.   
  16.     Private Sub EditingControl_TextChanged(ByVal sender As ObjectByVal e As System.EventArgs)  
  17.   
  18.         Select Case True  
  19.             ' TextBox  
  20.             Case TypeOf Me.FindForm.ActiveControl Is DataGridViewTextBoxEditingControl  
  21.                 Dim EditingControl As DataGridViewTextBoxEditingControl  
  22.                 EditingControl = DirectCast(Me.FindForm.ActiveControl, DataGridViewTextBoxEditingControl)  
  23.                 Dim CurrentCell As DataGridViewTextBoxCell  
  24.                 CurrentCell = DirectCast(Me.CurrentCell, DataGridViewTextBoxCell)  
  25.                 Dim ValueByteCount As Integer  
  26.   
  27.                 ValueByteCount = System.Text.Encoding.GetEncoding("Shift_JIS").GetByteCount(EditingControl.Text)  
  28.                 If ValueByteCount > CurrentCell.MaxInputLength Then  
  29.                     EditingControl.Text = LeftB(EditingControl.Text, CurrentCell.MaxInputLength)  
  30.                     EditingControl.SelectionStart = EditingControl.TextLength  
  31.                 End If  
  32.   
  33.                 ' ComboBox  
  34.             Case TypeOf Me.FindForm.ActiveControl Is DataGridViewComboBoxEditingControl  
  35.                 ' 必要の都度、型ごとに増やしていく  
  36.         End Select  
  37.   
  38.     End Sub  
  39.   
  40.     ' 左からバイト数で文字列を取得 これは他の共通クラスで持たせてください。  
  41.     Private Function LeftB(ByVal value As StringByVal length As IntegerAs String  
  42.         Dim enc As System.Text.Encoding  
  43.         enc = System.Text.Encoding.GetEncoding("Shift_JIS")  
  44.         Dim bytes As Byte()  
  45.         bytes = enc.GetBytes(value.PadRight(length))  
  46.         Return enc.GetString(bytes, 0, length)  
  47.     End Function  
  48. #End Region  

動きとしては、DataGridViewで、編集状態に入った時に
EditingControl が生成(?)されます。
その時のイベントでEditingControlにテキストチェンジのイベントを与えます。
そこで入力制限をすれば各セルにバイト制限持たせられます。

2011年1月17日月曜日

【Android】AdMobが表示されない場合にAdMakerを表示するクラス

前に使ったクラスを晒します。

  1. package jp.dd0125.common;  
  2.   
  3. import jp.co.nobot.libYieldMaker.libYieldMaker;  
  4. import android.app.Activity;  
  5. import android.util.Log;  
  6. import android.view.ViewGroup.LayoutParams;  
  7. import android.widget.LinearLayout;  
  8. import android.widget.ProgressBar;  
  9. import android.widget.RelativeLayout;  
  10.   
  11. import com.admob.android.ads.AdListener;  
  12. import com.admob.android.ads.AdView;  
  13.   
  14. public class CommonAdMob_AdMaker {  
  15.  private static final String TAG = "CommonAdvertisement";  
  16.   
  17.  ProgressBar pb;  
  18.  AdView adView;  
  19.  libYieldMaker adMaker;  
  20.  Activity act;  
  21.  public CommonAdMob_AdMaker(Activity act){  
  22.   this.act = act;  
  23.   
  24.   pb = new ProgressBar(act);  
  25.   pb.setVisibility(ProgressBar.VISIBLE);  
  26.   
  27.   
  28.   //pb.setGravity(android.view.Gravity.RIGHT);  
  29.   pb.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));  
  30.   
  31.  }  
  32.   
  33.   
  34.   
  35.   
  36.  public void createAdMob(int align){  
  37.         adView = new AdView(act);  
  38.         adView.setVisibility(android.view.View.VISIBLE);  
  39.         adView.requestFreshAd();  
  40.   
  41.         adView.setGravity(align);  
  42.         adView.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));  
  43.   
  44.   
  45.         adView.setAdListener(new AdListener() {  
  46.   
  47.             public void onReceiveRefreshedAd(AdView adView) {  
  48.                 Log.d(TAG, "AdListener.onReceiveRefreshedAd called!");  
  49.             }  
  50.   
  51.             public void onReceiveAd(AdView adView) {  
  52.                 Log.d(TAG, "AdListener.onReceiveAd called!");  
  53.                 // 広告が表示できたのでProgressBarを消す  
  54.                 pb.setVisibility(ProgressBar.GONE);  
  55.             }  
  56.   
  57.             public void onFailedToReceiveRefreshedAd(AdView adView) {  
  58.                 Log.d(TAG, "AdListener.onFailedToReceiveRefreshedAd called!");  
  59.             }  
  60.   
  61.             public void onFailedToReceiveAd(AdView adView) {  
  62.                 Log.d(TAG, "AdListener.onFailedToReceiveAd called!");  
  63.                 // プログレスバーを消す  
  64.                 pb.setVisibility(ProgressBar.GONE);  
  65.   
  66.   
  67.                 // AdMaker の広告を設定している場合、AdMakerの広告を表示するのでAdViewの更新を行わせない  
  68.                 if(adMaker != null){  
  69.                     adView.setRequestInterval(0);  
  70.                     adView.setVisibility(AdView.GONE);  
  71.   
  72.                     // AdMakerの広告を表示させる  
  73.                     adMaker.setVisibility(libYieldMaker.VISIBLE);  
  74.                     adMaker.startView();  
  75.   
  76.                 }  
  77.             }  
  78.         });  
  79.  }  
  80.   
  81.  public void createAdMaker(String url){  
  82.   adMaker = new libYieldMaker(act);  
  83.         adMaker.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));  
  84.   
  85.         adMaker.setActivity(act);  
  86.         adMaker.setUrl(url);  
  87.   
  88.  }  
  89.  public RelativeLayout getAdMob_AdMaker(){  
  90.   RelativeLayout layout = new RelativeLayout(act);  
  91.   layout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT));  
  92.   
  93.   layout.setGravity(android.view.Gravity.CENTER);  
  94.   layout.addView(pb);  
  95.   if(adView != null){  
  96.    layout.addView(adView);  
  97.   }  
  98.   if(adMaker != null){  
  99.    layout.addView(adMaker);  
  100.    if(adView == null) {  
  101.     pb.setVisibility(ProgressBar.GONE);  
  102.     adMaker.setVisibility(libYieldMaker.VISIBLE);  
  103.     adMaker.startView();  
  104.    }  
  105.   }  
  106.   return layout;  
  107.  }  
  108. }  

このように使います。

  1. // 広告  
  2.  //AdManager.setTestDevices( new String[] {  
  3.  //  AdManager.TEST_EMULATOR,  
  4.  //  //"XXXXXXXXXXXXXXXXXXXX",  
  5.  //  });  
  6.  LinearLayout l_ad = (LinearLayout)findViewById(レイアウトID);  
  7.  CommonAdMob_AdMaker Ad;  
  8.  Ad = new CommonAdMob_AdMaker(this);  
  9.  Ad.createAdMob(RelativeLayout.ALIGN_TOP); // AdMobを生成  
  10.  Ad.createAdMaker("http://stg-images.ad-maker.info/sample-test.html"); // AdMakerを生成  
  11.   
  12.  l_ad.addView(Ad.getAdMob_AdMaker()); // 広告を持ったレイアウトが返ってきますので addViewします  

ただし、
・res/values/attr.xml
・AdMob と AdMaker の jarライブラリ組み込み
は必要です。

【Android】HandMemo 0.5 をアップデートしました。

HandMemo 0.5

機能としては、中断時に自動保存機能を追加しました。
これで気軽にメモを中断し、その後、またメモの続きを行うことができます。

HandMemo : かんたん手書きメモ!Androidアプリ1215
http://octoba.net/archives/20101129-handmemo-android-1215.html

【Windows】IEの右クリックに自作アプリケーションの起動の登録

レジストリの
HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\MenuExt
に新しいキーを登録する。

キー名に右クリックに表示される名称になります。
規定の値に実行するhtmlファイル。

ContextsというDWORD値により、リンクで開くかページ内で開くか画像で開くかを設定できます。


実行するものは直接アプリケーションでは動かないようです。
htmlにスクリプトを記述し、その中でexeファイルなどを起動します。







【スクリプト】
  1. <script type="text/javascript">  
  2. var parentwin = external.menuArguments;  
  3. var parentwinPoint = external.menuArguments.document.elementFromPoint(parentwin.event.clientX, parentwin.event.clientY);  
  4.   
  5. var strTitle = new String();  
  6. var strURL = new String();  
  7. strTitle = parentwin.document.title;  
  8. strURL = parentwin.location.href;  
  9. //alert(strTitle);  
  10. alert("現URL:" + strURL);  
  11.   
  12. // リンク先  
  13. //alert("先URL:" + parentwinPoint.parentElement.href     );  
  14. //alert("先URL:" + parentwinPoint.href     );  
  15.   
  16. // もし現在の選択タグがAの場合は、現在タグのリンク先  
  17. if(parentwin.event.srcElement.tagName == "A"){  
  18.  alert("先URL:" + parentwin.event.srcElement.href     );  
  19. // それ以外の場合は、そのひとつ上のタグのリンク先  
  20. }else{  
  21.  alert("先URL:" + parentwin.event.srcElement.parentElement.href     );  
  22. }  
  23.   
  24.    
  25.   
  26.   
  27. // ファイル実行  
  28. //var WshShell = new ActiveXObject("WScript.Shell");  
  29. //WshShell.run("C:\\osero.exe");  
  30.   
  31. // ナビゲート  
  32. //parentwin.location.href ="http://yahoo.co.jp"  
  33.   
  34. // InnerHTML  
  35. //alert(parentwin.event.srcElement.document.body.innerHTML      );  
  36.   
  37. // tagName  
  38. //alert(parentwin.event.srcElement.tagName      );  
  39.   
  40. // 選択文字  
  41. //alert(external.menuArguments.document.selection.createRange().text);  
  42.   
  43.   
  44. </script>  
・ファイル実行
・ページ遷移
・InnerHTML取得
・右クリックしたリンク先の取得
・選択文字取得
・タグ名取得

などできるようです。

何かに応用利くかどうか考え中。

【VB.NET】ExitException

今回はエラー処理のお話です。


  1. Public Function A()  
  2.         Try  
  3.             If Not AA() Then  
  4.                 Return False  
  5.             End If  
  6.   
  7.             ' なんらかの処理  
  8.   
  9.         Catch ex As Exception  
  10.             MessageBox.Show("A にてエラーが発生しました。""エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)  
  11.             Return False  
  12.         End Try  
  13.   
  14.         Return True  
  15.     End Function  
  16.   
  17.     Public Function AA() As Boolean  
  18.         Try  
  19.             If Not AAA() Then  
  20.                 Return False  
  21.             End If  
  22.   
  23.             ' なんらかの処理  
  24.   
  25.         Catch ex As Exception  
  26.             MessageBox.Show("AA にてエラーが発生しました。""エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)  
  27.             Return False  
  28.         End Try  
  29.   
  30.         Return True  
  31.     End Function  
  32.   
  33.     Public Function AAA() As Boolean  
  34.         Try  
  35.   
  36.             ' なんらかの処理  
  37.   
  38.         Catch ex As Exception  
  39.             MessageBox.Show("AAA にてエラーが発生しました。""エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)  
  40.             Return False  
  41.         End Try  
  42.   
  43.         Return True  
  44.     End Function  
つまりこんな感じの処理です。
  1. A関数処理  
  2.  AA関数処理  
  3.   AAA関数処理  
  4.  AA関数処理  
  5. A関数処理  
AAA関数でエラーが発生した場合、AAの後の処理は行ってはいけないわけです。 行わないように
  1. If Not AAA() Then  
  2.                 Return False  
  3.             End If  
と記述し、エラーの場合は即座に親関数に戻しています。

私はこの記述が面倒くさいと考えました。

面倒な理由は

・ If Not ~ という記述を毎回行わないといけない。
・ エラーメッセージの記述が面倒。メンテナンスも面倒。


そこで考案した方法は、
  1. Public Class ExitException  
  2.         Inherits Exception  
  3.         Public Sub New(Optional ByVal ErrMsg As String = "エラーが発生しました。")  
  4.             MyBase.New(ErrMsg)  
  5.         End Sub  
  6.         Public Sub New(ByVal ErrMsg As StringByVal ex As Exception)  
  7.             MyBase.New(ErrMsg, ex)  
  8.         End Sub  
  9.     End Class  
  10.   
  11.     Public Function A()  
  12.         Try  
  13.             Call AA()  
  14.   
  15.             ' なんらかの処理  
  16.   
  17.         Catch ex As Exception  
  18.             ErrMsg(ex, "A にてエラーが発生しました。")  
  19.             Throw New ExitException  
  20.         End Try  
  21.   
  22.         Return True  
  23.     End Function  
  24.   
  25.     Public Function AA() As Boolean  
  26.         Try  
  27.             Call AAA()  
  28.   
  29.             ' なんらかの処理  
  30.   
  31.         Catch ex As Exception  
  32.             ErrMsg(ex, "AA にてエラーが発生しました。")  
  33.             Throw New ExitException  
  34.         End Try  
  35.   
  36.         Return True  
  37.     End Function  
  38.   
  39.     Public Function AAA() As Boolean  
  40.         Try  
  41.   
  42.             ' なんらかの処理  
  43.   
  44.         Catch ex As Exception  
  45.             ErrMsg(ex, "AAA にてエラーが発生しました。")  
  46.             Throw New ExitException  
  47.         End Try  
  48.   
  49.         Return True  
  50.     End Function  
  51.   
  52.     Public Sub ErrMsg(ByVal ex As Exception, Optional ByVal Message As String = "")  
  53.         If TypeOf ex Is ExitException Then  
  54.             Exit Sub  
  55.         Else  
  56.             If Message = "" Then  
  57.                 ' メッセージを指定していない場合  
  58.                 Message = "不正なエラーが発生しました。"  
  59.   
  60.                 ' 実行関数名取得してメッセージに含める。これに関してはまた改めて・・  
  61.             End If  
  62.   
  63.             MessageBox.Show(Message, "エラー発生", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)  
  64.   
  65.         End If  
  66.   
  67.     End Sub  
です。 まず、 if Not ~ の記述がなくなっています。

そして共通エラークラスとして ExitException というのが増えており、 ErrMsgという共通関数が増えています。

ExitException ・・・ 発生した場合、エラーメッセージを表示しないエラー。素通りのエラー。
ErrMsg     ・・・ エラーメッセージを表示する関数。ログ書き込みとかもここで実装していいかもしれません。
クラス化してログ書き込みパラメータとかにするともっといいかもしれませんね。

Throw New ExitException を実行するとエラーメッセージを出さずに親の関数にエラーを通知できると考えれば良いと思います。

また、ErrMsgなどで呼び出し元の実行関数名を取得することもできるので、エラーメッセージやログに活用することもできます。


とりあえず少し走り書きで書きましたが、ここまで。