デスクトップ アプリケーションで特定のフィールドに入力するときに、ユーザーの入力を数値のみ (小数を許可) に制限するにはどうすればよいですか?
〜ロジャー
デスクトップ アプリケーションで特定のフィールドに入力するときに、ユーザーの入力を数値のみ (小数を許可) に制限するにはどうすればよいですか?
〜ロジャー
ベンの答えはすべてのケースを網羅しているわけではないことに注意してください
あなたはそれらすべてを行うことができます
local sExisting
on openfield
put the text of me into sExisting
end openfield
on textChanged
put the selectedText && sExisting && the text of me into msg
if the text of me is a number or me is empty then
put the text of me into sExisting
else
put sExisting into me
end if
end textChanged
注意-無効な文字を入力すると、入力カーソルが行の先頭に移動します。別のことをしたい場合は、('textChanged'の最初のアクションとして)画面をロックし、完了したらロックを解除できます。
アレックス、私はあなたのスクリプトが好きですが、それはすべてのケースをカバーしているわけではありません。負の数を入力したい場合(空のフィールドに「-」記号で始まる場合)は機能しません。以下は修正されたスクリプトです。今回はすべてのケースをカバーすることを願っていますが、許可されていない文字を入力すると選択が失われます(まだ何かを行う必要があります)。
local sExisting, sSelected
on openfield
put the text of me into sExisting
end openfield
on textChanged
--put the selectedText && sExisting && the text of me into msg
put the selectedChunk into sSelected
if the text of me is a number or me is empty or me is "-" then
put the text of me into sExisting
else
put sExisting into me
end if
select sSelected
end textChanged
以前の回答を編集するよりも、これを別の回答として追加する方が簡単で、おそらく優れていることがわかりました。これは Marek の改善を利用して、先頭の "." のケースをもう 1 つ追加します。また、数値が入力された後だけでなく、一般的に先頭と末尾の空白を許可します。
また、追加の文字を入力または貼り付けようとして失敗した後、選択/挿入ポイントを復元します (選択を完全に復元することはできませんが、挿入ポイントは常に前の選択の直後に終了する必要があります.
完全性を高めるために、理解しやすさを確実にトレードオフしていることに注意してください...
最終的な値は有効であるが、介在する状態の 1 つ (1.2e) が有効ではないため、科学的表記 (1.2e34 など) を挿入するケースについては、まだ完全にはカバーしていません。
local sExisting
on openfield
put the text of me into sExisting
end openfield
on textChanged
local tMe, tChunk, tDeltaLength, tWhere
put the selectedChunk of me into tChunk
put word 1 to -1 of the text of me into tMe -- strip leading/trailing spaces
if tMe is a number or tMe = "-" or tMe = "." or tMe is empty then
put the text of me into sExisting
else
-- calculate how many characters were inserted,
-- and move the insertion point back to there
put the number of chars in me - the number of chars in sExisting into tDeltaLength
put sExisting into me
put word 4 of tChunk - tDeltaLength into tWhere
put tWhere into word 4 of tChunk
put tWhere into word 2 of tChunk
do ("select after " & tChunk & " of me")
end if
end textChanged
アレックス、
次の場合、スクリプトは正しく機能しません。
これを確認してください:
local sExisting, sSelected, sSelected1
on openField
put the text of me into sExisting
end openField
on selectionChanged
put the selectedChunk into sSelected1
put "sSelected1: " & sSelected1 into line 1 of msg
end selectionChanged
on arrowKey
send "selectionChanged" to me in 0
pass arrowKey
end arrowKey
on textChanged
local tMinus, tDot
put empty into tDot
put empty into tMinus
--
put the selectedChunk into sSelected
put "sSelected: " & sSelected into line 2 of msg
--
get matchChunk (me, "^(-?)[0-9]*(\.)?([0-9]*)$", tMinus, tMinus, tDot, tDot)
if it then
switch tDot
case 2
if tMinus = 1 then put "-0." & char 3 to -1 of me into me
put (word 2 of sSelected) + 1 into word 2 of sSelected
put (word 4 of sSelected) + 1 into word 4 of sSelected
break
case 1
put "0." & char 2 to -1 of me into me
put (word 2 of sSelected) + 1 into word 2 of sSelected
put (word 4 of sSelected) + 1 into word 4 of sSelected
break
default
end switch
send "selectionChanged" to me in 0
put me into sExisting
else
if not (me is empty) then
put sExisting into me
put sSelected1 into sSelected
end if
end if
select sSelected
end textChanged
おそらく完璧ではありませんが、貼り付け後の選択と文字入力 (許可されていない場合でも) は正しいはずです。「-」または「.」で入力を開始できます。また、「自動修正」を使用すると、「.34」または「-.34」と入力すると、「0.34」または「-0.34」に修正されます。
矢印でカーソル位置を変更できます。貼り付けが許可されていない文字列の後、カーソル位置は変更されません。適切な文字列を貼り付けた後、新しいカーソル位置は貼り付けられた文字列の最後になります。
先行ゼロの削除が欠落しているのが気に入らない既知の障害 (および末尾のゼロも削除する必要があるかもしれません)。
エラーが見つかった場合はお知らせください。修正を試みます(喜んで)。スクリプトは少し長いです。昨日、いくつかのバグを見ましたが、今後数日間は時間がないので、誰かがプレイするためにそこに置くことにしました。
これは実際には見た目よりもトリッキーです。しかし、これは機能します:
on keyDown pKey
if pKey = "-" and me <> "" then exit keyDown
if pKey = "." and "." is in me then exit keyDown
if pKey is in "-0123456789." then pass keydown
end keyDown
「数字です」を使ってみてはどうですか?唯一の特殊なケースは、先頭に "-" を許可する必要があることです:
on KeyDown theKey
if (the text of me & theKey) is a number then
pass keyDown
else if the text of me is empty and theKey is "-" then
pass keyDown
end if
end KeyDown