伝票入力に最適化した DataGridView

  LboxGrid からのユーザーコード拡張



ブラウザでダウンロード


※ Visual Studio 2005 と Visual Studio 2008 で動作します
Lboxgrid_den

LboxGrid は、DataGridView を継承しており、列やカラムの処理を簡単に扱えるようなメソッドを実装していますが、
細やかな処理はユーザ側で記述する必要があります

このサンプルでは、コード参照用のボタンはまだ未実装ですが、
ユーザがコードを知っているという前提で、アプリケーションを作成する為のテンプレートです。


追加実装

1) 初期画面でのセルへの編集フォーカスの移動
2) Grid 内で最後のセルから先頭セルへの移動
( LboxGrid の仕様に合わせた調整 )
3) 列( ヘッダと明細 )のスタイル設定
4) 列単位での入力不可の設定





  ソースコード



Timer コンポーネントを Form に貼り付けてください

EnterKey イベントは、エンターキーを TAB キーを押した事にする前に割り込みで挿入
したユーザーイベントなので、ここでした操作の後、TAB キーが押された事になります。

ですから、移動したいカラムの一つ前に移動しておけば良いのですが、最終カラムでは
TAB キーを押しても通常では先頭に移動しないので、いろいろな使い勝手を想定して
遅延のフォーカス移動をタイマーで実装しています。

  
Public Class Form1

	Private Sub Form1_Load(ByVal sender As System.Object, _
	 ByVal e As System.EventArgs) Handles MyBase.Load


		' 列幅の自動調整をしない
		Me.LboxGrid1.AutoSizeColumnsMode = _
		 DataGridViewAutoSizeColumnsMode.None
		' 入力モードの開始は、フォーカスを取得した場合直ちに行う
		Me.LboxGrid1.EditMode = DataGridViewEditMode.EditOnEnter
		' Grid 全体の入力を可能にする
		Me.LboxGrid1.ReadOnly = False
		' 【拡張】タブキーとエンターキーを同等に扱う
		Me.LboxGrid1.isEnterToTab = True

		' タイトル用のスタイル
		Dim HeaderStyle As DataGridViewCellStyle = New DataGridViewCellStyle
		HeaderStyle.WrapMode = DataGridViewTriState.[False]  ' 自動改行しない
		Me.LboxGrid1.ColumnHeadersDefaultCellStyle = HeaderStyle

		' ************************************************
		' カラム追加
		' ************************************************
		Me.LboxGrid1.AddColumn("COL_1", "コード")
		Me.LboxGrid1.SetColumnWidth("COL_1", 40)

		Me.LboxGrid1.AddColumn("COL_2", "商品名")
		Me.LboxGrid1.SetColumnWidth("COL_2", 150)
		Me.LboxGrid1.Columns("COL_2").ReadOnly = True   ' この列は入力不可

		Me.LboxGrid1.AddColumn("COL_3", "数量")
		Me.LboxGrid1.SetColumnWidth("COL_3", 50)

		' 右寄せにする為、ヘッダとカラム用のスタイルを作成する
		Dim MiddleRight As DataGridViewCellStyle = New DataGridViewCellStyle
		MiddleRight.Alignment = DataGridViewContentAlignment.MiddleRight
		Me.LboxGrid1.Columns("COL_3").HeaderCell.Style = MiddleRight
		Me.LboxGrid1.Columns("COL_3").DefaultCellStyle = MiddleRight

		Me.LboxGrid1.AddColumn("COL_4", "単価")
		Me.LboxGrid1.SetColumnWidth("COL_4", 50)
		Me.LboxGrid1.Columns("COL_4").ReadOnly = True   ' この列は入力不可
		Me.LboxGrid1.Columns("COL_4").HeaderCell.Style = MiddleRight
		Me.LboxGrid1.Columns("COL_4").DefaultCellStyle = MiddleRight

		Me.LboxGrid1.AddColumn("COL_5", "金額")
		Me.LboxGrid1.SetColumnWidth("COL_5", 50)
		Me.LboxGrid1.Columns("COL_5").HeaderCell.Style = MiddleRight
		Me.LboxGrid1.Columns("COL_5").DefaultCellStyle = MiddleRight

		' 行を作成
		Dim I As Integer
		For I = 1 To 6
			Me.LboxGrid1.AddRow()
			Me.LboxGrid1.SetColumnText("COL_1", "")
			Me.LboxGrid1.SetColumnText("COL_2", "")
			Me.LboxGrid1.SetColumnText("COL_3", "")
			Me.LboxGrid1.SetColumnText("COL_4", "")
			Me.LboxGrid1.SetColumnText("COL_5", "")
		Next

		' 編集対象フォーカスの設定
		Me.LboxGrid1.SetFocusCell(0, 0)
		' 初期の編集可能なセルフォーカスの設定
		Me.LboxGrid1.EditingControl.Select()

	End Sub

	' **************************************************
	' 遅延フォーカス処理
	' **************************************************
	Private Sub setCellFocus(ByVal row As Integer, ByVal col As Integer)

		Dim pt As Point = New Point(col, row)
		Me.Timer1.Tag = pt
		Me.Timer1.Interval = 50
		Me.Timer1.Enabled = True

	End Sub

	' ************************************************
	' 【拡張イベント】セル内のエンターキー
	' ************************************************
	Private Sub LboxGrid1_EnterKey(ByVal e As lightbox.EnterKeyEventArgs) _
	Handles LboxGrid1.EnterKey

		Dim nCol As Integer = Me.LboxGrid1.CurrentCell.ColumnIndex
		Dim nRow As Integer = Me.LboxGrid1.CurrentCell.RowIndex

		' ******************************************************
		' カーソル移動制御
		' セルデータを確定して取得する為にカーソルを
		' カレントセルに Nothing をセットして移動させています
		' その後、ひとつ前のセルにフォーカス移動します
		' つまり、連続するセルの場合は自分自身にセットします
		' 最終カラムのみは遅延で先頭にフォーカス移動させます
		' ******************************************************
		If nCol = 0 Then
			Me.LboxGrid1.CurrentCell = Nothing
			Me.LboxGrid1.CurrentCell = Me.LboxGrid1(1, nRow)
		End If
		If nCol = 2 Then
			Me.LboxGrid1.CurrentCell = Nothing
			Me.LboxGrid1.CurrentCell = Me.LboxGrid1(3, nRow)
		End If
		' 最終行でない行の最終カラム
		If nCol = 4 And nRow <> 5 Then
			Me.LboxGrid1.CurrentCell = Nothing
			Me.LboxGrid1.CurrentCell = Me.LboxGrid1(4, nRow)
		End If

		' 最終カラムなので、先頭カラムへ移動
		If nCol = 4 And nRow = 5 Then
			Me.LboxGrid1.CurrentCell = Me.LboxGrid1(0, 0)
			Call setCellFocus(0, 0)
		End If

		' 確定した値を取得
		Dim value As String = Me.LboxGrid1.GetColumnText(nRow, nCol)
		Console.Out.WriteLine("確定データ:" & _
		 nRow.ToString() & ":" & nCol.ToString() & ":" & value)
		' **************************************************
		' 入力チェック
		' **************************************************
		If nCol = 0 Then
			If value = "" Then
				MessageBox.Show("未入力です")
				Call setCellFocus(nRow, nCol)
			End If
		End If

	End Sub

	' ************************************************
	' Grid内の遅延セルフォーカス用
	' ************************************************
	Private Sub Timer1_Tick(ByVal sender As System.Object, _
	 ByVal e As System.EventArgs) Handles Timer1.Tick

		Me.Timer1.Enabled = False

		Dim pt As Point = CType(Me.Timer1.Tag, Point)
		Me.LboxGrid1.CurrentCell = Me.LboxGrid1(pt.X, pt.Y)

	End Sub

End Class
  



  タイマー処理をプライペートクラスにラップしたバージョン

  
Public Class Form1

	Private tm As myTimer = New myTimer()
	' **************************************************
	' 遅延フォーカス用プライベートクラス
	' **************************************************
	Private Class myTimer
		Inherits System.Windows.Forms.Timer

		Private _col As Integer
		Private _row As Integer

		Protected Overrides Sub OnTick(ByVal e As System.EventArgs)
			MyBase.OnTick(e)

			Me.Enabled = False
			Form1.LboxGrid1.CurrentCell = Form1.LboxGrid1(_col, _row)
		End Sub

		Public Sub setCellFocus(ByVal row As Integer, ByVal col As Integer)

			_col = col : _row = row
			Me.Interval = 50
			Me.Enabled = True

		End Sub
	End Class

	Private Sub Form1_Load(ByVal sender As System.Object, _
	 ByVal e As System.EventArgs) Handles MyBase.Load


		' 列幅の自動調整をしない
		Me.LboxGrid1.AutoSizeColumnsMode = _
		 DataGridViewAutoSizeColumnsMode.None
		' 入力モードの開始は、フォーカスを取得した場合直ちに行う
		Me.LboxGrid1.EditMode = DataGridViewEditMode.EditOnEnter
		' Grid 全体の入力を可能にする
		Me.LboxGrid1.ReadOnly = False
		' 【拡張】タブキーとエンターキーを同等に扱う
		Me.LboxGrid1.isEnterToTab = True

		' タイトル用のスタイル
		Dim HeaderStyle As DataGridViewCellStyle = New DataGridViewCellStyle
		HeaderStyle.WrapMode = DataGridViewTriState.[False]  ' 自動改行しない
		Me.LboxGrid1.ColumnHeadersDefaultCellStyle = HeaderStyle

		' ************************************************
		' カラム追加
		' ************************************************
		Me.LboxGrid1.AddColumn("COL_1", "コード")
		Me.LboxGrid1.SetColumnWidth("COL_1", 40)

		Me.LboxGrid1.AddColumn("COL_2", "商品名")
		Me.LboxGrid1.SetColumnWidth("COL_2", 150)
		Me.LboxGrid1.Columns("COL_2").ReadOnly = True   ' この列は入力不可

		Me.LboxGrid1.AddColumn("COL_3", "数量")
		Me.LboxGrid1.SetColumnWidth("COL_3", 50)

		' 右寄せにする為、ヘッダとカラム用のスタイルを作成する
		Dim MiddleRight As DataGridViewCellStyle = New DataGridViewCellStyle
		MiddleRight.Alignment = DataGridViewContentAlignment.MiddleRight
		Me.LboxGrid1.Columns("COL_3").HeaderCell.Style = MiddleRight
		Me.LboxGrid1.Columns("COL_3").DefaultCellStyle = MiddleRight

		Me.LboxGrid1.AddColumn("COL_4", "単価")
		Me.LboxGrid1.SetColumnWidth("COL_4", 50)
		Me.LboxGrid1.Columns("COL_4").ReadOnly = True   ' この列は入力不可
		Me.LboxGrid1.Columns("COL_4").HeaderCell.Style = MiddleRight
		Me.LboxGrid1.Columns("COL_4").DefaultCellStyle = MiddleRight

		Me.LboxGrid1.AddColumn("COL_5", "金額")
		Me.LboxGrid1.SetColumnWidth("COL_5", 50)
		Me.LboxGrid1.Columns("COL_5").HeaderCell.Style = MiddleRight
		Me.LboxGrid1.Columns("COL_5").DefaultCellStyle = MiddleRight

		' 行を作成
		Dim I As Integer
		For I = 1 To 6
			Me.LboxGrid1.AddRow()
			Me.LboxGrid1.SetColumnText("COL_1", "")
			Me.LboxGrid1.SetColumnText("COL_2", "")
			Me.LboxGrid1.SetColumnText("COL_3", "")
			Me.LboxGrid1.SetColumnText("COL_4", "")
			Me.LboxGrid1.SetColumnText("COL_5", "")
		Next

		' 編集対象フォーカスの設定
		Me.LboxGrid1.SetFocusCell(0, 0)
		' 初期の編集可能なセルフォーカスの設定
		Me.LboxGrid1.EditingControl.Select()


	End Sub

	' ************************************************
	' 【拡張イベント】セル内のエンターキー
	' ************************************************
	Private Sub LboxGrid1_EnterKey(ByVal e As lightbox.EnterKeyEventArgs) _
	Handles LboxGrid1.EnterKey

		Dim nCol As Integer = Me.LboxGrid1.CurrentCell.ColumnIndex
		Dim nRow As Integer = Me.LboxGrid1.CurrentCell.RowIndex

		' ******************************************************
		' カーソル移動制御
		' セルデータを確定して取得する為にカーソルを
		' カレントセルに Nothing をセットして移動させています
		' その後、ひとつ前のセルにフォーカス移動します
		' つまり、連続するセルの場合は自分自身にセットします
		' 最終カラムのみは遅延で先頭にフォーカス移動させます
		' ******************************************************
		If nCol = 0 Then
			Me.LboxGrid1.CurrentCell = Nothing
			Me.LboxGrid1.CurrentCell = Me.LboxGrid1(1, nRow)
		End If
		If nCol = 2 Then
			Me.LboxGrid1.CurrentCell = Nothing
			Me.LboxGrid1.CurrentCell = Me.LboxGrid1(3, nRow)
		End If
		' 最終行でない行の最終カラム
		If nCol = 4 And nRow <> 5 Then
			Me.LboxGrid1.CurrentCell = Nothing
			Me.LboxGrid1.CurrentCell = Me.LboxGrid1(4, nRow)
		End If

		' 最終カラムなので、先頭カラムへ移動
		If nCol = 4 And nRow = 5 Then
			Me.LboxGrid1.CurrentCell = Me.LboxGrid1(0, 0)
			tm.setCellFocus(0, 0)
		End If

		' 確定した値を取得
		Dim value As String = Me.LboxGrid1.GetColumnText(nRow, nCol)
		Console.Out.WriteLine("確定データ:" & _
		 nRow.ToString() & ":" & nCol.ToString() & ":" & value)
		' **************************************************
		' 入力チェック
		' **************************************************
		If nCol = 0 Then
			If value = "" Then
				MessageBox.Show("未入力です")
				Call tm.setCellFocus(nRow, nCol)
			End If
		End If


	End Sub

End Class
  










  infoboard   管理者用   
このエントリーをはてなブックマークに追加





フリーフォントWEBサービス
SQLの窓WEBサービス

SQLの窓フリーソフト

素材

一般WEBツールリンク

SQLの窓

フリーソフト

JSライブラリ