
いつもお世話様です。
エクセルVBAでFormatを使うと、文字列中にeが一つ入っていると、「指数」とみなされて勝手に数値に化けてしまうようです。
話を簡単にするため、問題のコートを簡易化したコードが下記のtest1です。
入力されるのは常に3文字以内の英数です。
test1のコードは、ab9と入れればAB9、01とか20とか入れると、予定通り001や020を返してくれます。
ところが、なかには1E1や4E3なども入力する必要があり、これを入れると010や4000に化けてしまいます。
現在は、対処するため、下記test2のように、文字列中に"E"があるかどうかで処理を分岐させていますが、ほかに何か良い方法はないでしょうか?
Sub test1()
Dim x As String, y As String, z As String
x = Application.InputBox("CODEを入力してねん。", Type:=2)
y = StrConv(StrConv(x, vbUpperCase), vbNarrow)
z = Format(y, "000")
MsgBox z & " Typeだよ。"
End Sub
Sub test2()
Dim x As String, y As String, z As String
x = Application.InputBox("CODEを入力してねん。", Type:=2)
y = StrConv(StrConv(x, vbUpperCase), vbNarrow)
If InStr(y, "E") > 0 Then
z = y
Else
z = Format(y, "000")
End If
MsgBox z & " Typeだよ。"
End Sub
No.2ベストアンサー
- 回答日時:
エキスパートさん、こんにちは。
FORMAT関数をまだ自分のものにしておりませぬね。
と、ちょっときついことを言ってみる。(^^;;;
Format(y,"000") は、数値表示書式指定文字を使ってますから
文字列1E2(10^2)も数字になります。
質問には英数混合3桁の例で、ab9 とありますが
英数混合で3桁未満はどう表示するのでしょうか?
ab → 0AB → ■AB → AB
b → 00B → ■■B → B
1a → 01A → ■1A → 1A
■はスペース
3桁未満の表示の仕方によっては、#1の回答も
単純には使えないことはお分かりですね。
(おまけ)
いまのままで 1a とか 1p を試したみてください。
何れにしろ分岐が必要になると思われます。
以上です。
これはこれは、kobouzu_su様、いつも有難うございます。
1a とか 1p も化けるんですね!亜茶^2!!
これは指数じゃないですよね?な、なんなのでしょう?
先頭に0をつけるのはあくまで数字だけの場合ですので1Aや1Pはそのまま表示されればいいのです。
試行錯誤の結果、以下のように対応しましたがこれで正解でしょうか?
Sub test5()
Dim x As String, y As String, z As String
x = Application.InputBox("CODEを入力してねん。", Type:=2)
If Len(Trim(x)) > 3 Then
MsgBox "そんな長いTypeCode知りませぬ。", vbCritical, " (; ´・ω・`)σ" & x
Exit Sub
End If
y = StrConv(StrConv(x, vbUpperCase), vbNarrow)
z = IIf(IsNumeric(y), Right$("000" & y, 3), y)
MsgBox z & " Typeだよ。", , " ( ̄ー ̄)v "
End Sub
No.5
- 回答日時:
> Eは指数表示というのは存じてましたが、Dは何なのですか?
「D」も「E」もともに指数を表しています。両者の違いは、
・E 有効桁数が Single(単精度)の指数
・D 有効桁数が Double(倍精度)の指数
です。
> 1Pや1Aもわかりません。
これは IsNumeric の問題ではありません。Format の問題ですね。
こちらについては、kobouzu_su さんが詳しく回答なさってます。
以下は余談までに。
IsNumeric 関数は仕様として、指数表記の文字、小数点、桁区切り
のカンマなども数値として評価します。
つまり、、
IsNumeric 関数はあくまで「数値として評価できるか」を判定する
関数であって、判定対象が必ずしも数字で構成されていることを
保証しません。
これはこれで都合が良いことも多いのですが、例えばデータベース
絡みの処理を考えてみると、整数フィールドに値を代入する SQL
を発行する場合に、指数表記の文字などが混入すると SQL でコケ
るか、間違った値が保存されてしまいます。
単純に IsNumeric でしか入力チェックしてないとスルーしちゃうん
ですね...
このような心配があるときは、#3 の参考 URL にある IsDigit の
ような自前関数を作ってチェックを行う必要があります。
IsNumeric にバグがある訳ではなく、あくまで仕様なのですが、
このことを理解していないと、思いもよらない結果を返すという話
になってしまいます。
# 同じように IsDate 関数も英語表記の日付式で True を返します。
結局は、仕様を良く理解した上で利用する...「上手に使え」という
ことになってしまうのですが^^;
ご参考までに、正規表現を使った例です。
Sub test6()
Dim x As String
Dim y As Variant
x = Application.InputBox("CODEを入力してねん。", Type:=2)
v = CheckCode(x)
If VarType(v) = vbBoolean Then
MsgBox "(; ´・ω・`)σ不正値みたい", vbCritical
Else
MsgBox CStr(v) & " Typeだよ。", vbInformation, " ( ̄ー ̄)v "
End If
End Sub
' // Code チェック関数
Private Function CheckCode( _
ByVal sCode As String _
) As Variant
' // コードの長さ(文字数)
Const MAX_DIGIT As Long = 3&
CheckCode = False
' // 引数 sCode が3文字より多ければ終了
If Len(sCode) > MAX_DIGIT Then Exit Function
' // 前後の不要スペース除去・半角大文字に補正
sCode = Trim(sCode)
sCode = StrConv(sCode, vbUpperCase Or vbNarrow)
' // 正規表現で入力チェック
Dim reg As RegExp
Set reg = CreateObject("VBScript.RegExp")
reg.Pattern = "^[0-9]+$"
If reg.test(sCode) Then
' // Return: 数字のみの場合-->桁数補正
CheckCode = Right$(String$(MAX_DIGIT, "0") & sCode, MAX_DIGIT)
Else
' // Return: 数字以外が含まれる場合
' // 規定の文字以外がないかチェック
reg.Pattern = "^[0-9A-Z]+$"
If reg.test(sCode) Then
CheckCode = sCode
End If
End If
Set reg = Nothing
End Function
KenKen_SPさま、ご丁寧に有難うございます。
「正規表現」というのはまったく馴染みがないのですが、これもいずれ勉強したいと思います。
今回も有難うございました。
No.4
- 回答日時:
またまた登場、kobouzuです。
(^o^)/KenKen_SPさんまで登場してくださるとは、エキスパートさんはなんと幸せものでしょう。
鬼に金棒とは、こういう状況を言ふのですよねぇ。
あと、一人、登場されると、金棒2本ですね。
ということで、当方への質問のみの返答ということで。
2a と 3p とかと、Format(y,"000")の関係について。
以下をお試しください。
Sub test()
Dim y
y = "2a" ''' y = "5p"
Range("A1").Value = Format(y, "0.0000000")
Range("A2").Value = Format(y, "0.0000000")
Range("A2").NumberFormat = "hh:mm:ss"
End Sub
どうでせしょう。お分かりになりましたか?
それから、
>If Len(Trim(x)) > 3 Then
と
>y = StrConv(StrConv(Trim(x), vbUpperCase), vbNarrow)
Trimはあまり感心しませんね。
2■5 とかが上手くいかないですよね。
それと細かいことですが、vbUpperCase,vbNarrowは次のように
y = StrConv(????, vbUpperCase+vbNarrow)
と、+で結合して使うのがふつうです。
以上です。
kobouzuさま、いつも有難うございます。
素晴らしい知識のみなさまに教えていただき「質問のエキスパート」?は非常に助かっております。
IsNumericではFalseになるけど、Formatすると、2Aは午前二時、3Pは午後3時なんですね!初めて知りました。おどろきました。
> Trimはあまり感心しませんね。
> 2■5 とかが上手くいかないですよね。
すみません、これはちょっとわかりませんでした。
■は、スペースの意味ですか?
Trim関数は文字列の先頭と末尾のスペースだけ削除するんですよね?なら真中の■に影響ないのでは?それとも他の問題でしょうか?
MsgBox StrConv("abc", vbUpperCase + vbNarrow) と、+で結合して使えるんですね!!これも初めて知りました。おどろき^2 です。
No.3
- 回答日時:
こんにちは。
どうせならもう一歩踏み込んでみては?
[つっこみ] IsNumeric だけでは不十分(意地悪じゃないですよ^^;)
例).12、+12、-12、!!!
[ご提案] 規定の文字以外を弾くチェック関数を作ってみては?
・方法1: 正規表現を使ってみる
CreateObject("VBScript.RegExp")
Test メソッド
マッチングパターン: [0-9A-Z]{,3}
・方法2: 一文字ずつ Mid で取り出して判定
Like 演算子を使ってみる、または文字リストを作っておき、
それと比較する
文字列長は3文字判定しておく
[参考URL:]
http://homepage1.nifty.com/rucio/main/technique/ …
この回答への補足
すみません。勘違いでした。お礼で書いたABSは使えませんね。
また3D2や3E2もFALSEではなくTRUEでした。
ただ、1Pや1AはFALSEです。
Dは何なのですか?また1Pや1Aも何なのでしょうか?という質問です。
よろしくお願いいたします。
ご指摘有難うございました。いろいろ問題ありますねえ!
今回は、Typeの誤入力を防ぐ方法ではなく、入力した1E1等がが化けることが問題なので.12、+12、-12は特に差し支えありません。(一応ABSで対処はしましたが)
参考URLを見ましたが、Eだけじゃなく3D2のようなのも数値に化けるんですね!これは問題です。Eは指数表示というのは存じてましたが、Dは何なのですか?さきほどの1Pや1Aもわかりません。よろしかったらご教示ください。
また、参考URL ではIsNumericでTRUEとなると書かれた3D2や3E2が下記のコードではFALSEとなるようですが何故でしょうか?
Sub test6()
Dim x As String, y As String, z As String
x = Application.InputBox("CODEを入力してねん。", Type:=2) ')
If Len(Trim(x)) > 3 Then
MsgBox "そんな長いTypeCode知りませぬ。", vbCritical, " (; ´・ω・`)σ" & x
Exit Sub
End If
y = StrConv(StrConv(Trim(x), vbUpperCase), vbNarrow)
If IsNumeric(y) Then
z = Right$("000" & Abs(y), 3)
Else
z = y
End If
MsgBox z & " Typeだよ。", , " ( ̄ー ̄)v "
End Sub
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) エクセルVBA、ファイル名をセルの値で保存の方法を教えてください。 おそれいります。こちらで数々のエ 6 2023/06/30 22:17
- Visual Basic(VBA) ExcelVBAに関する質問 3 2023/02/17 10:47
- Excel(エクセル) エクセルシート中の全角英数字を半角に変換したい 4 2022/07/07 13:14
- Excel(エクセル) エクセルVBA、間違っているコード内容を正して頂けませんか? エクセルワークシートに納品書を作ったの 2 2023/08/02 21:13
- Visual Basic(VBA) Excel VBA でデータ転記について 1 2023/03/07 19:11
- Excel(エクセル) このコードに追記事項の仕方を教えて下さい。 以下のコード内容に出てくる。セルH3が空白の場合、エラー 4 2023/08/03 00:22
- Visual Basic(VBA) InputBoxでキャンセルボタンを押したらファイル自体を閉じたい 3 2022/07/23 17:52
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Visual Basic(VBA) 入力ボックスが繰り返しポップアップして止まらない。 下記コードでファイル名の変更をしたいのですが、変 1 2022/09/08 11:27
- Visual Basic(VBA) 別シートのデータを参照して値を入れたい。 まとめデータシートのC列D列の値を商品一覧シートのコードが 7 2022/08/17 13:20
このQ&Aを見た人はこんなQ&Aも見ています
-
Excelで数値→文字列変換で指数表示になったものをいっぺんに直したい
Excel(エクセル)
-
Excelで指数表現しないようにする方法
Excel(エクセル)
-
エクセルvbaで転記したのですが、数字のゼロが消えてしまいます。 ゼロも転記するためにはどうしたらい
Excel(エクセル)
-
-
4
VBAでFormat がうまく使えない
Excel(エクセル)
-
5
Excelで3E8を3.00E+8にしない方法を教えてください。
Excel(エクセル)
-
6
VBAで文字列を数値に変換したい
Excel(エクセル)
-
7
callで順に実行されるプロシージャを途中で止める方法
Excel(エクセル)
-
8
【Excel VBA】CSV取込時、数字の先頭の0を消えないようにするには?
Excel(エクセル)
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
正整数の半角数字かどうか判定する
-
VC#でテキストボックスに変数の...
-
ハイフンだけ置換したい。
-
C#でTextBoxに数値のみ入力可能...
-
VB.NET2003 テキストボックスに...
-
エクセルVBA/ Formatで文字列が...
-
エクセル 半角英数6文字以上 ...
-
JavaScriptでフォームの入力項...
-
文字認証の問題
-
禁止文字チェック
-
正規表現での入力文字数と連続...
-
正規表現について
-
c言語で「文字列(最大80文字)お...
-
Javascript Netscapeの文字数判...
-
デザイン時のVisible=Falseは実...
-
以下のコードを実行しても、オ...
-
VisualStudio2008の最適化について
-
JavaScriptで月に対して日の整...
-
DOMで追加した要素が「前に戻る...
-
htmlのfileタグに自動で値を入...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB.NET2003 テキストボックスに...
-
VBAによる第3、4水準文字の判定...
-
正整数の半角数字かどうか判定する
-
「終了していない文字列型の定...
-
gas 全角数字を半角数字に変換
-
文字認証の問題
-
エクセルVBA/ Formatで文字列が...
-
ハイフンだけ置換したい。
-
エクセル 半角英数6文字以上 ...
-
正規表現について
-
禁止文字チェック
-
Access VBAで、数字だけをチェ...
-
漢字などを正規表現でパターン...
-
javascript 文字列の最後から1...
-
Visual Basic 6.0 のテキストボ...
-
Vba SelStart、SelLen教えてく...
-
【教えて下さい】正規表現クイズ
-
Javascript 全角カナ+半角スペ...
-
Javascriptで別のサイトのフォ...
-
入力された文字を1文字ずつチ...
おすすめ情報