表計算風?項目入力例 <TOP>
表計算のような項目に入力する場合、FlexGridのようなものがないので文字数固定のセルを2頁に分けて入力する方法を考えてみました。
エディットボックスで入力しフォーカスが外れるとピクチャボックスに書き出しています。
マウスを置いたセルは淡い黄色の背景色になり、文字入力後【Enter】押下で次のセルに移動します。
図の例では、住所1のセル入力後【Enter】で次のセルに移動しますが、住所2のセルは途中で切れているので2頁目に切り替わります。
セルに文字が入っている場合は文字の最後尾にカーソルが移動し、数値が入っている場合は全範囲選択状態で入力待ちになります。
手っ取り早く試用できるようGRID.LZHにテストデータ共々入れてあります。
メインフォームにエディットボックス、ピクチャボックス、水平スクロールバー、コマンドボタンを貼り付けます。
エディットボックス:複数行入力あり(Enter移動部の方法にる)、垂直オートスクロールあり、3D表示なし、可視なしに設定します。
枠無し、背景色を淡い黄色に設定するためリソースを書き換える必要があります。
フォーム :ピクセルモード
ピクチャボックス :ピクセルモード、境界線あり、境界線あり、可視なしに設定。保存ボタンは確認のために設けています。
スクロールバー :あまり意味はありません。テスト用です。
リソースの書き換え(初期状態)
__BEGIN
__CREATE3, XWT_EDIT, 0x40810144L, 0x0L
__ATTRDATA3, 0x0L
__WINDOWTITLE, "\0"
__CONTROLNAME, "EDIT1\0"
__LIMITTEXT3, 0x12L
__CTRLTEXTCOLOR, 0x0L
__CTRLBACKCOLOR, 0xffffffL
__FONTSIZE, 8
__FONTNAME2, "MS ゴシック\0",
1, 186
__IMEMODE3, 0x1L
__WINDOWSIZE3, 0x0L, 0x10L,
0x22L, 0x5eL, 0x16L
__EVENT
上記赤文字の部分を下記のとおり書き換えます。
イ.境界線なし
__CREATE3,
XWT_EDIT, 0x40810144L, 0x0L
↓8を0に
__CREATE3,
XWT_EDIT, 0x40010144L, 0x0L
ロ.白を薄い黄色に(あまり薄色に設定すると液晶では判別しにくいようです)
__CTRLBACKCOLOR,
0xffffffL
↓
__CTRLBACKCOLOR,
0xe0ffffL
'================================================================
'= EXCEL風入力テスト
'================================================================
#include "Windows.bi"
Var Shared MainForm As Object
Var Shared Edit As Object
Var Shared Picture As Object
Var Shared HScroll As Object
Var Shared Button As Object
Var Shared CrLf$ As String '
Var Shared EPos As Integer 'CRLF取得位置(Enter移動用)
Var Shared Col As Integer '列番号(項目)
Var Shared Row As Integer '行番号
Var Shared ColMax As Integer 'セル最大値
Var Shared ColMax1 As Integer '1面表示(1〜Col1)
Var Shared ColMax2 As Integer '2面表示(ColMax2〜ColMax)
Var Shared RowMax As Integer '行最大値
Var Shared RowHeight As Integer '行間隔
Var Shared YPos As Integer 'Y軸(横罫線、文字表示位置)
Var Shared XPos(21) As Integer 'X軸(縦罫線、文字表示位置)
Var Shared Mx As Integer 'X軸(マウスクリック位置)
Var Shared My As Integer 'Y軸(マウスクリック位置)
Var Shared Dt$(21,30) As String 'データ格納(最大20×30)
Var Shared Item$(21,3) As String '0:項目名 1:文字数 2:IME制御 3:数値扱
Var Shared CellWidth(21) As Integer 'セル幅
Var Shared FtName$ As String 'フォント
Var Shared FrameTop As Integer '枠上位置
Var Shared FrameBottom As Integer '枠下位置
Var Shared FrameLeft As Integer '枠左位置
Var Shared FrameRight As Integer '枠右位置
Var Shared FrameWidth As Integer '1面+2面項目総幅
Var Shared FrameWidth2 As Integer '2面項目総幅
Var Shared FontSize As Integer 'フォントサイズ
Var Shared FrmWidth As Integer 'フォーム幅
Var Shared FrmHeight As Integer 'フォーム高
Var Shared DataMax As Long '
Var Shared PageFlg As byte '1面/2面
Var Shared ColOfst As Integer '
Var Shared OffSet As Integer '
MainForm.Attach GethWnd
Edit.Attach GetDlgItem("Edit1")
Picture.Attach GetDlgItem("Picture1")
HScroll.Attach GetDlgItem("HScroll1")
Button.Attach GetDlgItem("Button1")
Declare Sub MainForm_Start edecl ()
Declare Sub Picture1_Click edecl () 'マウスクリック位置確認
Declare Sub EditBox_Move edecl () 'EditBox表示位置
Declare Sub Grid_Draw edecl () '★Picture1
Declare Sub Data_Read edecl ()
Declare Sub Data_Dsp edecl ()
Declare Sub Separate_Point edecl ()
'================================================================
'= 例:20項目のデータを用意
'================================================================
Sub MainForm_Start()
SetMapMode 1
CrLf$ = Chr$(13,10)
'▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼▼
' 項目名 半角換算文字数 IME制御 文字・数値
' Item$(x,0) Item$(x,1) Item$(x,2) Item$(x,3)
'--------------------------------------------------
data "名前" ,20 ,4 ,0
data "ヨミ" ,10 ,6 ,0
data "敬称" ,6 ,4 ,0
data "連名1" ,8 ,4 ,0
data "連名2" ,8 ,4 ,0
data "連名3" ,8 ,4 ,0
data "会社名" ,20 ,4 ,0
data "役職" ,14 ,4 ,0
data "〒" ,8 ,2 ,0
data "住所1" ,40 ,4 ,0
data "住所2" ,40 ,4 ,0
data "電話" ,15 ,2 ,0
data "金額" ,10 ,2 ,1
data "文字1" ,10 ,4 ,0
data "文字2" ,16 ,4 ,0
data "文字3" ,20 ,4 ,0
data "数値1" ,8 ,2 ,1
data "数値2" ,8 ,2 ,1
data "数値3" ,8 ,2 ,1
data "数値4" ,8 ,2 ,1
'--------------------------------------------------
If GetDeviceCaps(8) < 1280 Then
FontSize = 12 'フォントサイズ(18P以下偶数)
Else
FontSize = 14 'フォントサイズ(18P以下偶数)
End If
ColMax = 20 '項目数
RowMax = 30 '行数
RowHeight = FontSize + 8 '行間隔(ドット)文字位置(上4ドット/下4ドット)
FrameLeft = 24 'グリッド左位置
FrameTop = 24 'グリッド上位置
FrameBottom = FrameTop + RowMax * RowHeight 'グリッド下位置
FtName$ = "MS ゴシック"
MainForm.MaximizeWindow 'フォーム最大
MainForm.MoveWindow 0, 0
FrmWidth = MainForm.GetWidth 'フォーム幅
FrmHeight = MainForm.GetHeight 'フォーム高
MainForm.ShowWindow -1 '
'▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲▲
MainForm.SetFontName FtName$
Picture.SetFontName FtName$
Picture.SetFontBold 0
MainForm.SetFontSize FontSize
Picture.SetFontSize FontSize
Button.SetFontSize FontSize
'******************************
'項目名,入力可能文字数(半角換算),IME制御読込
'******************************
XPos(0) = 0
FrameWidth = 0
For i = 1 To ColMax
For J = 0 To 3
Read Item$(I, J)
Next J
If i > 0 Then CellWidth(I) = Val(Item$(i, 1)) * FontSize / 2 + 8 '+8:文字前後4ドット
XPos(i) = XPos(i - 1) + CellWidth(i) + 1
FrameWidth = FrameWidth + CellWidth(i) + 1 'グリッド幅
Next I
'------------------------------
'ピクチャボックス用意
'------------------------------
Picture.SetWindowSize FrmWidth - 8 - FrameLeft * 2, FrameBottom '-8(4 * 2:フォーム枠立体部)
Picture.MoveWindow FrameLeft, FrameTop
Button.SetWindowSize 30, 24 '保存(テスト用)
Button.MoveWindow 4, FrmHeight - 60 '
Button.ShowWindow -1
Separate_Point '面/2面区切位置取得
If RowMax * RowHeight + FrameTop + 20 > FrmHeight Then
A% = MessageBox(GetWindowText, "行数を減らしてください!", 0, 2) : Stop : End
Else If FrameWidth2 > FrmWidth - 8 - FrameLeft * 2 Then
A% = MessageBox(GetWindowText, "フィールド数を減らすかフォントサイズを小さくしてください!", 0, 2) : Stop : End
Else If FontSize Mod 2 <> 0 Then
A% = MessageBox(GetWindowText, "フォントサイズは偶数で指定してください!", 0, 2) : Stop : End
End If
PageFlg = 0
OffSet = 0
Col = 1
Row = 1
Grid_Draw
Data_Read
Data_Dsp
Picture.ShowWindow -1
EditBox_Move
End sub
'================================================================
'= 切替位置取得
'================================================================
Sub Separate_Point()
WD = 0
For i = 1 To ColMax
WD = WD + CellWidth(I) + 1
If WD > FrmWidth - FrameLeft * 2 Then
ColMax1 = i - 1 '★1面(1〜ColMax1)
Exit For
End If
Next i
WD = 0
For i = ColMax To 1 Step -1
WD = WD + CellWidth(i) + 1
If WD >= FrmWidth - FrameLeft * 2 Then
ColMax2 = i '★2面(ColMax2〜ColMax)
Exit For
End If
Next i
WD = 0
For i = ColMax1 + 1 To ColMax
WD = WD + CellWidth(i) + 1
Next i
FrameWidth2 = WD '2面項目総幅
WD = 0
For i = 1 To ColMax2
WD = WD + CellWidth(i) + 1
Next i
ColOfst = WD 'オフセット
End sub
'================================================================
'= Picture1描画
'================================================================
Sub Grid_Draw()
Picture.Cls
Picture.Line(XPos(0), 0) - (XPos(ColMax) - 1, RowHeight), , 14, bf '項目名下罫線
For i = 0 To ColMax
Picture.Line(XPos(i) - OffSet, 0)-(XPos(i) - OffSet, RowHeight), , 1 '縦罫線(項目)
Picture.Line(XPos(i + 1) - OffSet, RowHeight) - (XPos(i + 1) - OffSet, FrameBottom), , 14 '縦罫線
If i < ColMax Then Picture.Line(XPos(i) - OffSet + 1, 0) - (XPos(i) - OffSet + 1, RowHeight), , 15 '縦罫線
Next
Picture.Line(XPos(0), RowHeight) - (XPos(ColMax) - 1, RowHeight), , 1 '項目名下罫線
Picture.Line(XPos(0), 1) - (XPos(ColMax), 1), , 15 '横罫線
Picture.Line(XPos(0), RowHeight) - (XPos(ColMax), RowHeight), , 1 '横罫線
For i = RowHeight * 2 To RowHeight * RowMax Step RowHeight
Picture.Line(XPos(0), i) - (XPos(ColMax), i), , 14 '横罫線
Next
Picture.Line(XPos(0), 0) - (FrmWidth - FrameLeft * 2 - 1, FrameBottom), , 0, b '外枠(ピクチュアボックス境界線なし時)
HScroll.SetWindowSize FrmWidth - 8 - FrameLeft * 2, 16
HScroll.MoveWindow FrameLeft, FrameBottom + RowHeight + 4
HScroll.ShowWindow -1
HScroll.SetScrollRange 0, ColMax + 1
HScroll.SetScrollPos Col
HScroll.SetScrollStep 1, 1
For i = 1 To ColMax
Picture.Symbol(XPos(i - 1) - OffSet + (CellWidth(i) - Len(Item$(i, 0)) * FontSize / 2) / 2 + 4, 6), Item$(i, 0), 1, 1, 0
Next
Data_Dsp
End sub
'================================================================
'= データ表示
'================================================================
Sub Data_Dsp()
YPos = RowHeight
If PageFlg = 0 Then
ST = 1
ED = ColMax
Else
ST = ColMax2 + 1
ED = ColMax
End If
For i = 1 To RowMax
For j = ST To ED
If Val(Item$(J, 3)) = 1 Then '数値表示
Num$ = Right$("###,###,###,###",Val(Item$(J, 1)))
If Left$(Num$, 1) = "," Then Num$ = " " & Right$(Num$, Len(Num$) -1)
Picture.Symbol(XPos(J - 1) - OffSet + 4, YPos + (i - 1) * RowHeight + 4), Format$(Val(Dt$(j, i)), Num$), 1, 1
Else '文字表示
Picture.Symbol(XPos(J - 1) - OffSet + 4, YPos+(I - 1) * RowHeight + 4), Left$(Dt$(j, i), Val(Item$(j, 1))), 1, 1
End If
Next j
Next i
End sub
'================================================================
'= スクロールバーでの移動
'================================================================
Declare Sub HScroll1_Change edecl ()
Sub HScroll1_Change()
Col = HScroll.GetScrollPos '位置取得
If PageFlg = 0 Then '★1面
If Col > ColMax1 Then '最大項目を超過
Edit.ShowWindow 0
PageFlg = 1
OffSet = ColOfst
Grid_Draw
Else If Col < 1 Then
Edit.ShowWindow 0
Col = ColMax
Row = Row - 1 : If Row < 1 Then Row = 1
PageFlg = 1
OffSet = ColOfst
Grid_Draw
End If
Else '★2面
If Col > ColMax Then
Edit.ShowWindow 0
Col = 1
Row = Row + 1 : If Row > RowMax Then Row = 1 '行制限
PageFlg = 0
OffSet = 0
Grid_Draw
Else If Col <= ColMax2 Then
Edit.ShowWindow 0
Row = Row - 1 : If Row < 1 Then Row = 1
PageFlg = 0
OffSet = 0
Grid_Draw
End If
End If
EditBox_Move
End sub
'================================================================
'= マウスによる行位置取得
'================================================================
Sub Picture1_Click()
Mx = Mouse(0)
My = Mouse(1)
If PageFlg = 0 Then ColMaxEnd = ColMax1 Else ColMaxEnd = ColMax
For i = 1 To ColMaxEnd
If Mx + OffSet > XPos(i - 1) And Mx + OffSet < XPos(i) Then
Col = i
Exit for
Else
Col = 0
End If
Next i
Select Case My
Case RowHeight To FrameBottom
Row = (My - FrameTop) \ RowHeight + 1
YPos = FrameTop + (Row - 1) * RowHeight
Case Else
Row = 0
End Select
EditBox_Move
End sub
'================================================================
'= EditBox移動
'================================================================
Sub EditBox_Move()
'面・カーソル位置確認
txt$ = AKCnv$(Trim$(Str$(PageFlg + 1))) & "面/Col=" & Format$(Col, "##")
txt$ = txt$ & "/Row=" & Format$(Row, "##") & "/Mx=" & Format$(Mx, "####") & "/My=" & Format$(My, "####")
MainForm.SetWindowText txt$
'マウスのセル範囲外クリック時
If Col = 0 Or Row = 0 Then
Edit.ShowWindow 0
Exit Sub
End If
YPos = FrameTop+RowHeight + (Row - 1) * RowHeight
Edit.SetImeMode Val(Item$(Col, 2)) 'IMEモード設定
Edit.SetWindowSize CellWidth(Col), RowHeight - 1 '-1:罫線消去防止
Edit.MoveWindow XPos(Col - 1) - OffSet + FrameLeft + 2, YPos + 2
Edit.ShowWindow -1
Edit.SetLimitText Val(Item$(Col, 1)) + 2 '+2:CrLf$(Enter移動方法による)
Edit.SetWindowText RTrim$(Left$(Dt$(Col, Row), Val(Item$(Col, 1))))
If Val(Item$(Col, 3)) = 1 Then '数値選択の場合
Edit.SetSelText 0, -1
Else '文字選択の場合
Edit.SetSelText Len(RTrim$(Dt$(Col, Row))), Len(RTrim$(Dt$(Col, Row)))
End If
HScroll.SetScrollPos Col
Edit.SetFontName FtName$
Edit.SetFontSize FontSize
Edit.SetFontBold 0
Edit.SETFOCUS
End sub
'================================================================
'= イベント
'================================================================
While 1
WaitEvent
Wend
'================================================================
'= 文字入力
'================================================================
Declare Sub Edit1_Change edecl ()
Sub Edit1_Change()
If PageFlg = 0 Then OffSet = 0 Else OffSet = ColOfst
OldDt$ = Dt$(Col, Row)
Dt$(Col, Row) = Edit.GetWindowText()
EPos = InStr(Dt$(Col, Row), CrLf$)
If EPos <> 0 Then
Dt$(Col, Row) = Mid$(Dt$(Col, Row), 1, EPos - 1) & Mid$(Dt$(Col, Row), EPos + 2)
Edit.SetWindowText Dt$(Col, Row)
If Dt$(Col, Row) = "" Then Dt$(Col, Row) = OldDt$
OldDt$ = Dt$(Col, Row)
Picture.Line(XPos(Col - 1) - OffSet + 2, YPos - FrameTop + 1) - (XPos(Col - 1) - OffSet + CellWidth(Col), YPos - FrameTop + RowHeight - 1), , 15, bf
If Val(Item$(Col,3)) = 1 Then '数値表示
Num$ = Right$("###,###,###,###", Val(Item$(Col, 1)))
If Left$(Num$, 1) = "," Then Num$ = " " + Right$(Num$, Len(Num$) - 1)
Picture.Symbol(XPos(Col - 1) - OffSet + 4, YPos - FrameTop + 4), Format$(Val(Dt$(Col, Row)), Num$), 1, 1
Else '文字表示
Picture.Symbol(XPos(Col - 1) - OffSet + 4, YPos - FrameTop + 4), Dt$(Col, Row), 1, 1
End If
'--------------------
Col = Col + 1 '次列
If PageFlg = 0 Then '★1面
If Col > ColMax1 Then
PageFlg = 1
OffSet = ColOfst
Edit.ShowWindow 0
Grid_Draw
End If
If Col > ColMax Then '最終列の場合
Row = Row + 1 '次行の
Col = 1 '最初の列
If Row > RowMax Then Row = RowMax '最終行の場合
End If
EditBox_Move 'EditBox移動
Else '★2面
If Col < ColMax1 Or Col > ColMax Then
PageFlg = 0
OffSet = 0
Edit.ShowWindow 0
Grid_Draw
End If
If Col > ColMax Then '最終列の場合
Col = 1 '最初の列
Row = Row+1 : If Row > RowMax Then Row = 1 '最終行の場合
End If
EditBox_Move 'EditBox移動
End If
End If
End sub
'================================================================
'= CSVデータ読込
'================================================================
Sub Data_Read()
On Error Goto *Er_Trap
FlNo = FreeFile
Open "TEST.CSV" For Input As #FlNo
i = 0
SetMousePointer 2
Do Until Eof(FlNo)
i = i + 1
Input #FlNo, Dt$(1, i)
Input #FlNo, Dt$(2, i)
Input #FlNo, Dt$(3, i)
Input #FlNo, Dt$(4, i)
Input #FlNo, Dt$(5, i)
Input #FlNo, Dt$(6, i)
Input #FlNo, Dt$(7, i)
Input #FlNo, Dt$(8, i)
Input #FlNo, Dt$(9, i)
Input #FlNo, Dt$(10, i)
Input #FlNo, Dt$(11, i)
Input #FlNo, Dt$(12, i)
Input #FlNo, Dt$(13, i)
Input #FlNo, Dt$(14, i)
Input #FlNo, Dt$(15, i)
Input #FlNo, Dt$(16, i)
Input #FlNo, Dt$(17, i)
Input #FlNo, Dt$(18, i)
Input #FlNo, Dt$(19, i)
Input #FlNo, Dt$(20, i)
Loop
Close #FlNo
DataMax = i
SetMousePointer 0
Exit Sub
*Er_Trap
SetMousePointer 0
Close #FlNo
A% = MessageBox(GetWindowText, "読込に失敗しました!『TEST.CSV』が用意されていないか、データ形式が違います!(i=" & Trim$(Str$(i)) & ")", 0, 0)
Resume *Er_Return
*Er_Return
On Error Goto 0
End sub
'================================================================
'= CSVデータ保存(DataMax固定)
'================================================================
Declare Sub Button1_ON edecl ()
Sub Button1_ON()
FlNo = freefile
On Error Goto *Er_Trap
If DataMax = 0 Then A% = MessageBox(GetWindowText, "保存するデータがありません!", 0, 2) : Exit Sub
Open "TEST.CSV" For Create As #FlNo
SetMousePointer 2
For i = 1 To DataMax
ZD$ = ""
ZD$ = ZD$ & RTrim$(Dt$(1, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(2, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(3, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(4, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(5, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(6, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(7, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(8, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(9, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(10, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(11, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(12, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(13, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(14, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(15, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(16, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(17, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(18, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(19, i)) & ","
ZD$ = ZD$ & RTrim$(Dt$(20, i))
Print #FlNo,ZD$
Next
Close #FlNo
SetMousePointer 0
A% = MessageBox(GetWindowText, "CSV型式で保存しました!", 0, 2)
Exit Sub
*Er_Trap
SetMousePointer 0
Close #FlNo
A% = MessageBox(GetWindowText, "保存に失敗しました!(Erl=" & Str$(Erl) & "/Err=" & Str$(Err) & "/i=" & Trim$(Str$(i)) & ")", 0, 2)
Resume *Er_Return
*Er_Return
On Error Goto 0
End sub