[前の記事]« NSLOOKUP,TELNETなどネットワーク関係のコマンドが使えない
[次の記事]標準出力の内容をコンソールとファイル双方に出したい »

関連オンラインソフト配布サイト:
Vector>ダウンロード(top) |>MS-DOSまたは汎用 | >WindowsVista/XP/2000/NT

▲カテゴリー「DATE,TIME…日付、時刻の取得/利用」索引へ

Win2000:入力された日付の文字列をチェックしたい


213) 日付入力チェックについて こう 2003/05/03(土) 01:39


久しぶりです「こう」といいます。
前回の質問「ファイルの自動仕分け」についてでは
ふぇむさんに色々とアドバイスをいただき
ありがとうございました。

さて、現在 WIN2000にて
以下のような仕様のバッチスクリプトを検討中ですなのですが
どうしたも実現できない部分があるため質問させていただきました。

①運用者に年月の指定で日付を入力してもらう
②その日付のディレクトリを作成する。
③MO格納されているファイルを全て②で作成したディレクトリへコピーする。

このバッチスクリプトは基本的には月次で起動してもらうが、数ヶ月間データMOを溜めてから
1日でファイルコピーをすることもあるため
システム日付を使用するのではなく運用者に、対象となる日付を入力してもらうことにしました。

①は
set /P ANS="日付を入力してください(YYYYMM)->"
でユーザより日付をYYYYMMのフォーマットで入力してもらおうと考えています。
②のディレクトリを作成する前に最低限の入力チェックをしたいので
(1)日付としての妥当性のチェックができれば理想
(2)入力した値が6桁であるかチェックする。
(3)入力した値が全て数字であることをチェックする。
(4)月の部分(5文字目~6文字目)が01~12の範囲かチェックする。

(1)のチェックでは、IS_DATEのようなコマンドか関数あれば良いのですが
ないとおもわれたため(勝手におもっています)
最低限(2)~(4)のチェックができれば良いと考えております。
(4)はIF文でなんとかなるとおもうのですが(2)(3)のチェック方法がわかりません

前置きが長くなってしまいましたが、
・環境変数に設定されている値の桁数を取得する方法
・環境変数に設定されている値が数字であるかの判定方法
がわからないのです。

どなたか知っていたら、アドバイスをお願いしたいとおもい質問させていただきました。
どうか宜しくお願いいたします。


217) Re:日付入力チェックについて じゃく 2003/05/04(日) 17:39


こうさん、こんにちは

>①は
>set /P ANS="日付を入力してください(YYYYMM)->"
>でユーザより日付をYYYYMMのフォーマットで入力してもらおうと考えています。
>②のディレクトリを作成する前に最低限の入力チェックをしたいので
>(1)日付としての妥当性のチェックができれば理想
>(2)入力した値が6桁であるかチェックする。
>(3)入力した値が全て数字であることをチェックする。
>(4)月の部分(5文字目~6文字目)が01~12の範囲かチェックする。

>(1)のチェックでは、IS_DATEのようなコマンドか関数あれば良いのですが
>ないとおもわれたため(勝手におもっています)
>最低限(2)~(4)のチェックができれば良いと考えております。

もう少し整理して、以下の2つでよいのでは?
(1)入力文字の1-4桁目を数値として見て、2000以上2100以下である
(2)入力文字の5-6桁目を数値として見て、1以上12以下である

その上で、環境変数の任意の桁を取り出す方法は set /?
環境変数の値を数値として見て比較するのは if /?
の2つのヘルプで確認できます。

>>C:\>set /?
>>cmd.exe 環境変数を表示、設定、または削除します。
>>
>>SET [変数名=[文字列]]
>>
>> 変数名 環境変数名を指定します。
>> 文字列 変数に割り当てる文字列を指定します。
>>
>>現在の環境変数を表示するには、パラメータを指定せずに SET と入力してください。
(途中略)

>>また、展開の副文字列を指定することもできます。
>>
>> %PATH:~10,5%
>>
>>は、PATH 環境変数を展開し、展開結果の 11 番目 (オフセット 10) の文字
>>から始まる 5 文字だけを使います。長さが指定されなかった場合は、変数の
>>値の残りの長さを既定値とします。オフセットまたは長さのどちらかが負の値
>>の場合、環境変数の値の長さに指定されたオフセットまたは長さを足してその
>>数を使います。
>>
1-4桁目を ans1 に、5-6桁目を ans2 にいれるには、
set ans1=%ANS:~0,4%
set ans2=%ANS:~4,2%
ですね。
数値の大小比較は if 文の LEQ や GEQ でできます。
詳細な記述が必要でしたら、再度質問してみてください。




220) Re2:日付入力チェックについて こう 2003/05/04(日) 23:19


じゃくさん
ありがとうございます。

>1-4桁目を ans1 に、5-6桁目を ans2 にいれるには、
>set ans1=%ANS:~0,4%
>set ans2=%ANS:~4,2%
>ですね。
>数値の大小比較は if 文の LEQ や GEQ でできます。
>詳細な記述が必要でしたら、再度質問してみてください。

上記の
set ans1=%ANS:~0,4%
set ans2=%ANS:~4,2%
については、理解していました

たとえば
set /P ANS="YYYYMM->"
set ans1=%ANS:~0,4%
set ans2=%ANS:~4,2%
if "%ans1%" GEQ "2001" (
if "%ans1%" LEQ "2100" (
echo OK
)else (
echo NG
)
) else (
echo NG
)

とした場合に数値のみ入力した場合は意図した通りに比較チェックされますが
20A101と入力した場合は(文字が混在)
20A1は2001よりも大きいと判断されてしまい
また、20A1は2100よりも小さいと判断されてしまい OK となります
これは、if文は数値として比較しているのではなく
文字として比較しているのだと推測ができます。
日付チェックではやはり20A1は NG になるようにしたいので
今回の質問をさせていただきました。

ちなみに上記スクリプトで
if文に /I スイッチを付加したり
ダブルクォーテーションでの囲みをはずしたりしましたがだめでした

再度質問となりますが
if文で数値として比較する方法があれば教えていただけないでしょうか
たびたびで申し訳ありません

221) Re3:日付入力チェックについて じゃく 2003/05/05(月) 06:41


こんにちは。

>たとえば
>set /P ANS="YYYYMM->"
>set ans1=%ANS:~0,4%
>set ans2=%ANS:~4,2%
>if "%ans1%" GEQ "2001" (
> if "%ans1%" LEQ "2100" (
> echo OK
> )else (
> echo NG
> )
>) else (
> echo NG
>)

>とした場合に数値のみ入力した場合は意図した通りに比較チェックされますが
>20A101と入力した場合は(文字が混在)
>20A1は2001よりも大きいと判断されてしまい
>また、20A1は2100よりも小さいと判断されてしまい OK となります
>これは、if文は数値として比較しているのではなく
>文字として比較しているのだと推測ができます。
>日付チェックではやはり20A1は NG になるようにしたいので
>今回の質問をさせていただきました。
if 文で文字が入った場合、文字で比較するのですね。
確認を怠っておりました。

>再度質問となりますが
>if文で数値として比較する方法があれば教えていただけないでしょうか
そうすると、考えられる方法は次の2つですね。
(結局こうさんの質問(2)~(4)ですね。スミマセン)

(1) set /a を使用して数値化することで文字を排除する
(2) findstrの正規表現を使用して文字を限定する

(1) は set /a で一旦数値として別の変数にセットした内容と
元の環境変数が同じになるかをチェックするものです。
例えば、
set /a y=1%ans1% -10000
if not "%ans1%"=="%y%" goto err
という風に書くと、有効な4桁の数字でない場合は err に飛ぶ
はずです。ただ、文字列が ans1 に入っているとエラー表示が
表示されますのでその場合は以下のように記述します。
set /a y=1%ans1% -10000 >nul 2>&1
この後に、数値の範囲を比較します。
先頭に"1"をつけるのは、set /a が0で始まる数値を8進数と見なす
からです。

(2) の findstr によるチェックの例は次のようになります。
数値として一致しないとファイルのサイズが0になることを
チェックしています。年は2000から2199まで、月は00から19まで
OKとしていますのでその後範囲チェックが必要と思います。

--------------------------------------------------------
set ans1=%ANS:~0,4%
set ans2=%ANS:~4,2%

echo %ans%> tmp.txt
findstr /r "^2[0-1][0-9][0-9][01][0-9]$" tmp.txt > tmp2.txt
for %%A in ( tmp2.txt ) do set size=%%~zA
if %size%==0 goto Err
echo 引数1 %1
echo 引数2 %ans1% %ans2%

REM 以降にans2の数値の大小比較等を記述

goto end
:Err
echo 引数の指定エラー
:end
del tmp.txt
del tmp2.txt



222) Re4:日付入力チェックについて こう 2003/05/07(水) 00:29


じゃくさん こんにちは。
返事がおそくなり申し訳ありませんでした

>(1) set /a を使用して数値化することで文字を排除する
>(2) findstrの正規表現を使用して文字を限定する

本日、(1)の方法で無事バッチスクリプト完成いたしました。
set /aは理解していましたが
>set /a y=1%ans1% -10000
>if not "%ans1%"=="%y%" goto err
このような使い方があるとは...

わがままな質問に答えていただきありがとうございました。

ちなみに、(2)の方法は、
チェックのためにワークファイルを作成するのは、
後々面倒な部分(作成エラー等)が発生する可能性があると思ったので
(1)の方法で実現させていただきました。


231) Re5:日付入力チェックについて ふぇむ 2003/05/18(日) 10:27


ふぇむと申します。久々にここを開きました。
既に解決済みのようですが、数値チェックの方法について、ふぇむのやりかたをご参考までに紹介いたします。

考え方ですが、set文の文字列置き換え機能を使って、0~9全てを消し去ったあとに何か残っていれば数値のみの文字列ではなかった、という判定です。


:IS_NUMERIC
rem ##
rem ## 数値かどうかを判定
rem ##
rem ## 引数:チェック対象文字列
rem ## 戻り: %RETCODE% に TRUE or FALSE or NULLSTR or SPACESTR
rem ##

rem ## ダミー文字 x を先頭に付加
set __TESTSTR=x%~1

if "%__TESTSTR%" == "x" (
set RETCODE=NULLSTR
goto :eof
)

if "%__TESTSTR: =%" == "x" (
set RETCODE=SPACESTR
goto :eof
)

set __TESTSTR=%__TESTSTR:0=%
set __TESTSTR=%__TESTSTR:1=%
set __TESTSTR=%__TESTSTR:2=%
set __TESTSTR=%__TESTSTR:3=%
set __TESTSTR=%__TESTSTR:4=%
set __TESTSTR=%__TESTSTR:5=%
set __TESTSTR=%__TESTSTR:6=%
set __TESTSTR=%__TESTSTR:7=%
set __TESTSTR=%__TESTSTR:8=%
set __TESTSTR=%__TESTSTR:9=%

if "%__TESTSTR%" == "x" (
set RETCODE=TRUE
) else (
set RETCODE=FALSE
)

goto :eof


こんな感じです。
 
 


カテゴリー「DATE,TIME…日付、時刻の取得/利用」索引へ

 

カテゴリー一覧

FPCU/FPCDIY QUICK LINK online
この上の各ジャンル名をクリックすると、下のウィンドウが切り替わります▼


=リンク集のインデックスはこちら=

資料書籍

About

2003年05月03日 01:41に投稿されたエントリーのページです。

ひとつ前の投稿は「NSLOOKUP,TELNETなどネットワーク関係のコマンドが使えない」です。

次の投稿は「標準出力の内容をコンソールとファイル双方に出したい」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

This site is powered by Six Apart
Movable Type 3.33-ja
このブログについて | 運営:有限会社メディアポート