・VB6
Private Sub Form_MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
If Button = vbRightButton Then
If Shift = (vbShiftMask + vbCtrlMask) Then
MsgBox "SHIFT+CTRL+右クリック"
End If
End If
End Sub
・VB.NET
Private Sub Form1_MouseUp(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
If e.Button = Windows.Forms.MouseButtons.Right Then
If Control.ModifierKeys = (Keys.Shift + Keys.Control) Then
MsgBox "SHIFT+CTRL+右クリック"
End If
End If
End Sub
・VB2005以降ならControl.ModifierKeysの代わりに以下も可能
My.Computer.Keyboard.ShiftKeyDown And My.Comp.Keyboard.CtrlKeyDown
2011年07月26日
マウスイベントと同時にキーボードの状態を取得するには
SHIFTキーとCTRLキーを押しながら右クリックしたことを知るには
2010年02月06日
VB6(VBA)とVB.NET(VB2005,2008)の色データの違い
VB2008でExcelの表を作成するプログラムを作った時、セルの色を指定するところでエラーが起きた。
原因はVB6やVBA(Excel)が色のデータをRGB(赤,緑,青)の3色(3×8)24bitで表現しているのに対し、.NETではARGB(RGBとAlpha(透過)値)の4×8=32bitで表現するようになったためだ。
これらを相互に変換するためにSystem.Drawing.ColorTranslatorクラスにある関数を使う。
・ARGB(Color構造体)をRGBにする
ColorTranslator.ToOle(Color.Red)
ColorTranslator.ToWin32(Color.Red)
・逆にRGBデータをARGB(Color構造体)に変換するには
ColorTranslator.FromOle(RGB(255,255,0))
ColorTranslator.FromWin32(RGB(255,255,0))
・ColorTranslatorにはHTMLで使うカラー形式を変換するメソッドもある
ColorTranslator.ToHtml(Color.Red)
ColorTranslator.FromHtml("#FF00FF")
その後RGBで指定する場合ならColor構造体のメンバーにあるFromArgbメソッドでも可能なことが分かった。
RGBデータでColor(ARGB)指定するには Color.FromArgb(255,255,0)とするだけでよい。この場合アルファ値は暗黙的に 255 (完全不透明) になる。
原因はVB6やVBA(Excel)が色のデータをRGB(赤,緑,青)の3色(3×8)24bitで表現しているのに対し、.NETではARGB(RGBとAlpha(透過)値)の4×8=32bitで表現するようになったためだ。
これらを相互に変換するためにSystem.Drawing.ColorTranslatorクラスにある関数を使う。
・ARGB(Color構造体)をRGBにする
ColorTranslator.ToOle(Color.Red)
ColorTranslator.ToWin32(Color.Red)
・逆にRGBデータをARGB(Color構造体)に変換するには
ColorTranslator.FromOle(RGB(255,255,0))
ColorTranslator.FromWin32(RGB(255,255,0))
・ColorTranslatorにはHTMLで使うカラー形式を変換するメソッドもある
ColorTranslator.ToHtml(Color.Red)
ColorTranslator.FromHtml("#FF00FF")
その後RGBで指定する場合ならColor構造体のメンバーにあるFromArgbメソッドでも可能なことが分かった。
RGBデータでColor(ARGB)指定するには Color.FromArgb(255,255,0)とするだけでよい。この場合アルファ値は暗黙的に 255 (完全不透明) になる。
2009年04月15日
アプリケーション情報(VB6とVB2005)
| アプリ情報 | VB6 | VB2005 |
|---|---|---|
| 実行パス | App.Path | My.Application.Info.DirectoryPath |
| 実行ファイル名 (拡張子を除く) | App.EXEName | My.Application.Info.AssemblyName |
| メジャー番号 | App.Major | My.Application.Info.Version.Major |
| マイナー番号 | App.Minor | My.Application.Info.Version.Minor |
| ビルド番号 | (該当無し) | My.Application.Info.Version.Build |
| リビジョン番号 | App.Revision | My.Application.Info.Version.Revision |
| バージョンの構成 | (Major.Minor.0.Revision) | (Major.Minor.Build.Revision) |
| タイトル | App.Title | My.Application.Info.Title |
| ファイルの説明 | App.FileDescription | |
| 会社名 | App.CompanyName | My.Application.Info.CompanyName |
| コメント | App.Comments | My.Application.Info.Description |
| ヘルプファイル名 | App.HelpFile | (該当無し) |
| 著作権情報 | App.LegalCopyright | My.Application.Info.Copyright |
| 商標 | App.LegalTrademarks | My.Application.Info.Trademark |
※バージョン情報については、こちらも参考に→「自アプリケーションのバージョンを取得」
2009年03月27日
デフォルトボタンの指定方法
VB6では、Enterキーを押すと自動で応答するボタンをDefaultプロパティをTrueにすることで指定できた。
VB.NET(2005,2008含)になってその方法が変わり、フォームのAcceptButtonプロパティでボタンの名前を指定する。


同様にESCキーに応答させるVB6のボタンのCancelプロパティは、VB.NETではフォームのCancelButtonプロパティになる。
VB.NET(2005,2008含)になってその方法が変わり、フォームのAcceptButtonプロパティでボタンの名前を指定する。
VB6のサンプル画面
VB6:
Private Sub Text1_Change()
If Text1.Text = "" Then
Command1.Default = False
Else
Command1.Default = True
End If
End Sub
VB2008のサンプル画面
VB.NET:
Private Sub TextBox1_TextChanged(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles TextBox1.TextChanged
If TextBox1.Text = "" Then
Me.AcceptButton = Nothing
Else
Me.AcceptButton = Button1
End If
End Sub
同様にESCキーに応答させるVB6のボタンのCancelプロパティは、VB.NETではフォームのCancelButtonプロパティになる。
2008年03月06日
VB6のhDCプロパティはVB.NET(VB2005)ではどうなる?
VB6でグラフィック関連のWindowsAPIを使うときは必ずと言ってよいほどコントロール(FormやPictureBox)のデバイスコンテキストであるhDCプロパティを指定する。
これをVB.NET(VB2005)で使おうとしてアップデートウィザードを使うと肝心のhDCが「'UPGRADE_ISSUE: Form プロパティ Form1.hdc はアップグレードされませんでした。」となり使えない。別件だが同じくWindowsAPIでよく使うウィンドウハンドル(.hWnd)は、.NET Frameworkでは(コントロール).Handleというプロパティになっており判りやすい。
いったいhDCはどうすれば指定できるのだ?と思い調べてみたところこんな具合になった。VB6との比較で紹介する。
例として起動したフォームの座標(x,y)地点の色(RGB値)を取得するGetPixel関数で説明する。
この関数の定義は以下の通り、最初の引数にhDCを渡す。
Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
これをVB.NET(VB2005)で使おうとしてアップデートウィザードを使うと肝心のhDCが「'UPGRADE_ISSUE: Form プロパティ Form1.hdc はアップグレードされませんでした。」となり使えない。別件だが同じくWindowsAPIでよく使うウィンドウハンドル(.hWnd)は、.NET Frameworkでは(コントロール).Handleというプロパティになっており判りやすい。
いったいhDCはどうすれば指定できるのだ?と思い調べてみたところこんな具合になった。VB6との比較で紹介する。
例として起動したフォームの座標(x,y)地点の色(RGB値)を取得するGetPixel関数で説明する。
この関数の定義は以下の通り、最初の引数にhDCを渡す。
Declare Function GetPixel Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long) As Long
VB6:
Dim iro As Long
iro = GetPixel(Me.hdc, x, y) 'たったこれだけ。
VB.NET/VB2005:
Dim gp As Graphics = Me.CreateGraphics 'フォームのGraficsを作成
Dim hDC As IntPtr = gp.GetHdc() 'そのデバイスコンテキストを取得
Dim iro As Long = GetPixel(hDC, x, y) 'やっと使える
2007年10月15日
日付型(DateTime)の初期値を判定
VB6まではDate型は8バイトのDouble形式で値が格納されていた。
整数部が日付で小数部が時刻という具合である。
プログラムの中で日付型の変数に値があるかどうか、言い方を変えると使用されたかどうか、を判断するのにその値が0であるかどうかでチェックすることができた。
VB.NET(VB2005)になって仕様が変わってこの方法がそのまま使えなくなった。そこで違いを確認し、初期値(定義直後の値)を確認する方法をまとめた。
以下は日付型の変数にNow関数とDate関数(VB2005はToDay関数)で現在日時と現在日付を取得しそのまま表示させたものにVal関数とCDbl関数で変換を行っている。また変数を定義した直後の値も同様に表示している。VB2005の場合はToOADate関数でVB6のCDbl関数で取得したのと同様の結果が得られる。またToBinary関数ではVB6には無かった100ナノ秒単位までの値を含む64ビットのシリアル値を表示する。このToBinaryをみると定義直後の値が0であることが良く分かる。
・VB6の場合

・VB2005の場合

整数部が日付で小数部が時刻という具合である。
プログラムの中で日付型の変数に値があるかどうか、言い方を変えると使用されたかどうか、を判断するのにその値が0であるかどうかでチェックすることができた。
VB.NET(VB2005)になって仕様が変わってこの方法がそのまま使えなくなった。そこで違いを確認し、初期値(定義直後の値)を確認する方法をまとめた。
以下は日付型の変数にNow関数とDate関数(VB2005はToDay関数)で現在日時と現在日付を取得しそのまま表示させたものにVal関数とCDbl関数で変換を行っている。また変数を定義した直後の値も同様に表示している。VB2005の場合はToOADate関数でVB6のCDbl関数で取得したのと同様の結果が得られる。またToBinary関数ではVB6には無かった100ナノ秒単位までの値を含む64ビットのシリアル値を表示する。このToBinaryをみると定義直後の値が0であることが良く分かる。
・VB6の場合
Dim d1 As Date
d1 = Now
Text1.Text = d1
Label4.Caption = "Val : " & Val(d1) & vbCrLf & "CDbl : " & CDbl(d1)
Text2.Text = Date
Label5.Caption = "Val : " & Val(Date) & vbCrLf & "CDbl : " & CDbl(Date)
Dim d2 As Date
Text3.Text = d2
Label6.Caption = "Val : " & Val(d2) & vbCrLf & "CDbl : " & CDbl(d2)
・VB2005の場合
Dim d1 As DateTime = Now
TextBox1.Text = d1
Label4.Text = "Val : " & Val(d1) & vbCrLf & _
"ToOADate : " & d1.ToOADate & vbCrLf & _
"ToBinary : " & d1.ToBinary
TextBox2.Text = Today
Label5.Text = "Val : " & Val(Today) & vbCrLf & _
"ToOADate : " & Today.ToOADate & vbCrLf & _
"ToBinary : " & Today.ToBinary
Dim d2 As Date
TextBox3.Text = d2
Label6.Text = "Val : " & Val(d2) & vbCrLf & _
"ToOADate : " & d2.ToOADate & vbCrLf & _
"ToBinary : " & d2.ToBinary
2006年11月10日
次期OS「Vista」ではVisualBasic6はサポートされるが、VisualStudio.NET2002,2003はサポートされないんだと
http://www.microsoft.com/japan/msdn/vstudio/support/windowsvista/faq/
上記リンクにMicrosoftの言い分が載っている。
NET Frameworkが出現し、いずれVB6は対応しなくなる可能性があるからわざわざ.NETに移行した開発者はバカをみた事になるのか。そのままVB6で開発していればまだ生き長らえたかもしれないのにね。
開発ツールがサポートされなくなるだけでアプリケーションは動くらしい。でも開発できないんじゃやっぱりVS2005に移行させるしかないじゃん。VB6からの移行に比べたら何でもないけど・・・。
VB6のサポートを決めたのは、世にVB6アプリが沢山あって、歴史の浅い.NETアプリなんかよりずっと沢山の人々が使っているからなんだろう。
だったらVB2005の後はVB9としてアンマネージコードも作成できるようにして欲しいよ。
Windows VistaのBeta2とRC2を使っているけど、操作方法がいろいろ変わってまた覚えないといけない。XPが出たときもそうだったが、ベテランほどストレスが溜まるんだ。OSを独占している現在の状態が問題なのは言うまでも無い。Microsoftの意向が神の御告げのようにユーザーに降りかかるのである。
Linuxのように無料かそれに近い安さで公的な資産とし、ディストリビュータ毎にカスタマイズして競争させれば、一番使い勝手の良いものが売れるようになるだろうから、操作性もそう大幅に変わることも無いだろうにと思う。
上記リンクにMicrosoftの言い分が載っている。
NET Frameworkが出現し、いずれVB6は対応しなくなる可能性があるからわざわざ.NETに移行した開発者はバカをみた事になるのか。そのままVB6で開発していればまだ生き長らえたかもしれないのにね。
開発ツールがサポートされなくなるだけでアプリケーションは動くらしい。でも開発できないんじゃやっぱりVS2005に移行させるしかないじゃん。VB6からの移行に比べたら何でもないけど・・・。
VB6のサポートを決めたのは、世にVB6アプリが沢山あって、歴史の浅い.NETアプリなんかよりずっと沢山の人々が使っているからなんだろう。
だったらVB2005の後はVB9としてアンマネージコードも作成できるようにして欲しいよ。
Windows VistaのBeta2とRC2を使っているけど、操作方法がいろいろ変わってまた覚えないといけない。XPが出たときもそうだったが、ベテランほどストレスが溜まるんだ。OSを独占している現在の状態が問題なのは言うまでも無い。Microsoftの意向が神の御告げのようにユーザーに降りかかるのである。
Linuxのように無料かそれに近い安さで公的な資産とし、ディストリビュータ毎にカスタマイズして競争させれば、一番使い勝手の良いものが売れるようになるだろうから、操作性もそう大幅に変わることも無いだろうにと思う。
2006年09月29日
自アプリケーションのバージョンを取得
| Major | Minor | Build | Revision | |
|---|---|---|---|---|
| VB6 | App.Major | App.Minor | - | App.Revison |
| Label1.Cation = App.Major & "." & App.Minor & "." & App.Revision | ||||
| VB.NET | Dim Ver As New Version(Application.ProductVersion) | |||
| Ver.Major | Ver.Minor | Ver.Build | Ver.Revison | |
| Dim Ver As New Version(Application.ProductVersion) Label1.Text = Ver.ToString | ||||
| VB2005 | Dim Ver As Version = My.Application.Info.Version | |||
| Ver.Major | Ver.Minor | Ver.Build | Ver.Revison | |
| Label1.Text = My.Application.Info.Version.ToString | ||||
追加説明....
2006年09月28日
VB2005から新たに加えられたMouseイベント
前回のTips用サンプルを作っていたときに偶然見つけたのだが、DoubleClickイベントとは別にMouseDoubleClickイベントなるものがあるのに気が付いた。ヘルプをみたら、.NET Framework2.0つまりVB2005で新たに追加されたものらしい。
どう違うのか、理解しやすいようにバージョン毎のイベントの流れを比較してみる。
VB6よりVB.NETの方がイベントがスッキリしているが、VB2005になって複雑になった。細かく制御できるわけだがそこまで使うかどうか・・・。
ClickとMouseClick、DoubleClickとMouseDoubleClickの違いは、Mouseと名づけられた方が、純粋にマウスからのイベントだけを処理するものだ。
クリックイベントは、コントロールにフォーカスがあるときEnterキーやSpaceキーでも発生させることができるからだ。キーボードだけで操作したいこともあるからね。
どう違うのか、理解しやすいようにバージョン毎のイベントの流れを比較してみる。
ダブルクリックしたときのイベント発生順序
VB6 VB.NET VB2005
----------------------------------------------------
1. MouseDown MouseDown MouseDown
2. MouseUp Click Click
3. Click DoubleClick MouseClick
4. DblClick MouseUp MouseUp
5. MouseUp MouseDown
6. DoubleClick
7. MouseDoubleClick
8. MouseUp
----------------------------------------------------
VB6よりVB.NETの方がイベントがスッキリしているが、VB2005になって複雑になった。細かく制御できるわけだがそこまで使うかどうか・・・。
ClickとMouseClick、DoubleClickとMouseDoubleClickの違いは、Mouseと名づけられた方が、純粋にマウスからのイベントだけを処理するものだ。
クリックイベントは、コントロールにフォーカスがあるときEnterキーやSpaceキーでも発生させることができるからだ。キーボードだけで操作したいこともあるからね。
2006年09月26日
イベントの中で他のコントロールのクリックを実行するには
例として、リストボックスの項目を選択・確定する処理で説明する。
一般的には
1.リストボックスの項目をクリックし選択状態にし、
2.ボタンコントロールをクリックして確定する。
の2段階で行う。
これを
1.リストボックスの項目をダブルクリックして選択・確定する。
という1つのイベントで実行させたいことがある。
VB6では以下のようになる。
VB.NET(2005含)になると、VB6のようにイベントプロシージャをそのまま呼ぶことはできない。そこで登場するのが PerformClickメソッド。
ヘルプをみると「Clickイベントを発生させる」とある。クリック以外のイベントを発生させるメソッドがないか調べてみたがどうもなさそうだった。
一般的には
1.リストボックスの項目をクリックし選択状態にし、
2.ボタンコントロールをクリックして確定する。
の2段階で行う。
これを
1.リストボックスの項目をダブルクリックして選択・確定する。
という1つのイベントで実行させたいことがある。
VB6では以下のようになる。
Private Sub Form_Load()
With List1
.Clear
.AddItem "私"
.AddItem "お父さん"
.AddItem "お母さん"
.AddItem "お兄ちゃん"
.AddItem "お姉ちゃん"
.ListIndex = 0
End With
End Sub
'/// 選択したリストの項目を表示 ///
Private Sub Command1_Click()
MsgBox "「" & List1.List(List1.ListIndex) & "」が選ばれました"
End Sub
'/// ボタンのクリックを内部で実行 ///
Private Sub List1_DblClick()
Command1_Click '上記のクリックイベントを呼んでいるだけ
End Sub
VB.NET(2005含)になると、VB6のようにイベントプロシージャをそのまま呼ぶことはできない。そこで登場するのが PerformClickメソッド。
ヘルプをみると「Clickイベントを発生させる」とある。クリック以外のイベントを発生させるメソッドがないか調べてみたがどうもなさそうだった。
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
With ListBox1
.Items.Clear()
.Items.Add("私")
.Items.Add("お父さん")
.Items.Add("お母さん")
.Items.Add("お兄ちゃん")
.Items.Add("お姉ちゃん")
.SelectedIndex = 0
End With
End Sub
'/// 選択したリストの項目を表示 ///
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
MsgBox("「" & ListBox1.SelectedItem & "」が選ばれました")
End Sub
'/// ボタンのクリックイベントを発生させる ///
Private Sub ListBox1_DoubleClick(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles ListBox1.DoubleClick
Button1.PerformClick()
End Sub
2006年09月12日
TextBoxコントロールのよく使うプロパティ・メソッド比較
| VB6 | VB.NET(VB2005) | |
|---|---|---|
| コントロールに入力フォーカスを移す | Text1.SetForcus | TextBox1.Forcus() |
| 選択されたテキストの開始点を設定(取得) | Text1.SelStart=0 | TextBox1.SelectionStart=0 |
| 選択されたテキストの文字数を設定(取得) | Text1.SelLength=10 | TextBox1.SelectionLength=10 |
| 選択されたテキストの内容を設定(取得) | Text1.SelText="hoge" | TextBox1.SelectedText="hoge" |
| 指定した位置のテキストを選択 | (該当なし) | TextBox1.Select(0,10) これは下の2行と同じ TextBox1.SelectionStart=0 TextBox1.SelectionLength=10 |
| コントロールの全てテキストを選択 | (該当なし) | TextBox1.SelectAll() |
2006年09月08日
Erase ステートメントの違い
VB2005でデータベースからExecuteReaderでデータを読み込み、配列に代入するルーチンを作ったがなぜかアプリケーションエラーが発生する。(下図)

DBからのデータ取得はこれまでさんざんやってきた作業なのでコードに問題があるとは思えなくVB2005(ADO.NET 2.0)になってDataReaderのクラスが変わったのかなと思って調べてみたのだが、特にそれらしい記載はない。コードも代入する直前まで問題なく動いているので原因がなかなか判らなかった。
こうした場合エラーの原因は意外なところにあるもので、今回の場合ADO.NETの使い方ではなく代入先の配列の使い方にあった。
代入しようとする配列(変数のタイプは構造体)がNothingになっていたのだ。
えー、ちゃんと初期化してあるし、なんで?と思ったが確かにNothingになっている(下図)

何故Nothingになってたのか考えてみたところ、直前にEraseしているのが原因らしい。
実はVB6ではこれで問題なく動いていたのだ。ところがVB2005(VB.NETでも同じ)ではEraceの動きが違っている。
VB6のヘルプを見るとEraceの機能は
静的配列[Dim hoge(5) 添字を指定して宣言]
・・・変数を初期化(数値は0に、文字列は"")してくれる。
動的配列[Dim hoge() 添字を未指定にして宣言する]
・・・メモリを開放。その後ReDimする必要あり。
VB2005でもVB6と同様に静的配列の初期化を想定していたのだ。しかしVB6とは違い自動で初期化してくれなかった(^^;
※VB6ではこの初期化の機能が大変便利で、構造体の内部変数を初期化するのに、Eraseで一回で済むようわざわざ配列にしたくらいである。
VB2005のヘルプには「各配列変数に Nothing 値を割り当てるのと同じ結果になります」とある。サンプルは下のようになっている。
Dim threeDimArray(9, 9, 9), twoDimArray(9, 9) As Integer
Erase threeDimArray, twoDimArray
ReDim threeDimArray(4, 4, 9)
※VB6では静的配列をReDimできないのに、VB.NETではできてしまう!
これで直した結果、エラーは無くなった。(下図)
DBからのデータ取得はこれまでさんざんやってきた作業なのでコードに問題があるとは思えなくVB2005(ADO.NET 2.0)になってDataReaderのクラスが変わったのかなと思って調べてみたのだが、特にそれらしい記載はない。コードも代入する直前まで問題なく動いているので原因がなかなか判らなかった。
こうした場合エラーの原因は意外なところにあるもので、今回の場合ADO.NETの使い方ではなく代入先の配列の使い方にあった。
代入しようとする配列(変数のタイプは構造体)がNothingになっていたのだ。
えー、ちゃんと初期化してあるし、なんで?と思ったが確かにNothingになっている(下図)
何故Nothingになってたのか考えてみたところ、直前にEraseしているのが原因らしい。
実はVB6ではこれで問題なく動いていたのだ。ところがVB2005(VB.NETでも同じ)ではEraceの動きが違っている。
VB6のヘルプを見るとEraceの機能は
静的配列[Dim hoge(5) 添字を指定して宣言]
・・・変数を初期化(数値は0に、文字列は"")してくれる。
動的配列[Dim hoge() 添字を未指定にして宣言する]
・・・メモリを開放。その後ReDimする必要あり。
VB2005でもVB6と同様に静的配列の初期化を想定していたのだ。しかしVB6とは違い自動で初期化してくれなかった(^^;
※VB6ではこの初期化の機能が大変便利で、構造体の内部変数を初期化するのに、Eraseで一回で済むようわざわざ配列にしたくらいである。
VB2005のヘルプには「各配列変数に Nothing 値を割り当てるのと同じ結果になります」とある。サンプルは下のようになっている。
Dim threeDimArray(9, 9, 9), twoDimArray(9, 9) As Integer
Erase threeDimArray, twoDimArray
ReDim threeDimArray(4, 4, 9)
※VB6では静的配列をReDimできないのに、VB.NETではできてしまう!
これで直した結果、エラーは無くなった。(下図)
2006年06月30日
文字列から数値への変換(その2):IIF関数内での注意
VB6、VB.NET共通のコーディング上の注意です。
テキストボックス(Text1)に入力された文字を数値に変換する処理の場合
(例)Text1.Text = "abc"
上記のようにすればText1.Textの値に何がきても正しく処理されエラーになることはない、ところが次のようなコードにするとエラーになる。
これは、IIF関数がTrue時の式とFalse時の式を両方とも評価しているために起こる。つまり、CSng("abc")が実行されて「型が一致しません」のエラーになるからだ。
テキストボックス(Text1)に入力された文字を数値に変換する処理の場合
(例)Text1.Text = "abc"
Dim s As Single
If IsNumeric(Text1.Text) = False Then
s = 0
Else
s = CSng(Text1.Text)
End If
上記のようにすればText1.Textの値に何がきても正しく処理されエラーになることはない、ところが次のようなコードにするとエラーになる。
s = IIF(IsNumeric(Text1.Text) = False, 0, CSng(Text1.Text))
これは、IIF関数がTrue時の式とFalse時の式を両方とも評価しているために起こる。つまり、CSng("abc")が実行されて「型が一致しません」のエラーになるからだ。
2006年06月16日
文字列から数値への変換
VB.NETでもVB6の時とほとんど同じ使い方(Val関数・CSng関数)ができるが、Javaと同じParseメソッドもある。
また、変換時に注意すべき点は、金額などで"¥"や3桁毎のカンマ(,)を含んだ場合にVal関数は使えないということだ。
また、変換時に注意すべき点は、金額などで"¥"や3桁毎のカンマ(,)を含んだ場合にVal関数は使えないということだ。
| 実行サンプル | VB6:結果 | VB.NET:結果 |
|---|---|---|
| Val("1234.5") | 1234.5 | 1234.5 |
| Val("1,234.5") | 1 | 1 |
| Val("\1.234.5") | 0 | 0 |
| CSng("1234.5") | 1234.5 | 1234.5 |
| CSng("1,234.5") | 1234.5 | 1234.5 |
| CSng("\1,234.5") | 1234.5 | 1234.5 |
| Single.Parse("1234.5") | - | 1234.5 |
| Single.Parse("1,234.5") | - | 1234.5 |
| Single.Parse("\1,234.5") | - | 1234.5※ |
| ※Single.Parse("\1,234.5",NumberStyles.Any) としないとエラー | ||
2006年05月29日
ComboBoxの初期化:その2
以前紹介したComboBoxの初期化は単純にテキスト項目をセットするものだった。
今回はVB6のItemDataに相当する表示テキストとは別の値(数値)をセットする方法である。
これは予想外に手間取った。結論から言えばVB.NETにItemDataに相当するプロパティは無い。
オンラインマニュアル、サンプル、幾つかの参考書を調べても掲載されていないのだ。やっと見つけたのが「魔界の仮面弁士」さんの記事である。(この方は相当な経験と知識の持ち主である。これまでもオンラインソフトの開発では幾度となく助けられた。)
Addメソッドで登録できるのはVB6の場合はテキストのみだが、VB.NETではObject型に代わっている。つまりテキストの他何でも登録できるように進化している。
ただこれによってObject型の定義が事前に必要になってくる。共通モジュールにでも登録しておくといいだろう。
サンプルは前回のものを修正した。
今回はVB6のItemDataに相当する表示テキストとは別の値(数値)をセットする方法である。
これは予想外に手間取った。結論から言えばVB.NETにItemDataに相当するプロパティは無い。
オンラインマニュアル、サンプル、幾つかの参考書を調べても掲載されていないのだ。やっと見つけたのが「魔界の仮面弁士」さんの記事である。(この方は相当な経験と知識の持ち主である。これまでもオンラインソフトの開発では幾度となく助けられた。)
Addメソッドで登録できるのはVB6の場合はテキストのみだが、VB.NETではObject型に代わっている。つまりテキストの他何でも登録できるように進化している。
ただこれによってObject型の定義が事前に必要になってくる。共通モジュールにでも登録しておくといいだろう。
サンプルは前回のものを修正した。
VB6
Private Sub Form_Load()
With Combo1
.Clear
.Style = 2 'ドロップダウンリスト
.AddItem "その1"
.ItemData(.NewIndex) = 101 'ItemDataに値101をセット
.AddItem "その2"
.ItemData(.NewIndex) = 102
.AddItem "その3"
.ItemData(.NewIndex) = 103
.ListIndex = 0 '先頭を初期値に指定
End With
End Sub
'--- ItemDataを取り出す
Debug.Print Combo1.ItemData(Combo1.ListIndex)
VB.NET
'-- ComboBox用Item構造体 --
Public Structure ComboItem
Public Text As String '表示テキスト
Public Data As Integer '数値データ
'--- ToStringのオーバーライド(上書)
Public Overrides Function ToString() As String
Return Text
End Function
'--- コンストラクタ(Object生成時の初期化)の定義
Public Sub New(ByVal st As String, ByVal it As Integer)
Text = st
Data = it
End Sub
End Structure
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
With ComboBox1
.Text = ""
.Items.Clear()
.DropDownStyle = ComboBoxStyle.DropDownList
.BeginUpdate() 'EndUpdate()が呼び出されるまで描画しない
.Items.Add(New ComboItem("その1", 101))
.Items.Add(New ComboItem("その2", 102))
.Items.Add(New ComboItem("その3", 103))
.EndUpdate() 'ここで描画され、ちらつきが発生しない
.SelectedIndex = 0 '先頭を初期値に指定
End With
End Sub
'Dataの取り出し
Console.WriteLine DirectCast(ComboBox1.SelectedItem, ComboItem).Data
2006年05月17日
マウスカーソルが消えてしまう
以前VB6とVB.NETでのマウスカーソルの形状について比較を行った。
「マウスポインタ(カーソル)の形状」
今回とりあげるのは比較ではなく、VB6、VB.NETに関係なく両方に起きる困った現象である。
テキストボックスに入力したコードをキーとしてデータベースからデータを取得する、こういうプログラムを作った。その際、データを取得するまで若干時間が掛かるのでその間マウスカーソルを砂時計になるようにコードを記述した。
注)この処理はテキストボックスのキーイベント内部で行うものである。
ところが、実行すると砂時計になる前にマウスカーソルが消えてしまった。そしてデータが取得されたころ、つまり元のカーソルに戻すコードにきて現れた。
一体何だこれは?と思い。またVB.NETの特例かと心配になり、VB6で似たようなサンプルを作って確かめたところ、こっちでも同じようにマウスカーソルが消えてしまった。
最初は、データ取得にCPU負荷が大きすぎて表示する余裕がないためかと思い、Application.DoEventsメソッドなどを追加してみたのだがやはり表示されない。
いろいろ調べてみた結果、やっと分かったのが、コントロールパネルの「マウス」のプロパティで「文字の入力中にポインタを非表示にする」が有効になっているときに起きるということだった。これを無効にするとちゃんと砂時計が表示された。また、この現象はWindows2000で起きたのだが、マウスのプロパティが同じでもWindowsXPでは起きなかった。つまりWindows2000の問題のようである。
「マウスポインタ(カーソル)の形状」
今回とりあげるのは比較ではなく、VB6、VB.NETに関係なく両方に起きる困った現象である。
テキストボックスに入力したコードをキーとしてデータベースからデータを取得する、こういうプログラムを作った。その際、データを取得するまで若干時間が掛かるのでその間マウスカーソルを砂時計になるようにコードを記述した。
注)この処理はテキストボックスのキーイベント内部で行うものである。
ところが、実行すると砂時計になる前にマウスカーソルが消えてしまった。そしてデータが取得されたころ、つまり元のカーソルに戻すコードにきて現れた。
一体何だこれは?と思い。またVB.NETの特例かと心配になり、VB6で似たようなサンプルを作って確かめたところ、こっちでも同じようにマウスカーソルが消えてしまった。
最初は、データ取得にCPU負荷が大きすぎて表示する余裕がないためかと思い、Application.DoEventsメソッドなどを追加してみたのだがやはり表示されない。
いろいろ調べてみた結果、やっと分かったのが、コントロールパネルの「マウス」のプロパティで「文字の入力中にポインタを非表示にする」が有効になっているときに起きるということだった。これを無効にするとちゃんと砂時計が表示された。また、この現象はWindows2000で起きたのだが、マウスのプロパティが同じでもWindowsXPでは起きなかった。つまりWindows2000の問題のようである。
2006年05月16日
LabelコントロールのTextAlignとAutoSizeの連携動作の違い
2006年05月09日
フォームのスタイル
こんな初歩的なことでさえ判らないなんて情けないと思うが、それだけVB6とVB.NETは変ったという証拠(どっぷりVB6に漬かっていた証拠)でもある。
フォームを固定サイズにするためプロパティを変更しようと思ったのだが、どこにそれがあるのかすぐに判らなかった。VB6ではあまりにも慣れすぎた操作だったので同じように考えてそのプロパティが見つからないのである。
やっとそれらしきものを探したのだが、プロパティの値が英語で記述されていて迷った。下に対比表をまとめた。画面のキャプチャーも載せておく。
左がVB6、右がVB.NETのプロパティ画面
フォームを固定サイズにするためプロパティを変更しようと思ったのだが、どこにそれがあるのかすぐに判らなかった。VB6ではあまりにも慣れすぎた操作だったので同じように考えてそのプロパティが見つからないのである。
やっとそれらしきものを探したのだが、プロパティの値が英語で記述されていて迷った。下に対比表をまとめた。画面のキャプチャーも載せておく。
| スタイル ※VB6での呼び方 | VB6 (BorderStyle) | VB.NET (FormBorderStyle) |
|---|---|---|
| なし | 0 (vbBSNone) | None |
| 固定(実線) | 1 (vbFixedSingle) | FixedSingle |
| 可変 | 2 (vbSizable) | Sizable |
| 固定 ダイアログ | 3 (vbFixedDialog) | FixedDialog |
| 固定ツール ウィンドウ | 4 (vbFixedToolWindow) | FixedToolWindow |
| 可変ツール ウィンドウ | 5 (vbSizableToolwindow) | SizableToolWindow |
| 該当無し | 該当無し | Fixed3D |
2006年04月25日
和暦表示
VB.NETになって不便になったことはいろいろあるが、和暦表示はその最たるものの一つ。Format関数でダイレクトに使えないところが不便極まりない。
今回は取り上げないが、DateTimePicker(VB6ではDTPicker)コントロールでの和暦表示がコントロールパネルの地域オプションで日付を和暦にしないと使えないらしい。困ったことだ(--#
実はVB.NETには不具合のおまけがあり、1桁の年の場合 "ggy年M月d日"と記述しても平成0x年と0が頭に付いてしまう。
毎回長々と記述するのは賢くないので関数化すると以下のようになる。
今回は取り上げないが、DateTimePicker(VB6ではDTPicker)コントロールでの和暦表示がコントロールパネルの地域オプションで日付を和暦にしないと使えないらしい。困ったことだ(--#
VB6
'西暦の今日を和暦にする
Dim Wareki As String
Wareki = Format(Date, "gggee年mm月dd日")
'「平成18年04月25日」となる。
VB.NET
Dim Wareki As String
Dim cult As System.Globalization.CultureInfo = _
New System.Globalization.CultureInfo("ja-JP")
cult.DateTimeFormat.Calendar = _
New System.Globalization.JapaneseCalendar
Wareki = Today.ToString("ggyy年MM月dd日", cult)
実はVB.NETには不具合のおまけがあり、1桁の年の場合 "ggy年M月d日"と記述しても平成0x年と0が頭に付いてしまう。
毎回長々と記述するのは賢くないので関数化すると以下のようになる。
Imports System.Globalization
Public Function JpnFormat(ByVal tday As DateTime) As String
'tday : 日付
'-----------
Dim cult As CultureInfo = New CultureInfo("ja-JP")
cult.DateTimeFormat.Calendar = New JapaneseCalendar
Return tday.ToString("ggyy年MM月dd日", cult)
End Function
2006年02月28日
コントロール配列−その2
以前コントロール配列のイベント処理を扱ったが、データベースなどから取得したデータを画面に表示する場合など、コントロールに代入する際の方法を紹介する。VB6のようにコントロール配列が使えるととても楽になるのだが、VB.NET(ASP.NET)ではそれに代わる方法を用いるしかない。
例:配列の値を同数のテキストボックスに代入する
例:配列の値を同数のテキストボックスに代入する
VB6:
'配列の添字と同数のコントロール配列を用いる
Private Sub StrDataSet(dat() As String)
Dim L%, U%, i%
L% = LBound(dat)
U% = UBound(dat)
For i% = L% To U%
Text1(i%).Text = dat(i%)
Next i%
End Sub
VB.NET(Windowsアプリでは使えず、Web(ASP.NET)アプリで可)
'配列の添字と比例するコントロール名を使う
Private Sub StrDatSet(ByVal dat() As String)
Dim L, U, i As Integer
Dim tx As System.Web.UI.WebControls.TextBox
L = LBound(dat)
U = UBound(dat)
For i = L To U
'コントロール名を探し出す
tx = FindControl("TextBox" & CStr(i))
'見つかったコントロールのTextプロパティに代入
tx.Text = dat(i)
Next
End Sub

