C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

TextBoxのフォーマット /たかし (21/08/24(Tue) 15:43) #98010
Re[1]: TextBoxのフォーマット /Hongliang (21/08/24(Tue) 15:54) #98011
Re[1]: TextBoxのフォーマット /魔界の仮面弁士 (21/08/24(Tue) 16:15) #98013
Re[1]: TextBoxのフォーマット /WebSurfer (21/08/24(Tue) 16:00) #98012
Re[1]: TextBoxのフォーマット /大谷刑部 (21/08/25(Wed) 11:38) #98014
  └ Re[2]: TextBoxのフォーマット /たかし (21/08/25(Wed) 13:18) #98015
    └ Re[3]: TextBoxのフォーマット /furu (21/08/25(Wed) 15:09) #98016
      └ Re[4]: TextBoxのフォーマット /たかし (21/08/25(Wed) 15:32) #98017
        ├ Re[5]: TextBoxのフォーマット /大谷刑部 (21/08/25(Wed) 16:10) #98020
        │└ Re[6]: TextBoxのフォーマット /たかし (21/08/25(Wed) 16:41) #98021
        │  └ Re[7]: TextBoxのフォーマット /大谷刑部 (21/08/26(Thu) 09:46) #98023
        ├ Re[5]: TextBoxのフォーマット /Hongliang (21/08/25(Wed) 16:01) #98018
        └ Re[5]: TextBoxのフォーマット /shu (21/08/25(Wed) 16:06) #98019
          └ Re[6]: TextBoxのフォーマット /たかし (21/08/25(Wed) 18:31) #98022 解決済み


親記事 / ▼[ 98011 ] ▼[ 98013 ] ▼[ 98012 ] ▼[ 98014 ]
■98010 / 親階層)  TextBoxのフォーマット
□投稿者/ たかし (26回)-(2021/08/24(Tue) 15:43:30)

分類:[.NET 全般] 

いつもお世話になっております、たかしです。
VB.NETの質問なのですが、TextBoxのフォーマットを「12,345,678」にするために、
次のようなコードを書いてみたのですが、
TextBoxの値が「12,345」となって桁が3つ飛んでしまいます。
どこが間違いなのでしょうか?どなたか教えて下さい。

  TextBox.Text = CStr(Val(TextBox1.Text) + Val(TextBox2.Text) + Val(TextBox3.Text))
If TextBox.Text = "" Then
  Exit Sub
Else
  TextBox.Text = String.Format("{0:##,###,###}", CLng(TextBox.Text))
End If

[ □ Tree ] 返信 編集キー/

▲[ 98010 ] / 返信無し
■98011 / 1階層)  Re[1]: TextBoxのフォーマット
□投稿者/ Hongliang (1192回)-(2021/08/24(Tue) 15:54:16)
「桁が3つ飛んで」というのがちょっとわかりません。
・TextBox1〜3のTextにそれぞれどんな値が格納されているのか
・その場合どういう出力を想定しているのか
をご提示ください。
[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98010 ] / 返信無し
■98013 / 1階層)  Re[1]: TextBoxのフォーマット
□投稿者/ 魔界の仮面弁士 (3168回)-(2021/08/24(Tue) 16:15:03)
No98010 (たかし さん) に返信
> TextBoxのフォーマットを「12,345,678」にするために、

TextBox1.Text を NumericUpDown1.Value に差し替えるのは如何ですか?

NumericUpDown ならば、最初から数値しか入力できなくなりますし、
3 桁区切りも ThousandsSeparator プロパティの設定だけで済みます。
最小値・最大値・小数点桁数なども制限できますよ。

TextBox では文字列を返す Text プロパティを扱いましたが、
NumericUpDown ではそれの代わりに、数値を返す Value プロパティを使うことになります。



> TextBox.Text = CStr(Val(TextBox1.Text) + Val(TextBox2.Text) + Val(TextBox3.Text))

・TextBox の名前を、型名と同一の "TextBox" にするのは、混乱を招くので避けましょう。
・Val の利用はお奨めしません。特定の文字列に対して変換エラーを起こすことがあります。


文字列の数値化が目的なら、Decimal.TryParse メソッドの利用をお奨めしておきます。


> TextBox.Text = CStr(Val(TextBox1.Text) + Val(TextBox2.Text) + Val(TextBox3.Text))
この時点で、 String → Double → String という変換が発生しています。

> If TextBox.Text = "" Then
となれば、この時点で "" になることは無いはず。

> TextBox.Text = String.Format("{0:##,###,###}", CLng(TextBox.Text))
先ほどは String → Double → String したものを、さらに
String → Long → String と変換していますね。
であれば、最初にわざわざ CStr せずとも、数値型の変数に受けて処理した方が良いでしょう。

また、3 桁区切りを ##,###,### 指定にしていますが、
その場合、数値ゼロが "0" ではなく "" になります。
もしも N0 書式にすれば、ゼロを "0" と変換できます。
[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98010 ] / 返信無し
■98012 / 1階層)  Re[1]: TextBoxのフォーマット
□投稿者/ WebSurfer (2333回)-(2021/08/24(Tue) 16:00:50)
No98010 (たかし さん) に返信

何の TextBox ですか? WinForms? WPF? ASP.NET Web Forms? ASP.NET MVC? Html? その他?
[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98010 ] / ▼[ 98015 ]
■98014 / 1階層)  Re[1]: TextBoxのフォーマット
□投稿者/ 大谷刑部 (149回)-(2021/08/25(Wed) 11:38:42)
No98010 (たかし さん) に返信
> いつもお世話になっております、たかしです。
> VB.NETの質問なのですが、TextBoxのフォーマットを「12,345,678」にするために、
> 次のようなコードを書いてみたのですが、
> TextBoxの値が「12,345」となって桁が3つ飛んでしまいます。
> どこが間違いなのでしょうか?どなたか教えて下さい。
>
>   TextBox.Text = CStr(Val(TextBox1.Text) + Val(TextBox2.Text) + Val(TextBox3.Text))

飛ぶというより、3つのテキストボックスの値の三桁以内の整数であると仮定すると、
val関数通した時点で数値になり、+演算子は足し算にになりますよね。
8桁の整数にはなり得ないです。

> If TextBox.Text = "" Then
>   Exit Sub
> Else
>   TextBox.Text = String.Format("{0:##,###,###}", CLng(TextBox.Text))
> End If
>

弁さんの指摘通りTextBox.Text = ""には絶対になりません。
val関数かけた時点でNothig(vbNullstring)、empty等は全部0に変換されてしまいますから。

12,345,678としたいのであれば、まず+演算をした時点で、TextBox.Textの値が12345678となっているのを確認する必要がありますよね?

そもそも、+演算子は足し算か文字列連結かどちらの意図で使おうとしてますか?
それによって解が変わる気がします。

[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98014 ] / ▼[ 98016 ]
■98015 / 2階層)  Re[2]: TextBoxのフォーマット
□投稿者/ たかし (27回)-(2021/08/25(Wed) 13:18:05)
No98014 (大谷刑部 さん) に返信
> ■No98010 (たかし さん) に返信
>>いつもお世話になっております、たかしです。
>>VB.NETの質問なのですが、TextBoxのフォーマットを「12,345,678」にするために、
>>次のようなコードを書いてみたのですが、
>>TextBoxの値が「12,345」となって桁が3つ飛んでしまいます。
>>どこが間違いなのでしょうか?どなたか教えて下さい。
>>
>>  TextBox.Text = CStr(Val(TextBox1.Text) + Val(TextBox2.Text) + Val(TextBox3.Text))
>
> 飛ぶというより、3つのテキストボックスの値の三桁以内の整数であると仮定すると、
> val関数通した時点で数値になり、+演算子は足し算にになりますよね。
> 8桁の整数にはなり得ないです。
>
>> If TextBox.Text = "" Then
>>   Exit Sub
>> Else
>>   TextBox.Text = String.Format("{0:##,###,###}", CLng(TextBox.Text))
>> End If
>>
>
> 弁さんの指摘通りTextBox.Text = ""には絶対になりません。
> val関数かけた時点でNothig(vbNullstring)、empty等は全部0に変換されてしまいますから。
>
> 12,345,678としたいのであれば、まず+演算をした時点で、TextBox.Textの値が12345678となっているのを確認する必要がありますよね?
>
> そもそも、+演算子は足し算か文字列連結かどちらの意図で使おうとしてますか?
> それによって解が変わる気がします。
>

皆さん、どうもありがとうございます。

> そもそも、+演算子は足し算か文字列連結かどちらの意図で使おうとしてますか?

もちろん足し算です。If以下を消して、

TextBox.Text = CStr(Val(TextBox1.Text) + Val(TextBox2.Text) + Val(TextBox3.Text))

とした時点で、既に下3桁が表示されません。

TextBox.Text = Val(TextBox1.Text) + Val(TextBox2.Text) + Val(TextBox3.Text)

としても全く同じです。

そもそも下3桁が「飛ぶ」理由が分からないのです。
String.Format("{0:##,###,###}", CLng(TextBox.Text))では下3桁のない数値にカンマが付きます。

そこで苦し紛れに
TextBox.Text = Val(TextBox1.Text)*1000 + Val(TextBox2.Text)*1000+ Val(TextBox3.Text)*1000
などとやると当然ながら下3桁は「000」となり全く意味がわかりません。




[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98015 ] / ▼[ 98017 ]
■98016 / 3階層)  Re[3]: TextBoxのフォーマット
□投稿者/ furu (124回)-(2021/08/25(Wed) 15:09:46)
No98015 (たかし さん) に返信
具体的に
TextBox1.Text,TextBox2.Text,TextBox3.Textに何を入力し
TextBox.Textに何が表示されたか
記載してもらえますか?

たかしさんが気づかないことに気づけるかもしれません。

例えば、TextBox1.Textが「123456,789」となっていて
「789」を無視されたとか。
[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98016 ] / ▼[ 98020 ] ▼[ 98018 ] ▼[ 98019 ]
■98017 / 4階層)  Re[4]: TextBoxのフォーマット
□投稿者/ たかし (28回)-(2021/08/25(Wed) 15:32:10)
No98016 (furu さん) に返信
> ■No98015 (たかし さん) に返信
> 具体的に
> TextBox1.Text,TextBox2.Text,TextBox3.Textに何を入力し
> TextBox.Textに何が表示されたか
> 記載してもらえますか?
>
> たかしさんが気づかないことに気づけるかもしれません。
>
> 例えば、TextBox1.Textが「123456,789」となっていて
> 「789」を無視されたとか。

例えば次のようなことです。

TextBox1.Text = 896,000
TextBox2.Text = 896,000
TextBox3.Text = 896,000

TextBox.Textは「2,688,000」となるはずですが「2,688」となってしまいます。


[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98017 ] / ▼[ 98021 ]
■98020 / 5階層)  Re[5]: TextBoxのフォーマット
□投稿者/ 大谷刑部 (150回)-(2021/08/25(Wed) 16:10:19)
No98017 (たかし さん) に返信
> 例えば次のようなことです。
>
> TextBox1.Text = 896,000
> TextBox2.Text = 896,000
> TextBox3.Text = 896,000
>
> TextBox.Textは「2,688,000」となるはずですが「2,688」となってしまいます。
>

であれば、val関数を使ってるのが誤りです。
,付文字列を正常に数値に変換できてないということですから。

先に未入力を0に変換してからInteger.ParseかCintで整数に変換じゃないでしょうかね?

例えば、

iif(TextBox1.Text.length>0,Cint(TextBox1.Text),0)

みたいな感じで。

[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98020 ] / ▼[ 98023 ]
■98021 / 6階層)  Re[6]: TextBoxのフォーマット
□投稿者/ たかし (29回)-(2021/08/25(Wed) 16:41:10)
No98020 (大谷刑部 さん) に返信
> ■No98017 (たかし さん) に返信
>>例えば次のようなことです。
>>
>>TextBox1.Text = 896,000
>>TextBox2.Text = 896,000
>>TextBox3.Text = 896,000
>>
>>TextBox.Textは「2,688,000」となるはずですが「2,688」となってしまいます。
>>
>
> であれば、val関数を使ってるのが誤りです。
> ,付文字列を正常に数値に変換できてないということですから。
>
> 先に未入力を0に変換してからInteger.ParseかCintで整数に変換じゃないでしょうかね?
>
> 例えば、
>
> iif(TextBox1.Text.length>0,Cint(TextBox1.Text),0)
>
> みたいな感じで。
>



TextBox.Text = CLng(TextBox1.Text) + CLng(TextBox2.Text) + CLng(TextBox3.Text)

とすることで解決いたしました。
お騒がせしました。


[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98021 ] / 返信無し
■98023 / 7階層)  Re[7]: TextBoxのフォーマット
□投稿者/ 大谷刑部 (151回)-(2021/08/26(Thu) 09:46:02)
No98021 (たかし さん) に返信
> TextBox.Text = CLng(TextBox1.Text) + CLng(TextBox2.Text) + CLng(TextBox3.Text)
>
> とすることで解決いたしました。
> お騒がせしました。

当初の質問の回答としてはそれでいいですけど、
3つのテキストボックスのいずれかに未入力があったら例外発生しますよ。

TryParse使うか、IIF等で分岐するかは好きにしてもらうとして、
Nothing、String.empty等で型変換エラーにならない考慮は必要と思います。
数字以外を入力させない制御はやりようによっては出来るでしょうが、「入力値なし」を入力時点で抑止するのは不可能でしょうから。

Leaveイベント等で3つのテキストボックスの未入力チェックをしていて、足し算が未入力チェック後にしか起こりえないようなロジックになってるなら別ですが。


[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98017 ] / 返信無し
■98018 / 5階層)  Re[5]: TextBoxのフォーマット
□投稿者/ Hongliang (1193回)-(2021/08/25(Wed) 16:01:02)
それ以前のVal関数の問題ですね。
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.visualbasic.conversion.val?view=net-5.0#Microsoft_VisualBasic_Conversion_Val_System_String_
上記リンク先に
> 関数は、 Val 数値の一部として認識できない最初の文字の文字列の読み取りを停止します。 
> 多くの場合、ドル記号やコンマなど、数値の一部と見なされる記号と文字は認識されません。
と記載されています(日本語訳が酷いですが…)。

文字列を数値に変換する場合、整数値であればInt32.TryParseメソッド、実数値であれば
Double.TryParseまたはDecimal.TryParseメソッドを使用することをお勧めします。

例えば今回の場合以下のように記述できます。

' Imports System.Globalization をソースファイル先頭に記載する
Dim num1, num2, num3 As Integer
If Not(Int32.TryParse(TextBox1.Text, NumberStyles.Number, CultureInfo.InvariantCulture, num1)) Then
    ' 入力異常
    Return
End If
If Not(Int32.TryParse(TextBox2.Text, NumberStyles.Number, CultureInfo.InvariantCulture, num2)) Then
    ' 入力異常
    Return
End If
If Not(Int32.TryParse(TextBox3.Text, NumberStyles.Number, CultureInfo.InvariantCulture, num3)) Then
    ' 入力異常
    Return
End If
Dim total As Integer = num1 + num2 + num3
TextBox4.Text = total.ToString("##,###,###")

NumberStyles.Numberは、文字列の先頭・末尾の空白と正負の符号、桁区切り記号、小数点を許容するスタイルです。

[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98017 ] / ▼[ 98022 ]
■98019 / 5階層)  Re[5]: TextBoxのフォーマット
□投稿者/ shu (1262回)-(2021/08/25(Wed) 16:06:31)
No98017 (たかし さん) に返信

Dim a = "896,000"

Dim b = Val(a)
Dim c = CInt(a)

を実行すると
bは896
cは896000
となります。なので確認されているような現象が発生します。

[ 親 98010 / □ Tree ] 返信 編集キー/

▲[ 98019 ] / 返信無し
■98022 / 6階層)  Re[6]: TextBoxのフォーマット
□投稿者/ たかし (30回)-(2021/08/25(Wed) 18:31:25)
No98019 (shu さん) に返信
> ■No98017 (たかし さん) に返信
>
> Dim a = "896,000"
>
> Dim b = Val(a)
> Dim c = CInt(a)
>
> を実行すると
> bは896
> cは896000
> となります。なので確認されているような現象が発生します。
>
解決済み
[ 親 98010 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -