-
データファイルの書き込み、読み込みの処理を行う場合、 その処理を行うそれぞれの場所で PUT命令 、 GET命令 を 行うのも冗長なので、通常は関数化してそれをコールします。
今回テストデータファイルとして以下の2個のフィールドを持つファイルを想定します。
・第1フィールド:コードデータ(16バイト)
・第2フィールド:数量データ(12バイト)
FIELD命令 は以下の様になります。
'フィールドサイズを定義 CONST COL.CD% = 16 'コード CONST COL.NUM% = 12 '数量 'フィールド変数 PRIVATE REC.CD$, REC.NUM$ 'フィールド定義 FIELD #1, COL.CD% AS REC.CD$, COL.NUM% AS REC.NUM$
フィールドサイズをわざわざCONST命令で定義していますが、この後でこれを有効に使います。 フィールドサイズをどこかで定義しておけば、リテラルで FIELD命令 に記述するよりは ソースがわかりやすと思います。
■書き込み関数についてデータファイルに書き込む関数を以下の様に定義します。
Const GcTEST.DAT$ = "TEST.DAT" '--------------------------------------- 'データ書込 '--------------------------------------- 'Function MfPutData%(Byval pstrCD$, Byval plngNum&, Byval plngRecNo&) '引 数: ' pstrCD$ :コード ' pdblVal$ :数量 ' plngRecNo& :レコードNO(0:レコード追加) '戻り値: ' MfPutData% :書込OK:GcTrue%, NG:GcFalse% '--------------------------------------- Function MfPutData%(Byval pstrCD$, Byval plngNum&, Byval plngRecNo&) 'エラー処理宣言 On Error Goto MfPutData.ErrProc 'フィールドサイズ Const COL.CD% = 16 Const COL.NUM% = 12 '戻り値の初期化 MfPutData% = GcFalse% PRIVATE FILENO%, REC.CD$, REC.NUM$ FILENO% = 0 'TEST.DATファイルを、ファイル番号#1としてオープンします FILENO% = 1 OPEN GcTEST.DAT$ AS FILENO% RECORD 2147483647 FIELD #FILENO%, COL.CD% AS REC.CD$, COL.NUM% AS REC.NUM$ 'フィールドへデータ設定 REC.CD$ = LEFT$(pstrCD$ + GfSpc$(COL.CD%), COL.CD%) '既定の桁数分スペースを付加 REC.NUM$ = RIGHT$(GfSpc$(COL.NUM%) + STR$(plngNum&), COL.NUM%) '既定の桁数分スペースを付加 If plngRecNo& = 0 Then 'レコードNOが0の場合,レコードの最後尾に追加 PUT FILENO% Else 'レコードNOが指定された場合,レコードの上書 PUT FILENO%, plngRecNo& Endif '正常を返す MfPutData% = GcTrue% MfPutData.Return '関数戻り If FILENO% > 0 Then Close FILENO% Endif On Error Goto 0 Exit Function '----- 'エラー処理 '----- MfPutData.ErrProc Resume MfPutData.Return End Function
フィールド変数に値を設定するところで、 コードデータは右側に空白を付加してサイズ分のみ設定しています。 また、数値は文字列化後、左側にに空白を付加してサイズ分のみ設定しています。
レコード番号の指定が0の場合は、ファイルの最後尾に追加書込みし、 番号が呈されている場合はその番号で上書きします。
■読み込み関数についてデータファイルに書き込む関数を以下の様に定義します。
'--------------------------------------- 'データ読込 '--------------------------------------- 'Function MfGetData%(Byref pstrCD$, Byref plngNum&, Byval plngRecNo&) '引 数: ' pstrCD$ :コード ' pdblVal$ :数量 ' plngRecNo& :レコードNO '戻り値: ' MfGetData% :読込OK:GcTrue%, NG:GcFalse% '--------------------------------------- Function MfGetData%(Byref pstrCD$, Byref plngNum&, Byval plngRecNo&) 'エラー処理宣言 On Error Goto MfGetData.ErrProc 'フィールドサイズ ' Const COL.CD% = 10 '上の関数[MfPutData%]で定義済み ' Const COL.NUM% = 26 '戻り値の初期化 MfGetData% = GcFalse% PRIVATE FILENO%, REC.CD$, REC.NUM$ FILENO% = 0 'TEST.DATファイルを、ファイル番号#1としてオープンします FILENO% = 1 OPEN GcTEST.DAT$ AS FILENO% RECORD 2147483647 FIELD #FILENO%, COL.CD% AS REC.CD$, COL.NUM% AS REC.NUM$ '読込 GET FILENO%, plngRecNo& '値を返す pstrCD$ = GfTrim$(REC.CD$) 'コード plngNum& = VAL(GfTrim$(REC.NUM$)) '数量 '正常を返す MfGetData% = GcTrue% MfGetData.Return '関数戻り If FILENO% > 0 Then Close FILENO% Endif On Error Goto 0 Exit Function '----- 'エラー処理 '----- MfGetData.ErrProc Resume MfGetData.Return End Function
フィールド変数から値を返す変数に設定するところで、 GfTrim$ ユーザ関数で前後の空白を省いています。
レコード書込関数も読込関数もエラー処理では何もしていませんが、 エラー内容等を表示することも必要ではと思いますので、 実際のシステムで利用される方はご自身で追加してみて下さい。
尚、これらの関数を利用してテストしてみます。以下のソースにテスト処理を記述します。
SCREEN 1 '漢字モード LOCATE , , 2 'カーソルをブロック表示 '最初は書き込み処理の連続 PRIVATE W% W% = MfPutData%("CD0001", 100, 0) W% = MfPutData%("CD0002", 102, 0) W% = MfPutData%("CD0101", 201, 0) W% = MfPutData%("CD0201", 202, 0) W% = MfPutData%("CD1001", 500, 0) PRIVATE CD$, NUM&, REC% REC% = 1 W% = GcTrue% '読み込み処理をレコード番号1から順次行う WHILE W% = GcTrue% W% = MfGetData%(CD$, NUM&, REC%) IF W% = GcTrue% THEN PRINT CD$ + ":" + STR$(NUM&) END IF REC% = REC% + 1 WEND WAIT 0, &h01 'キー入力待ち END
このソースの実行結果は以下の図の様になります。
MfGetData%関数のコールをレコード番号を1から順次カウントアップして与えています。 実際のレコードが無くなった時点で戻り値としてGcFalse%が返ってくるので、 その時にWHILEループが終わります。
=====
2016/04/02:の時の情報
PR -
ハンディスキャナのプログラムとして当然データを入力するわけですが、 何処に格納するかと言えば、やはりファイルとしてハンディスキャナの内部に書き込むことになります。
最近私が作成したシステムでは、パソコンとのデータは全てデータファイル(テキストファイル)で やり取りを行うことにしました。 出庫処理などでは、作成された指示データをパソコンからダウンロードし、 そのデータに従って出庫の作業を行います。 また、入庫処理では検品チェックを行い、ハンディに入庫処理データを登録します。 入庫処理では作業が終わった時点で、パソコンにアップロードし 後処理をパソコン側で行う様にしました。
パソコンとハンディターミナルを切り離して作業ができるので 既存のシステムにハンディターミナルのシステムを付加する場合には有効だと思います。
ハンディターミナルにはLAN接続できるものもありますので、 直接データベースにアクセスして処理を行うこともできますが、 今回は見送りました。
ファイルの操作は昔のBASICと同じように OPEN命令 でファイル番号を指定して オープン処理を行います。データの読み書きは GET/PUT命令 で必ずレコード単位で行います。 処理後は CLOSE命令 でファイルをクローズします。
ファイルの格納先は内部Flashメモリと外部のmicroSD カードがあります。 それぞれの制約は以下の通りです。
仕様項目 内部メモリ(Flash) 外部メモリ(microSD カード) 最大ファイル数 420個 FAT32準拠 フォルダ作成 不可 可能 ファイル名の使用可能文字 英数字のみ
英字は,大文字/小文字の区別無英数字,文字,スペース,ピリオドと
22種類の特殊文字ファイル名の長さ制限 ファイル名:1~8文字
拡張子:1~3文字
(ファイル名と拡張子をピリオドで繋ぐ
但し、拡張子が無い場合はピリオドは要らない)255文字
(ドライブ名およびフォルダ名を含めた場合は、259文字)ドライブ名 Aドライブ
BドライブDドライブ
データファイルのレコード、フィールドの制約は以下の通りです。
項目 制約内容 最大レコード件数 2,147,483,647(2G)※BHT搭載メモリサイズに依存 最大レコード長(バイト) 65,535 フィールド変数サイズ(文字) 8192 フィールド個数(個) 254
■レコードについて
レコードとはデータファイルを読み書きする時の基本単位で、データ1件分のことです。 レコードは FIELD命令 でフォーマットを定義します。 1レコードの最大長は、各フィールドのサイズの合計です。
■フィールド定義について
FIELD命令 の定義は以下の様になっています。
FIELD [#]<ファイル番号>,<フィールド幅> AS <フィールド変数> [,<フィールド幅> AS <フィールド変数>・・・] <ファイル番号>:1~16の値を返す数値式 (OPEN命令で指定したファイル番号を指定) <フィールド幅>:1~8192 の値を返す数値式を指定 (対応するフィールド変数の大きさ(バイト数)を指定) <フィールド変数>:文字型単純変数
(FIELD命令の前に宣言されている変数を指定)
■OPEN命令について
説明が前後しますが OPEN命令 の定義は以下の様になっています。
OPEN <ファイル名> AS[#]<ファイル番号>[RECORD <ファイル長>]
<ファイル名>:"[ドライブ名:]ファイル名[<S>]"の書式の文字列式 ("ファイル名"は"ファイル名称"+"."+"拡張子") (<S>はフィールド末尾のスペース除去オプション ドライブ名に"D:\"指定のみ) <ファイル番号>:1~16の値を返す数値式 <ファイル長>:1~2147483647の数値型定数 (ファイルに登録できる最大レコード数を指定:未指定は1000個)
・同時にオープンできるのはバーコード、通信デバイスと合わせて16個までです。
・ファイル長は新規にファイルをオープンする時にしか機能せず、 既存のファイルをオープンする時には無視されます。
■CLOSE命令について
CLOSE命令 の定義は以下の様になっています。
CLOSE[[#]<ファイル番号>[,[#]<ファイル番号>...]] <ファイル番号>:1~16の値を返す数値式
・ファイル番号を省略するとオープン済みのファイルが全てクローズされます。
・クローズすればファイル番号は再利用可能です。
・オープンされていないファイル番号を指定しても、エラーは発生しません。
■PUT命令について
OPEN命令 、CLOSE命令 はファイル操作の最初と最後の処理で、 実際にデータを書き込む命令としての PUT命令 があります。
PUT [#]<ファイル番号>[,<レコード番号>] <ファイル番号>:1~16の値を返す数値式 (OPEN命令で指定したファイル番号を指定) <レコード番号>:1~2147483647の値を返す数値式 (最小値:1、最大値:OPEN命令で指定した最大登録レコード数)
・レコードへの書込みは FIELD命令 で定義された、 フィールド変数を介して行われます。(PUTする前にフィールド変数へ値を設定します)
・レコード番号を省略すると、現在の最大レコード番号+1の位置にレコードが書き込まれます。
・レコード番号は順番通りに指定しなくても書込みはOKで、 飛ばしたレコード番号の位置のレコードには空白が設定されます。
・レコードはテキストデータ(ASCII文字列)しか扱えないので、 数値データは STR$関数 で文字列に変換してからフィールド変数に設定します。
■GET命令について
GET命令 の定義は以下の様になっています。
GET [#]<ファイル番号>[,<レコード番号>] <ファイル番号>:1~16の値を返す数値式 (OPEN命令で指定したファイル番号を指定) <レコード番号>:1~2147483647の値を返す数値式 (最小値:1、最大値:OPEN命令で指定した最大登録レコード数)
・ファイル番号で指定されたデータファイルから、 レコード番号で指定されたレコードを読み込み、フィールド変数にデータを設定します。
・レコードが1件もないと実行時エラーが発生します。
・レコード番号を省略したときは、1つ前のGET命令で読んだレコード番号+1の番号のレコードが読まれます。
(最終レコードの次をGETすると実行時エラーが発生します。)
・レコード番号が最大レコード数より大きいと実行時エラーが発生します。
■各命令の順番について
データファイルを扱う命令は基本的に以下の様な順番で行います。
(1)フィールド変数の宣言
(2) OPEN命令
(3) FIELD命令
(4) PUT命令
(5) GET命令
(6) CLOSE命令
実際はこの順番でなくても良くて、PUT命令しかなかったり、 GET命令だけの処理かもしれません。
以下の簡単なソースで例を示します。
SCREEN 1 '漢字モード LOCATE , , 2 'カーソルをブロック表示 'フィールド変数定義 PRIVATE REC1$, REC2$, REC3$, REC4$ 'ファイル番号変数 PRIVATE FILENO% 'ファイル番号#1としてオープン FILENO% = 1 OPEN "TEST.DAT" AS FILENO% RECORD 2147483647 FIELD #FILENO%, 2 AS REC1$, 4 AS REC2$, 8 AS REC3$, 16 AS REC4$ 'フィールド変数に値設定 REC1$ = "AB" REC2$ = "12345" '文字列多目 REC3$ = "CDEFG" '文字列少な目 REC4$ = "0123456789012345" 'レコード書込み(先頭レコード) PUT #FILENO%, 1 'フィールド変数クリア REC1$ = "" REC2$ = "" REC3$ = "" REC4$ = "" 'レコード読込み GET #FILENO%, 1 'ファイルクローズ CLOSE #FILENO% 'フィールド変数の表示 PRINT "1:[" + REC1$ + "]" PRINT "2:[" + REC2$ + "]" PRINT "3:[" + REC3$ + "]" PRINT "4:[" + REC4$ + "]" WAIT 0, &h01 'キー入力待ち END
このソースの実行結果は以下の図の様になります。
フィールド変数REC2$には文字列を多目に設定していますが、 あふれた分は無視されていることが分かります。
また、REC3$には文字列を少な目に設定しましたが、 GETした結果は同じ文字列が返ってきました。 データファイルの中身には足りない分には空白が入っているようですが、 実際に読みだすと削除されてくるようです。
もし空白も読み出したいのであれば、REC3$の設定で後ろの方に空白文字列を付加する必要があります。
=====
2016/04/02:の時の情報
-
今までは何となく OUT命令 や WAIT命令 を使ってきましたが、 ここで関連するI/Oポートの説明を行いたいと思います。 I/Oポートとは入力・出力ポートの略称で、ハンディのCPUから見て外部装置に該当するキーボード、 LEDランプ、ブザーなどを制御するためのポート(外部メモリの様なもの)です。 I/Oポートは制御対象毎に別々のアドレスが割り当てられていて、 それへの入力命令が INP関数 で、出力命令が OUTステートメント です。 また、I/Oポートの状態が指定状態になるまでプログラムを止めておく WAITステートメント があります。
以下に私がプログラムで使用したポートについて一覧を記します。 ここに上げた以外のポートは各装置のマニアルを参照して下さい。
ポートNO
(HEX)bit 制御対象 R/W データ 初期値 .pnEvent
(0000)0 キーボードバッファ R
- 0 データ無 - .pvEvKeyOn 1 データ有 1 バーコードバッファ - 0 データ無 - .pvEvBarOn 1 データ有 2 トリガスイッチ - 0 OFF - .pvEvTrgOn 1 ON 3 受信バッファ - 0 データ無 - .pvEvtCmOn 1 データ有 4 TIMEA関数 - 0 関数の値が0以外 - .pvEvTma0 1 関数の値が0 5 TIMEB関数 - 0 関数の値が0以外 - .pvEvTmb0 1 関数の値が0 6 TIMEC関数 - 0 関数の値が0以外 - .pvEvTmc0 1 関数の値が0 7 CS(CTS)信号 - 0 常に0を返す - .pvEvCsOn 1 - .pnLEDCtrl
(0001)0 表示LED(赤) W
- 0 消灯 0 .pvLEDRed 1 点灯 1 表示LED(緑) - 0 消灯 0 .pvLEDGrn 1 点灯 2 表示LED(青) - 0 消灯 0 .pvLEDBle 1 点灯 .pnFont
(6080)0 表示フォント R/W
.pvFtStd 0 標準フォント 0 .pvFtSmall 1 小フォント サイズ指定(16,24,30,40) .pnKeyEnt
(60B0)0 キー入力方式 R/W
.pvKyNm 0 数字入力 0 .pvKyAlpNm 1 英数字入力 .pnKeyMd
(60B1)0 キー入力状態 R/W
.pvKMNm 0 数字 0 .pvKMAlp 1 英字
例として先ずは、WAIT命令について説明します。
WAIT <ポート番号> , <AND パターン>[,XOR パターン]
<ポート番号>:入力ポート番号を指定
<AND パターン>:チェックしたいビットを1 にして、AND パターンに設定
ポート番号で指定された入力ポートの内容を読込し、 AND パターンとXOR パターンで指定された値になるまで、 ユーザプログラムをこの命令で待つ様にします。
指定されたパターンになるまで命令が終わらないので、 指定値が間違っていると、命令から帰って来なくなり、 プログラムが止まってしまいますので、注意して下さい。
以下のソースがWAIT命令の使用例の関数なのですが、 ポート(0000)の0ビット目が1になるまで待っています。 WAIT命令を抜けてきた時点で、キーボードバッファにキー入力が在ることになるので キーデータを1文字取得しています。
Function GfGetKey$ Wait 0, &h01 'キー入力待ち GfGetKey$ =Input$(1) '入力されたキーを取得して戻す。 End Function
次は、INP関数について説明します。
INP(<ポート番号>)
<ポート番号>:入力ポート番号を指定
INP関数が返す値は整数型になります。 I/Oポートのデータは1バイトなので、整数型では最大でも255となります。
WAIT命令のところの関数の例をINP関数で置き換えると以下の様になります。
(ちょっと冗長すぎますね)
Function GfGetKey2$ PRIVATE W% W% = INP(0) WHILE (W% AND 1) = 0 W% = INP(0) WEND GfGetKey2$ =Input$(1) '入力されたキーを取得して戻す。 End Function
次は、OUT命令について説明します。
OUT <ポート番号>,<データ>
<ポート番号>:入力ポート番号を指定 <データ> :ポートに出力するバイトデータ(0~255)
I/Oポートに割り振られていないポート番号を指定すると無視されます。 また、使用されているポート番号でも意味の無いBIT位置にデータを 設定しても無視されます。
'数字入力方式に設定 OUT .pnKeyEnt, .pvKyAlpNm '英数字入力 OUT .pnKeyMd, .pvKMNm '数字 'フォントサイズ24ドット指定 OUT .pnFont , 24
最後にTIMER命令について説明します。書式1:(タイマ値を参照するとき)タイマは値を設定されてからカウントダウンが始まり、カウント値が0になった時点で動きを止めます。 例えばある時間の待ちを作る場合に、カウンタに値を設定し、カウンタを読込をループで行い その値が0になるのを待ちます。
W% = TIMEA
W% = TIMEB
W% = TIMEC
(W%は宣言済みとする)
書式2:(タイマ値を設定するとき)
TIMEA = <カウント値>
TIMEB = <カウント値>
TIMEC = <カウント値>
<カウント値>:指定可能範囲は0~32767、単位は100ms
ソースの例としては以下の様な感じです。
TIMEA = 100 '10秒設定 'TIMEAが0になったらループ終了 WHILE TIMEA > 0 WEND
=====
2016/04/02:の時の情報
-
文字列を扱うユーザ定義関数として使えそうなものを作成してみました。
関数定義 引数 戻り値 指定された文字列を分離文字列で分解
Sub GsSplit$(byval pstrSrc$, Byval pstrSplit$, Byref parr$())
pstrSrc$:分離元文字列
pstrSplit$:分離文字列
parr$:分解先配列指定文字で埋めて、右詰又は左詰で返す
'Function GfPadd$(pintMode%, pstrBuf$, pintLen%, pstrPadChar$)[255]
pintMode%:左詰(GcTrue%),右詰(GcFalse%)
pstrBuf$:文字列
pintLen%:最終文字列長(最大255)
pstrPadChar$:埋める文字GfPadd$:結果文字列
'--------------------------------------- '指定された文字列を分離文字列で分解する '--------------------------------------- 'Sub GsSplit$(byval pstrSrc$, Byval pstrSplit$, Byref parr$()) '引 数: ' pstrSrc$ :分離元文字列 ' pstrSplit$ :分離文字列 ' parr$ :分解先配列 '--------------------------------------- Sub GsSplit$(byval pstrSrc$, Byval pstrSplit$, Byref parr$()) 'エラー処理宣言 On Error Goto GsSplit.ErrProc Private i%: i% = 1 Private pos%: pos% = 1 Private posLast%: posLast% = 1 '区切り文字列を探す pos% = INSTR(posLast%, pstrSrc$, pstrSplit$) While pos% > 0 '前回位置から、区切り文字列の前までを退避 parr$(i%) = MID$(pstrSrc$, posLast%, pos% - posLast%) '指標++ i% = i% + 1 '前回位置を区切り文字列の次にする posLast% = pos% + LEN(pstrSplit$) '区切り文字列を探す pos% = INSTR(posLast%, pstrSrc$, pstrSplit$) Wend '最後の文字列 parr$(i%) = MID$(pstrSrc$, posLast%) GsSplit.Return '関数戻り On Error Goto 0 Exit Sub '----- 'エラー処理 '----- GsSplit.ErrProc Resume GsSplit.Return End Sub '--------------------------------------- '指定文字で埋めて、右詰又は左詰で返す '--------------------------------------- 'Function GfPadd$(pintMode%, pstrBuf$, pintLen%, pstrPadChar$)[255] '引 数: ' pintMode% :左詰(GcTrue%)か右詰(GcFalse%)か ' pstrBuf$ :文字列 ' pintLen% :最終文字列長(最大255) ' pstrPadChar$:埋める文字 '戻り値: ' GfPadd$ :結果文字列 '--------------------------------------- Function GfPadd$(pintMode%, pstrBuf$, pintLen%, pstrPadChar$)[255] 'エラー処理宣言 On Error Goto GfPadd.ErrProc Private intPad%, strTmp$[255] intPad% = pintLen% - Len(pstrBuf$) If intPad% > 0 Then strTmp$ = GfString$(pstrPadChar$, intPad%) If pintMode% = GcTrue% Then '左詰 GfPadd$ = pstrBuf$ + strTmp$ Else '右詰 GfPadd$ = strTmp$ + pstrBuf$ End If Else 'そのまま返す GfPadd$ = pstrBuf$ End If GfPadd.Return '関数戻り On Error Goto 0 Exit Function '----- 'エラー処理 '----- GfPadd.ErrProc GfPadd$ = "" Resume GfPadd.Return End Function
これらの関数の実行ソースは以下の様になります。
'----- '実行はここから処理 '----- Main SCREEN 1 '漢字モード LOCATE , , 2 'カーソルをブロック表示 PRINT "***GfPadd$" PRIVATE W$, W2$ W$ = GfPadd$(GcTrue%, "123", 5, " ") PRINT "[" + W$ + "]" W$ = GfPadd$(GcFalse%, "123", 5, "0") PRINT "[" + W$ + "]" PRINT "***GsSplit$" PRIVATE ARR$(10) CALL GsSplit$("123,AAA,!!!!!!!", ",", ARR$) FOR I% = 1 TO 3 PRINT "ARR$("; I%; PRINT ")="; ARR$(I%) NEXT WAIT 0, &h01 'キー入力待ち END
これを実行すると以下の様な表示になります。
=====
2016/04/02:の時の情報
-
文字列を扱うユーザ定義関数としてよくある感じのものを作成してみました。
関数定義 引数 戻り値 半角空白文字列生成
Function GfSpc$(byval pintCnt%)[128]
pintCnt%:文字数を指定 GfSpc$:空白文字列 右側半角空白削除
Function GfRTrim$(pstrValue$)[255]
pstrValue$:対象文字列 GfRTrim$:結果文字列 左側半角空白削除
Function GfLTrim$(pstrValue$)[255]
pstrValue$:対象文字列 GfRTrim$:結果文字列 前後の半角空白削除
Function GfTrim$(pstrValue$)[255]
pstrValue$:対象文字列 GfTrim$:結果文字列 文字列繰り返し
Function GfString$(pintSize%, pstrChr$)[255]
pstrChr$:対象文字
pintSize%:文字数(最大1~255)GfString$:結果文字列
エラー処理を各関数に入れましたが、必要ないかもしれません。 また、引数の文字列の長さチェックは行っていませんので、必要ならば追加して下さい。
'--------------------------------------- '定数宣言:共通⇒(これは別ファイルにすべき) '--------------------------------------- Global GcTrue% : GcTrue% = -1 Global GcFalse% : GcFalse% = 0 '--------------------------------------- '半角空白文字列生成 '--------------------------------------- 'Function GfSpc$(byval pintCnt%)[128] '引 数: ' pintCnt% :文字数を指定 '戻り値: ' GfSpc$ :空白文字列 '--------------------------------------- Function GfSpc$(byval pintCnt%)[128] Private strSpc$[128]: strSpc$ = "" Private i% If pintCnt% > 128 Then pintCnt% = 128 Endif For i%=1 To pintCnt% strSpc$ = strSpc$ + " " Next GfSpc$ = strSpc$ End Function '--------------------------------------- '右側半角空白削除(Rtrim) '--------------------------------------- 'Function GfRTrim$(pstrValue$)[255] '引 数: ' pstrValue$ :対象文字列 '戻り値: ' GfRTrim$ :結果文字列 '--------------------------------------- Function GfRTrim$(pstrValue$)[255] 'エラー処理宣言 On Error Goto GfRTrim.ErrProc Private intCnt%, intIdx% '最後尾から空白以外の文字を探す intCnt% = 0 For intIdx% = Len(pstrValue$) To 1 Step -1 If Mid$(pstrValue$, intIdx%, 1) <> " " Then intCnt% = intIdx% intIdx% = 1 'ループを止める Endif Next '右側全ての空白を排除 GfRTrim$ = Left$(pstrValue$, intCnt%) GfRTrim.Return '関数戻り On Error Goto 0 Exit Function '----- 'エラー処理 '----- GfRTrim.ErrProc GfRTrim$ = "" Resume GfRTrim.Return End Function '--------------------------------------- '左側半角空白削除(Rtrim) '--------------------------------------- 'Function GfLTrim$(pstrValue$)[255] '引 数: ' pstrValue$ :対象文字列 '戻り値: ' GfLTrim$ :結果文字列 '--------------------------------------- Function GfLTrim$(pstrValue$)[255] 'エラー処理宣言 On Error Goto GfLTrim.ErrProc Private intCnt% strTemp$ = "" '--- 左端からスペースではない文字を探していく For intCnt% = 1 To Len(pstrValue$) If Mid$(pstrValue$, intCnt%, 1) <> " " Then '空白では無い文字以降の文字列を戻す GfLTrim$ = Mid$(pstrValue$, intCnt%) intCnt% = Len(pstrValue$) End If Next intCnt% GfLTrim.Return '関数戻り On Error Goto 0 Exit Function '----- 'エラー処理 '----- GfLTrim.ErrProc GfLTrim$ = "" Resume GfLTrim.Return End Function '--------------------------------------- '前後の半角空白削除(Trim) '--------------------------------------- 'Function GfTrim$(pstrValue$)[255] '引 数: ' pstrValue$ :対象文字列 '戻り値: ' GfTrim$ :結果文字列 '--------------------------------------- Function GfTrim$(pstrValue$)[255] Private strWK$[255] strWK$ = GfLTrim$(pstrValue$) '左側空白削除 GfTrim$ = GfRTrim$(strWK$) '右側空白削除 End Function '--------------------------------------- '文字列繰り返し '--------------------------------------- 'Function GfString$(pintSize%, pstrChr$)[255] '引 数: ' pstrChr$ :対象文字 ' pintSize% :文字数(最大1~255) '戻り値: ' GfString$ :結果文字列 '--------------------------------------- Function GfString$(pstrChr$, pintSize%)[255] 'エラー処理宣言 On Error Goto GfString.ErrProc Private intCnt%, strTemp$[255] strTemp$ = "" '文字数分の文字列連結 For intCnt% = 1 To pintSize% strTemp$ = strTemp$ + pstrChr$ Next intCnt% GfString$ = strTemp$ GfString.Return '関数戻り On Error Goto 0 Exit Function '----- 'エラー処理 '----- GfString.ErrProc GfString$ = "" Resume GfString.Return End Function
これらの関数の実行ソースは以下の様になります。Sub DispData(Byval strP1$, Byval strP2$) PRINT "[" + strP1$ + "]=>[" + strP2$ + "]" End Sub '----- '実行はここから処理 '----- Main ' PRIVATE Num$, nRet%, intLoop% SCREEN 1 '漢字モード LOCATE , , 2 'カーソルをブロック表示 PRINT "***GfRTrim$" PRIVATE W$, W2$ W$ = "1234 " W2$ = GfRTrim$(W$) CALL DispData(W$, W2$) W$ = "12 34 " W2$ = GfRTrim$(W$) CALL DispData(W$, W2$) W$ = "12 34 A" W2$ = GfRTrim$(W$) CALL DispData(W$, W2$) PRINT "***GfLTrim$" W$ = " 1234" W2$ = GfLTrim$(W$) CALL DispData(W$, W2$) W$ = " 12 34 " W2$ = GfLTrim$(W$) CALL DispData(W$, W2$) W$ = " 1234 A" W2$ = GfLTrim$(W$) CALL DispData(W$, W2$) PRINT "***GfTrim$" W$ = " 1234 " W2$ = GfTrim$(W$) CALL DispData(W$, W2$) W$ = " 12 34 " W2$ = GfTrim$(W$) CALL DispData(W$, W2$) PRINT "***GfString$" W$ = GfString$("@", 10) PRINT W$; WAIT 0, &h01 'キー入力待ち END
これを実行すると以下の様な表示になります。
=====
2016/04/02:の時の情報