-
VB.NETのフォームに張り付けた入力コントロールの遷移は通常は「Tab」キーで行えますが、 「Enter」キーでも次の入力コントロールへフォーカスを移動したい要求は少なからずあります。
普通の人はテキストボックスに何かを入力し、入力の最後に「Enter」を押したくなります。 キーボードの配置(形)からしても1個の入力後は「Enter」を押すことが前提の様な感じがします。
さて、複数のTextBoxを並べたFormを例にしますが、画面的には以下の様な感じです。 この画面で、各TextBoxで「Enter」キーを押下した時に、次のコントロールにフォーカスを移動させます。
次のコントロールにフォーカスを移動させるためのメソッドが、Formコントロールのメソッドとして在ります。 以下のメソッドがそうです。
-----
SelectNextControl(ctl As System.Windows.Forms.Control, forward As Boolean, tabStopOnly As Boolean, nested As Boolean, wrap As Boolean) As Boolean
-----
引数 内容 ctl
検索を開始する位置にある System.Windows.Forms.Control forward
タブ オーダー内を前方に移動する場合は true、後方に移動する場合は false tabStopOnly
System.Windows.Forms.Control.TabStop プロパティが false に設定されているコントロールを無視する場合は true、それ以外の場合は false nested
入れ子になった (子コントロールの子) 子コントロールを含める場合は true、それ以外の場合は false wrap
タブ オーダーの最後のコントロールに到達した後、タブ オーダーの最初のコントロールから検索を続行する場合は true、それ以外の場合は false
このメソッドをKeyDownイベントで呼出せる形でメソッド化し、 FormのKeyDownで呼出してやるか、または、フォームのコンストラクタでKeyDownイベントにハンドラとして追加してやります。
以下のソースでは、コンストラクタでKeyDownイベントにハンドラを追加しています。
Public Class Form2 '当クラスのコンストラクタ Public Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 '「Enter」キーでのコントロール遷移処理の設定 Me.KeyPreview = True AddHandler Me.KeyDown, AddressOf MoveNextCtrl AddHandler Me.KeyPress, AddressOf MoveNextCtrlBeepSup End Sub '「Enter」キーによるコントロールの移動メソッド Private Sub MoveNextCtrl(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Try If e.KeyCode = Keys.Enter Then Dim fProc As Boolean = True If TypeOf sender.ActiveControl Is TextBox Then If (CType(sender.ActiveControl, TextBox)).Multiline = True Then fProc = False End If End If '次のコントロールをアクティブにします。 If fProc Then 'forward: タブ オーダー内を前方に移動する場合は true。後方に移動する場合は false。 Dim forward As Boolean = e.Modifiers <> Keys.Shift sender.SelectNextControl(sender.ActiveControl, forward, True, True, True) End If End If Catch ex As Exception MsgBox("PGエラー:" & ex.ToString) End Try End Sub '「Enter」キーによるコントロールの移動メソッド時にビープ音の消音 Private Sub MoveNextCtrlBeepSup(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Try 'Enterキーが押された事を取得 If e.KeyChar = Chr(Keys.Enter) Then Dim fProc As Boolean = True If TypeOf sender.ActiveControl Is TextBox Then If (CType(sender.ActiveControl, TextBox)).Multiline = True Then fProc = False End If End If 'イベントをキャンセルでBeep音の消音 If fProc Then e.Handled = True End If End If Catch ex As Exception MsgBox("PGエラー:" & ex.ToString) End Try End Sub End Class
■「Enter」キーによるコントロールの移動メソッド時にビープ音の消音
入力コントロールで「Enter」キーを押下するとビーとBeep音がなります。 これを止めるには、KeyDownイベントで「Enter」の次のコントロール移動をした様に、 KeyPressイベントで、「Enter」キー入力時にイベント処理のキャンセルを行うことです。
=====
2016/03/14:の時の情報
PR -
花粉予報が気になる時期になってきました。「花粉」という言葉に春を感じますが、みなさんは如何でしょうか。
春と言えばフレッシュな社会人や学生さんを連想しますが、VB.NETを始めたころも春だった様な...
そこでこのブログのVB.NET関連の記事ですが、データ変換などと基本的なものを取り上げました。 オブジェクト型から各種のデータ型への変換関数を以下のソースに示します。 オブジェクト型から変換する場合、いろいろな方法がありますが、 各データ型への変換メソッド「Parse」を使うのが一番簡単です。 この「Parse」ですが、変換に失敗を Try ... Catch で捉えられるのでエラー発生時にデフォルト値を返します。
これらの関数を利用する場面ですが、 データベースからの数値データを取得する場合にNULLデータを0に変換したい時によく使っています。
''' -------------------------------------------------------- ''' <summary>Object型からInteger型変換</summary> ''' <param name="obj">変換元Object型データ</param> ''' <returns>変換後Integer型データ(変換不可の場合は0)</returns> ''' -------------------------------------------------------- Public Function ObjectToInt(ByVal obj As Object) As Integer Try Return Integer.Parse(obj) Catch ex As Exception Return 0 End Try End Function ''' -------------------------------------------------------- ''' <summary>Object型からDecimal型変換</summary> ''' <param name="obj">変換元Object型データ</param> ''' <returns>変換後Decimal型データ(変換不可の場合は0)</returns> ''' -------------------------------------------------------- Public Function ObjectToDec(ByVal obj As Object) As Decimal Try Return Decimal.Parse(obj) Catch ex As Exception Return 0 End Try End Function ''' -------------------------------------------------------- ''' <summary>Object型からLong型変換</summary> ''' <param name="obj">変換元Object型データ</param> ''' <returns>変換後Long型データ(変換不可の場合は0)</returns> ''' -------------------------------------------------------- Public Function ObjectToLng(ByVal obj As Object) As Long Try Return Decimal.Parse(obj) Catch ex As Exception Return 0 End Try End Function ''' -------------------------------------------------------- ''' <summary>Object型からDouble型変換</summary> ''' <param name="obj">変換元Object型データ</param> ''' <returns>変換後Double型データ(変換不可の場合は0)</returns> ''' -------------------------------------------------------- Public Function ObjectToDbl(ByVal obj As Object) As Double Try Return Decimal.Parse(obj) Catch ex As Exception Return 0.0 End Try End Function ''' -------------------------------------------------------- ''' <summary>Object型からString型変換</summary> ''' <param name="obj">変換元Object型データ</param> ''' <returns>変換後String型データ(変換不可の場合は"")</returns> ''' -------------------------------------------------------- Public Function ObjToStr(ByVal obj As Object) As String Try Return obj.ToString Catch ex As Exception Return "" End Try End Function
このソースは単に「Public Function」と宣言していますので、 静的なModuleかSharedなクラスで宣言してどこからでも参照出来る様にすればいいと思います。
=====
2016/03/14:の時の情報
-
前回、PostgreSQLにおいて、複数行の整数を返すことができる関数「generate_series」を紹介しましたが、 Oracleでは関数ではなく階層問合せ用の「LEVEL疑似列」を使うことで可能になります。
以下のSQLの実行を見てください。(SQLコマンドラインから実行しています)
SQL> SELECT LEVEL FROM DUAL CONNECT BY LEVEL <= 5; LEVEL ---------- 1 2 3 4 5
階層問合せにおいて「CONNECT BY」句は親子関係の条件を指定するのですが、この場合は 「LEVEL疑似列」自身がそのまま、それ自体として条件づけられるので、 「LEVEL <= 5」により5個以下のレベル値が返るようです。 私自身もよくわかっていないのですが...
さらにこのSQL文をテーブルとして扱えば、以下の様にもできます。
SQL> SELECT CURRENT_DATE + X.LVL FROM 2 (SELECT LEVEL AS LVL FROM DUAL CONNECT BY LEVEL <= 5) X; CURRENT_ -------- 16-03-13 16-03-14 16-03-15 16-03-16 16-03-17
=====
2016/03/12:の時の情報
-
PostgreSQLでシステム日付を取得する場合には、以下の様なFROMの無いSQL文で行います。 PostgreSQLではFROMが必要なければ記述することはありません。
PostgreSQLの「SQL Shell(psql)」で実行します。
postgres=# SELECT NOW(); now ---------------------------- 2016-03-10 14:44:20.369+09 (1 行)
定数を同時にSELECT取得することもできます。
postgres=# SELECT NOW() AS DATETIME, 1 AS NumberTest, 'TEST' AS StringTest; datetime | numbertest | stringtest ----------------------------+------------+------------ 2016-03-10 14:47:16.987+09 | 1 | TEST (1 行)
ここで、PostgreSQLの面白い関数について紹介します。 それが「generate_series」で複数行の整数を返すことができます。
関数 動作内容 generate_series(start, stop)
グラフィックstartからstopまでの刻み1で連続する値を生成 generate_series(start, stop, step)
startからstopまでの刻みstepで連続する値を生成
以下にその例を示します。
postgres=# SELECT generate_series(1, 3); generate_series ----------------- 1 2 3 (3 行) postgres=# SELECT * FROM generate_series(1, 3); generate_series ----------------- 1 2 3 (3 行) postgres=# SELECT NumTbl.NumVal FROM generate_series(1, 3) AS NumTbl(NumVal); numval -------- 1 2 3 (3 行)
1番目の様にSELECT文のなかのカラムを記述するところにいれてもいいですし、 また、2番目の様にFROM句でテーブル扱いにしてもOKです。 さらに、3番目ではテーブルの別名として「NumTbl(NumVal)」(仮にここでの命名)とすると 生成される数値を「NumTbl」テーブルのカラム名「NumVal」で参照ができます。
この3番目の方法を使うことでいろいろ応用が利くと思います。 以下は、今日からの3日間を羅列するSQL文になります。
postgres=# SELECT current_date + N.V FROM generate_series(1, 3) AS N(V); ?column? ------------ 2016-03-11 2016-03-12 2016-03-13 (3 行)
=====
2016/03/05:の時の情報
-
ラベルプリンタメーカ「SATO」のラベル発行コンポーネント(MLComponent.dll)を使ったラベル印刷の紹介ですが、 レイアウトファイルとプリンタドライバを利用して行います。 USBへの直接出力もできるようですが、制御が難しい様なので、プリンタドライバへの出力で印刷します。
■印刷用レイアウトファイル
ラベル印刷を簡単に行うにはレイアウトファイルが必要になります。 このレイアウトファイルですがSATOが提供する「SATO Multi LABELIST V5 [MLデザイン]」で作成します。 Trail(試用)のままでも1個のファイルは生成が可能ですので、以下のURLからダウンロードしてみてください。
・Multi LABELIST V5
今回使用するレイアウトファイルの編集中の画面を以下に示します。 連番(NO)、日付、品番、QRコードのみを印刷する簡単なレイアウトで、デザインを作成したところです。
また、下図は印刷の定義順の設定の画面です。
定義順は1:連番(NO)、2:日付、3:品番、4:QRコード となっています。
実際のプログラムでのデータ設定の順番は、定義順に行います。
■プリンタ状態チェック関数
関数内の処理は以下の手順で行います。
(1)「MLComponent」のインスタンスを生成します。
(2)レイアウトファイルの設定
「MLComponent」の「LayoutFile」プロパティに、[MLデザイン]で作成されたレイアウトファイルを設定します。
(3)印刷データの設定
「MLComponent」の「PrnData」プロパティに、印刷データを設定します。
印刷データは印刷定義順に従って、各データを「タブ」文字を挟んで文字列で連結します。
最後に「印刷枚数」をさらに「タブ」文字を挟んで追加連結します。(今回は1枚なので"1"を連結)
(4)出力先の設定
「MLComponent」の「Setting」プロパティに、プリンタドライバ名を指定します。 (今回は「Lesprit412v」プリンタなので"DRV:SATO Lesprit412v")
(5)接続処理
「MLComponent」の「OpenPort」メソッドで接続します。
(6)発行処理
「MLComponent」の「Output」メソッドでラベル印刷の発行を行います。
(7)切断処理
「MLComponent」の「ClosePort」メソッドで切断します。
Module Module1 'SATOプリンタの印刷テスト Public Sub Main() Dim str As String = "" Dim fChk As Boolean = PrintLabel(1, "10001", str) MsgBox(str) End Sub ''' <summary>ラベル印刷</summary> ''' <param name="nNo">NO</param> ''' <param name="strHinban">品番</param> ''' <returns>印刷結果(True:OK, False:NG)</returns> Private Function PrintLabel(ByVal nNo As Integer, _ ByVal strHinban As String, ByRef strErr As String) As Boolean '戻り値初期化 PrintLabel = False 'MLComponentの宣言 Dim MLComponent As SATO.MLComponent.MLComponent = New SATO.MLComponent.MLComponent Try 'レイアウトファイルの設定 MLComponent.LayoutFile = "Layout.mllayx" '設定データ生成 Dim strData As String = "" 'ヘッダ strData &= nNo.ToString("00000000") 'NO strData &= vbTab & Now.ToString("yyyy/MM/dd") '日付 strData &= vbTab & strHinban '品番 'QRバーコードデータ(NO,日付,日付を設定) Dim strQR As String = "" strQR = "NO=" & nNo.ToString("00000000") 'NO strQR &= ",DATE=" & Now.ToString("yyyy/MM/dd") '日付 strQR &= ",HIN=" & strHinban '日付 'QRバーコードデータを設定データに付加 strData &= vbTab & strQR '発行枚数を設定データに付加 strData &= vbTab & "1" 'データの設定 MLComponent.PrnData = strData '出力先の設定(プリンタドライバ名を指定します。) MLComponent.Setting = "DRV:SATO Lesprit412v" '接続 Dim Result As Integer Result = MLComponent.OpenPort(1) If Result <> 0 Then strErr = "接続エラー No." & Result.ToString Exit Function End If '発行 Result = MLComponent.Output If Result <> 0 Then strErr = "発行エラー No." & Result.ToString Exit Function End If '切断 Result = MLComponent.ClosePort If Result <> 0 Then strErr = "切断エラー No." & Result.ToString Exit Function End If '戻り値OK PrintLabel = True Catch ex As Exception strErr = "その他エラー :" & ex.ToString Finally MLComponent = Nothing End Try End Function End Module
■プリンタドライバ
プリンタドライバのプロパティでUSBでの接続にしてあります。
プリンタドライバは以下のURLでダウンロードできます。
・プリンタドライバ・マニュアル
=====
2016/03/09:の時の情報