【TextBox1】
Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger) If KeyAscii < Asc("0") Or KeyAscii > Asc("9") Then
KeyAscii = 0 Beep
End If End Sub
なお、前回の記事でIF 条件式がわかりにくいとの指摘があったので、そちらを再度、説明しましょう。
まず、上のプロシジャでKeyAscii という変数が現われます。この変数は最初に Private Sub...文のかっこ書き部分
に出て来ています。これは、VBA のシステムが KeyPress イベントの発生時(なにかキーを押したとき)に、ユーザー が実際に押したキーを認識し、そのキーのAscii コード(整数)を KeyAscii という変数に代入してくれることを表して います。 したがって、(特殊なキーを除いては)数値以外のキーでもすべて押したキーのコードがKeyAscii 変数に取り込ま れます。(少なくとも印刷可能文字はすべて取り込まれます。) この場合、数値以外は入力させたくないので、If 条件文で「0」未満、「9」を超える数値が押された場合には無効処 理をさせます。 それがKeyAscii=0で、この文によって押されたキーを無効にすることができます。
なお、ASC( )はカッコの中の文字(数値)を Ascii コードに変換するための関数です。これにより、KeyAscii 変数と 比較できるようになります。(基本的に条件式では方が同じでないと比較できません。)
数値0 が Ascii コードで 46 で、順に数値 9 は 57 に割り当てられていますので、次のような書き方でも書けないこと
はありません。
If KeyAscii < 48 Or KeyAscii > 57 Then
ただ、あとからこのコードを見た場合、これらのコードが何のキーであるかがわかりにくいので、あえてAsc()関数を 使い、変換前の文字を記述しておくのが一般的です。もちろんAsc("0")は 48 をあたえ、Asc("9")は 57 をあたえま す。(そこにコメントを加えておく場合、話は別ですが...。) さて、今日の課題分に入ります。 ワークシート内の特定のセルがクリックされた場合に、フォームを開くというプロシジャは、WorkSheet オブジェクト に記述します。 WorkSheet オブジェクトはプロジェクトエクスプローラで確認してください。
上の図がプロジェクトエクスプローラです。通常、VisualBasicEditor 画面の左上に配置されています。
Microsoft Excel Objects(ワークシート)、フォーム、標準モジュール、クラスモジュールなどに分かれていて、そ れらの集まりをプロジェクトといいます。
Excel のワークシートは新規作成すると自動的に3つのワークシートができますが、そのシートが VBA では自動的 にオブジェクトとみなされます。
今回、使うのはSheet1 ですので一番上の Sheet1(Sheet1)を使います。(かっこ内は Excel におけるシート名で E
xcel のシート名を変えればここも変更されます。かっこ外の名前も Visual Basic Editor のプロパティウィンドウで なら変更できますが、慣れないうちは変えない方がわかりやすいと思います。) まず、Sheet1(Sheet1)をダブルクリックしてください。 Sheet1 にコードが記述されていれば、コードウィンドウに Sheet1 に関するコードが現われます。新規のプロジェク トの場合、何も表示されません。 このコードウィンドウには2つのプリセットがあります。「オブジェクト」と「プロシジャ」です。 選択はコードウィンドウの上部のセレクトボックスで行います。 上の図で(General)と Worksheet を選択するセレクトボックスが、「オブジェクト」の選択です。そして、内容は隠れ ていますが、右に配置された(Declarations)側が「プロシジャ」の選択です。プロシジャの選択ではイベントハンドラ を選びます。 先にも書きましたように今回のケースではWorksheet に記述するので図のように Worksheet を選びます。(上の
図ではセレクトボックスの下側に既にコードが表示されていますが、実際には何も表示されていません。) 今回の課題で「ある特定のセルを選んだとき...」とあるので、(Declarations)側では、「SelectionChange」を選 びます。(順序は必ず「オブジェクト」→「プロシジャ」の順に選択してください。オブジェクトに固有のプロシジャがあ るので、順逆だとプロシジャを選択できません。) 「SelectionChange」はセルの選択範囲が変わったときに発生するイベントです。実質上、特定のセルをクリックし たときにも1つのセルを選択したとみなされ発生します。(WorkSheets オブジェクトには上の図のように Click イベ ントは存在しません。) オブジェクトとプロシジャを選択すると、自動的に次のようなプロシジャが表示されます。(この部分は定型句です。)
Private Sub Worksheet_SelectionChange(ByVal Target As Range) (この部分に自身でコードを書いていきます) End Sub 考え方は、KeyPress と同様です。ただし、KeyPress ではキーが押されたときに該当のプロシジャが実行されました が、SelectionChange では選択範囲が変更されたときに実行されます。 今回のコードは次のように記述します。
【
Worksheet】 (
オブジェクト名worksheet1)
Private Sub Worksheet_SelectionChange(ByVal Target As Range) If (Target.Row = 1 And Target.Column = 1) Then
UserForm1.Show End If
End Sub
このプロシジャではワークシートでセル範囲を選択すると、先のKeyAscii 変数と同様に、その範囲(Range)が Tar
get という特殊なオブジェクト型変数に読み込まれます。 この変数はRow(行)と Column(列)というプロパティを持っていますのでそれらを使います。 上の条件式で、Row が「1」なのは1行目であることが想像できるでしょうが、Column で 1 列目を表示する場合にも 「1」で表現するのでご注意ください。なぜなら、Excel のワークシートでは「A1」など、列はアルファベットで表示して いるのでご注意ください。 つまり、上のIf 文は「選択範囲の行が1列目でかつ列が1列目であればUserForm1 を開きなさい。」ということにな
う意味になります。
他の選択範囲を選んでもUserForm1 は開きませんが、該当のセルが左上先頭である選択である場合に限り、それ
より広い範囲を選択してもフォームは開きます。
UserForm が開かれた時点で、次のコードを用いて TextBox1 を初期化します。
【
UserForm】
privete sub UserForm Activate() TextBox1.Text = ""
End sub
これはUserForm が Activate(活動的)になったら実行されるイベントプロシジャです。つまり UserForm が使われ
るようになったら発生するイベントです。 この文を要約すれば、「入力フォームが読み込まれたらテキストボックス(TextBox1)を初期化せよ」となります。As c()関数の引数でもあったように、2つの「"」に囲まれた文字は VBA では文字列をあらわしますが、この場合、その 間に何もないので、結果、TextBox1 に空白(厳密には違います)が代入されます。 最後に入力フォームのテキストボックスで入力した数値をワークシートに転記するコードを記述します。 先に記したようにKeyPress イベントが発生するとほとんどのキーコードが KeyAscii 変数に取り込まれますが、例外 があり、それが「Enter」キーや「Esc」キーなどの特殊キーです。 つまり、KeyPress イベントでは「Enter」キーが押されたことを認識することができないのです。 そのため、「Enter」キーや「Esc」キーのキーコードを取り込める KeyDown イベントプロシジャを用います。
【
UserForm】
Private Sub TextBox1_KeyDown(byVal KeyCode as Msforms ReturnInteger, ByVal Shift as Integer)
If KeyCode = vbKeyEscape Then UserForm1.Hide
Exit Sub End If
If KeyCode = vbKeyReturn And TextBox1.text <>"" Then Worksheets("Sheet1").Activate Worksheets("Sheet1").Range("A1").value = TextBox1.Text Worksheets("Sheet1").Range("A2").Activate UserForm1.Hide Exit Sub End If End Sub
KeyPress イベント同様に、押されたキーのコードが変数に取り込まれますが、KeyDown では KeyAscii 変数では
なく、KeyCode 変数です。変数名は異なりますが、ほぼ同じようなものと考えて差し支えありません。
このプロシジャはTextBox1 内で「Esc」キーを押すとフォームが閉じられ、入力がキャンセルされます。
を書き込み,UserForm を閉じます。 TextBox1.text<>""はテキストボックスが空白でなければということです。 Worksheets("Sheet1").Range("A2").Activate はフォーカスを別のセルに移すためのコードです。これがないと、 A1 セルにフォーカスが残り、そのまま通常の Excel のセルとして内容を書き換え可能となってしまうからです。(ここ では"A2"にしてありますが、使っていないセルならどこでもかまいません。これにより、再度、A1 セルをクリックして もSelectionChange プロシジャが実行され、直接、セルを書き換えることはできません。
vbKeyEscape や vbKeyReturn は VB 定数で「ESC」キー、「Enter」キー、それぞれのキーコードが入っています。 (定数ですので変更はできません。) ※Key イベントは KeyDown、KeyPress、KeyUp の3種類があります。 キーを押し下げたときにはKeyDown、KeyPress、そして、押したキーを離したときには KeyUp のそれぞれのイ ベントが発生します。 何かのボタンを押したときには、この3種のイベントがすべて発生し、イベントプロシジャもコードが存在すればす べて実行されます。 イベントの発生順序としてはKeyDown→KeyPress→KeyUp の順になります。 ただし、キーを押したまま離さないでいると、KeyDown イベントと KeyPress イベントが交互に繰り返し発生しKe yUp イベントは発生しません。キーを離すと その時点で KeyUp イベントが発生します。