• ベストアンサー

〔ExcelVBA〕ユーザーフォームテキスト

ユーザーフォームから値の入力を受け付けるようにしています。 このとき、テキストボックスに入力された数値が3桁区切りで表示されるように出来ないでしょうか?数値を入力するボックスなので。 100万円以上の数値を入力するときに見づらくて困っています。

質問者が選んだベストアンサー

  • ベストアンサー
  • myCat
  • ベストアンサー率60% (9/15)
回答No.4

こんにちは、再度の登場です。(^^; リアルタイムならWendy02さんの仰るとおりChangeイベントだろうと思います。 -------------------------------------------------- Private Sub TextBox1_Change()  TextBox1.Text = Format(TextBox1.Text, "#,###") End Sub ----------------------------------------------------- それから電卓のように右端から入力されていくようにするだけなら、MaskEdBoxコントロールを使えば出来ますが・・・・ 今回の場合とはちょと目的が違います。 一応後学のためにヘルプを覗いてみることをお勧めします。 以上です。

shunshun-dash
質問者

お礼

私の希望はChangeイベントでした。ありがとうございます。 これからはイベントの種類も勉強していきたいと思います。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (5)

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.6

> 簡単に言うとどのような利用の仕方をするものなのでしょうか? クラス化する最大のメリットはインスタンスが可能であること。 と言うと難しい話のように聞こえますが、実は単純な話です。今回の事例 で説明すると...電卓の入力動作には2種の制御が必要です。  1. 入力をリアルタイムで桁区切りの数値にフォーマットする    -->他ご回答にあるとおり、Change イベントで実現します  2. 入力時に数値しか入力できない    -->KeyDown イベントで実現します 通常ですと、以上のように2つのイベントプログラムを書くことになりますね。 では、この動作を100個のテキストボックスに適用するとしたらどうしますか? 必要イベント2×100個のテキストボックス = 200 で 200 のイベントプログラムを書きますか? では1000個なら? 全く同じ動作なのに効率が悪いですよね。そういう時にクラスが非常に 役立ちます。今回の場合、例え 100個のテキストボックスであろうとも Private NumCtrl(1 To 100) As New NumTextbox Private Sub UserForm_Initialize()   For i = 1 To 100     Set NumCtrl(i).Bind = Me.Controls("TextBox" & Cstr(i))   Next i End Sub これだけです。仮にテキストボックスが 1000 でも 2000 でもこの方法なら どれだけ増えても簡単です。 同じ機能を複製して使いたいとき...そんな時にクラスが使われます。 2次的なメリットは機能のカプセル化です。 クラスでは決められたプロパティーを設定したり、機能を呼び出すだけで ひとかたまりの処理がなされます。この時、クラス内のコードを理解して 使う必要はありません。 身近な例で言えば、Excel ワークシートや ThisWorkbook モジュール、 フォームは実は全てクラスなんですよ。 例えば、フォームのタイトルを変えるには   Userform1.Caption = "SAMPLE FORM" なんてコードを書きます。Caption プロパティーを設定するだけで、ウインドウ のタイトルが変わるんです。これは実際にはフォームクラスが裏で複雑な 処理をして Windows に数多くのメッセージを送って、Windows から返って きたメッセージを解析して、やっと書き換わるものなのですが、ユーザーは その煩雑な部分を意識することはありません。   Userform1.Caption = "SAMPLE FORM" これだけ書けば、ちょろっと書き換わるんです。今回の NumTextbox クラス も利用するのに必要なコードは、   NumCtrl(1).Bind = Textbox1 といった単純なコードです。 本当はものすごく複雑なことをやってるのだけれども、それをユーザーが 意識することなく、このように単純な手続きのみで処理ができる... これがカプセル化です。 クラス...と聞いて腰が引ける人が多いのですが、上述のとおりコードを書く 人は、普段からクラスを使っているのです。意識してないだけなんですよね。 もちろんクラスを書くにはそれなりの知識が必要なのですが、コツさえ掴んで しまえばそれほど難しくもなく、クラスを利用するに至っては非常に簡単な ことなのです。

shunshun-dash
質問者

お礼

ありがとうございます。 効率よくコードを記述するためにも、将来的には心得たいですね。 でも、クラスの意味するところのイメージはできました。

全文を見る
すると、全ての回答が全文表示されます。
  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.5

こんにちは。KenKen_SP です。 電卓のような入力...ということでクラスを作ってみました。取り合えず、 サンプルとして手順説明通り試してみて下さい。なお、クラスを他ブックに インポートし、Form_Initialize イベントにクラス関連付けのコードを追加 するだけで、他案件でも簡単に使いまわせます。 長いソースですが、慣れると簡単な作業です。 注) クラスとフォームと2つのソースがあります。 ' ソース1 の貼り付け手順 ' 1. VBE [挿入]-[フォーム] をクリック ' 2. 1. で挿入したフォームに次のコントロールを配置 '   Textbox1 '   Textbox2 '   CommandButton1 ' 3. ソース1 をフォームモジュールへコピペ ' ソース1 Option Explicit ' 冒頭で NumTextbox クラスを使うことを宣言します ' 今回は2つのテキストボックスを使うので(1 TO 2) Private NumCtrl(1 To 2) As New NumTextbox Private Sub UserForm_Initialize()   ' 数値用テキストボックスにそれぞれ NumTextbox クラスを関連付けます   Set NumCtrl(1).Bind = Me.TextBox1   Set NumCtrl(2).Bind = Me.TextBox2 End Sub Private Sub CommandButton1_Click()   On Error GoTo ERROR_HANDLER   MsgBox "合計:" & CStr(CCur(TextBox1.Value) + CCur(TextBox2.Value))   Exit Sub    ERROR_HANDLER:   If Err.Number = 6 Then     MsgBox "テキストボックスの値は文字列なので整数部29桁まで" & vbLf _        & "入力可能ですが、計算時はオバーフロー対策が必要です。", _        vbCritical, "注意事項"   End If End Sub ' ソース2 の貼り付け手順 ' 1. VBE [挿入]-[クラスモジュール] をクリック ' 2. 1. で挿入したクラスのプロパティーウインドウでモジュール名を '  を [NumTextbox] に変更 ' 3. ソース2 をコピペ ' ソース2 Option Explicit ' // 数値入力用テキストボックス制御クラス Private WithEvents TextBoxCtrl As MSForms.TextBox ' ------------------------------------------------------------------- ' コンストラクタ・デストラクタ ' ------------------------------------------------------------------- Private Sub Class_Terminate()   Set TextBoxCtrl = Nothing End Sub ' ------------------------------------------------------------------- ' プロパティー ' ------------------------------------------------------------------- Public Property Set Bind(ByVal Ctrl As MSForms.TextBox)   Set TextBoxCtrl = Ctrl   With TextBoxCtrl     ' IME モードを無効にしてテキストを右揃えにする     .IMEMode = fmIMEModeDisable     .TextAlign = fmTextAlignRight   End With End Property ' ------------------------------------------------------------------- ' イベント ' ------------------------------------------------------------------- ' 特定キー以外の入力を不可にする Private Sub TextBoxCtrl_KeyDown( _   ByVal KeyCode As MSForms.ReturnInteger, _   ByVal Shift As Integer)   Dim lPeriodPos As Long   Dim sNum    As String   Select Case KeyCode     ' 数字キー許可     Case 48 To 57, 96 To 105       ' ただし整数部が29桁以上ならフォーマットできないのでキャンセル       With TextBoxCtrl         If Len(.Text) > 0 Then           lPeriodPos = InStr(.Text, ".")           If lPeriodPos > 0 Then             sNum = Left$(.Text, lPeriodPos - 1)           Else             sNum = .Text           End If           sNum = Replace(sNum, ",", "")           sNum = Replace(sNum, "-", "")           If Len(sNum) = 29 Then KeyCode = 0          End If       End With     ' Enter等の特定制御キーは許可     Case vbKeyReturn, vbKeyTab, vbKeyDelete, vbKeyBack     Case vbKeyLeft To vbKeyDown     ' マイナスは冒頭で一つまで許可     Case vbKeySubtract       With TextBoxCtrl         If Len(.Text) > 0 Or InStr(.Text, "-") > 0 Then KeyCode = 0       End With     ' ピリオドは一つまで許可     Case 110, 190       If InStr(TextBoxCtrl.Text, ".") > 0 Then KeyCode = 0     ' その他キーキャンセル     Case Else: KeyCode = 0   End Select    End Sub ' 値が変化したらフォーマットする Private Sub TextBoxCtrl_Change()   Dim lPeriodPos As Long   Dim sNum    As String   Dim lNum    As String   On Error Resume Next   With TextBoxCtrl     If Len(.Text) > 0 Then       lPeriodPos = InStr(.Text, ".")       If lPeriodPos > 0 Then         lNum = Left$(.Text, lPeriodPos - 1)         sNum = Mid$(.Text, lPeriodPos)       Else         lNum = .Text       End If       .Text = FormatNumber$(lNum, 0, vbTrue, vbFalse, vbUseDefault) & sNum     End If   End With End Sub

shunshun-dash
質問者

お礼

KenKen_SP さん。ありがとうございます。 私はまだまだ未熟ですので、このコードを全て読みこなすことはできませんが、確かに電卓になりました。とりあえずテキストボックス入力中にリアルタイムで3桁区切り表示されればよかったのでChangeイベントで解決したのですが、KenKen_SPさんからご教示いただいたコードは本当に電卓みたいですね! ところで、「クラス」って初めてなのですが、簡単に言うとどのような利用の仕方をするものなのでしょうか? VBAって本当に奥が深いですね。私のような未熟者でもVBAをはじめてから仕事のスピードが10倍になりました。

全文を見る
すると、全ての回答が全文表示されます。
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんばんは。 Form では、Enter を押して、確定するというように、私はずっと通してきていますが、そうでないなら、TextBox1_Change()です。電卓画面とか、私には良く分かりませんので、どちらがよいかは、お決めください。また、そういう好みの問題は、ご自身でお調べくださったほうがよいと思います。

shunshun-dash
質問者

お礼

ありがとうございます。 Changeイベントで解決しました。今後はイベントの種類も勉強していきたいと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんばんは。Wendy02です。 私だったら、こんな風にしますね。Enter で起動します。 Change イベントだとうっとうしく思いますので。 Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If KeyCode = 13 Then  TextBox1.Text = Format(TextBox1.Text, "#,##0") End If End Sub

shunshun-dash
質問者

お礼

ありがとうございます。 これだと入力後Enterキーを押さないと3桁にならないですね。 あと、イベントを利用するのではなくて、テキストボックスへ入力中にリアルタイムで3桁区切りになる方法は無理なものでしょうか?電卓画面の感覚で入力を希望しています。

全文を見る
すると、全ての回答が全文表示されます。
  • myCat
  • ベストアンサー率60% (9/15)
回答No.1

こんばんは。 AfterUpdateイベントやExitイベントで。。。 Private Sub TextBox1_AfterUpdate() TextBox1.Text = Format(TextBox1.Text, "#,##0") End Sub   以上です。

shunshun-dash
質問者

お礼

ありがとうございます。 イベントを利用すればよかったですね。 ところで、一番の希望していた形としてはテキストボックスへ入力中(リアルタイム)で3桁区切りになる方法はないものでしょうか?それは無理ですかね?電卓に入力している感覚で。 やはりイベントを利用するとなると_AfterUpdate後でないと3桁区切りにならないので。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ExcelVBAでセルをクリックしてユーザーフォームを表示するには

    OfficeExcel2003を使用しています。 ユーザーフォームのテキストボックスやコンボボックスに文字や数値を入力し、OKボタンを押せばエクセルのセルに記入できるようにしようと思ってます。 フォームはなんとか(形だけですが..)作成できたのですが、そのフォームを呼び出す方法として、入力したい行のA列のセルをクリックすればユーザーフォームが表示されるようにしたいのです。 ネット上でいろいろ検索してみましたがなかなか見つけることができませんでした。 初歩的な質問かもわかりませんが、教えて頂けないでしょうか。 宜しくお願い致します。

  • VBAユーザーフォームで

     エクセルVBAでユーザーフォームより、テキストボックスで入力させたものをセルに表示させようとしています。  テキストボックスは1と2があり、テキストボックス1で入力した値の最初の5文字+固定値をテキストボックス2に自動で入力(表示)したいのですがなかなかうまくいきません。(自動入力後、手動で一部修正します。)  VBAをはじめたばかりの初心者ですが、どうぞよろしくお願いします。

  • エクセルのユーザーフォームについて

    エクセルマクロのユーザーフォームのテキストボックスに セルの値を表示する方法で質問です。 ユーザーフォームを表示するとその時点での セルの値はテキストボックスに表示されているのですが ユーザーフォームを表示したまま 別のブックのセルを選んだ際に そのセルの内容がテキストボックスに表示されるようにしたいです。 ボタンや、なにかをするわけではなく 自分で任意のセルを選択したら、という事です。 ユーザーフォームには selectionchange などがないのでどうすれば良いかわかりません。 宜しくお願いします。

  • 【VBA】ユーザーフォームから、シート上のテキストボックスを操作

    ユーザーフォームで入力した値を、シート上にあるテキストボックスに入力させたいのですが、 どのように記述すればいいのでしょうか?(ボタンで操作) またおなじくテキストボックスの大きさ、フォントの大きさ、などを操作するにはどのようにしたらいいですか?

  • ユーザーフォームについて

    エクセル2002です。 ユーザーフォーム内のテキストボックスを使用して、 (1)A1のセルに1と入力されている状態でマクロを起動した場合、 (2)ユーザーフォーム内のテキストボックスには2と表示される (3)ユーザーフォーム内のボタンを押すと、A2のセルに2と入力される。 このような流れで、A列のデータ最終行に番号をふっていきたいです。 (A列のデータ最終行がA30なら、A31に31と番号をふる) ユーザーフォームのテキストボックスとボタンは作ってあるのですが、 それぞれに入れるコードを教えていただけないでしょうか。 よろしくお願いします。

  • ユーザーフォームのテキスト印刷

    ユーザーフォームでテキストだけ印刷させる方法はありますか? ユーザーフォームに何箇所か入力するリストボックス、テキストボックスなどがあり、すべてを入力した後、最後にエクセルに登録するようなフォームなのですが、登録する前にそれらを印刷できればと思います。 登録したエクセルを印刷してもいいんですが、他の情報とかがあるのでユーザーフォームだけを印刷したいです。また、ユーザーフォームをそのまま印刷するとよけいな装飾なども印刷されトナーがもったいないのでそれもしたくはありません。 宜しくお願いします。

  • ExcelVBA テキストボックスについて

    フォーム上100個のテキストボックスがあります このテキストボックスに入力制限を加えたいのですが、どのように書けばよろしいでしょうか?  ・半角数字だけしか入力できない(計算に使う)  ・入力すると、1,234,567のような表示になり、右詰め  ・10桁までしか入力できない  ・予定の計算結果だと、10億を超えない  ・計算結果は数字が入力されるたびLabel1に表示される 私の作ったマクロだと、全てのテキストボックスに同じようなマクロを登録する結果になってしまい、これってもっと短くかけるのでは?と思い、質問いたしました よろしくおねがいします

  • ユーザーフォームで数字にカンマを付けたい

    今EXCEL2003を使用しています。 ユーザーフォームのテキストボックスに数値を入力した際 例えば1000→1,000のように自動で千単位でカンマを表示させる事は可能でしょうか?

  • ユーザーフォームのテキストボックスに配列の値を読み込む方法を教えて下さい

    お世話になります ユーザーフォームのリストボックスにAddItemで記述したデータを表示するような形で、ユーザーフォームのテキストボックスに配列にとりこんであるデータの値を順番に読み込むようにしたいのですが、このようなことができるのでしょうか? どなたか教えて頂けないでしょうか

  • ExcelVBA ユーザーフォームに関しての質問です。

    ExcelVBA ユーザーフォームに関しての質問です。 ユーザーフォームでフレームを使って、 フレーム内に複数のチェックボックスを配置したとします。 行いたい作業としては次の2点 ?フレーム内に配置したチェックボックスのうち、チェックが入っているものだけの数を調べる ?チェックが入っているボックスの値(caption)を取得して、変数に入れる 以上のことができるでしょうか?

専門家に質問してみよう