1−6 セル位置を指定しての処理

コンボボックスの内容を選択すると、カーソルのあるアクティブなセルにその値が書き込まれるまでの処理を作成してみました。ところで、この処理なのですが アクティブなセルがどこにあるかに関係なくデータを変更してしまいます。これでは 間違った位置にデータを書いてしまうことを心配しながら値の入力をしなくてはなりません。
誤動作を防ぐ為には、処理を行おうとする前にアクティブなセルがB列にあるという確認をする必要があります。さて アクティブなセルの列はどうやって調べるのでしょう。ここではActivecellのColumnプロパティを利用使用してみます。
はじめに、Activecell.Columnの値がB列(2列目)でない場合、警告メッセージを出して処理を中断させます。具体的に言うと

If ActiveCell.Column <> 2 Then
    MsgBox "内容の列を選択してから、処理を開始してください", vbQuestion + vbOKOnly, "確認して下さい"
    Exit Sub
End If図1−6−1

というコードを追加します。これを追加しておくと、B列以外がアクティブになっていると 警告のメッセージを出してくれます。(Msgboxの1つ目のパラメータが表示する内容、2つ目のパラメータで表示されるアイコンとボタンの種類とその動作、3つ目のパラメータでは表示されるダイアログのタイトルを指定します。なお、詳しい使い方は ヘルプを参照してみてください)。Ifはもし何々なら〜という判定を表します。Exit Subを使うと、以下のコードが実行されませんので、警告を発生させて処理を中止することが可能です。
同様なやり方で、アクティブなセルが2行目以下にあるという判定を挿入する事が出来ます。この場合には、ActivecellのRowプロパティを用いて、If Activecell.Row<3 Then という判定をし その後のメッセージと動作を規定します。

次に、既にアクティブなセルに値が入力されている場合を考えてみましょう。この場合には、上書きして良いかどうかの判定が必要ですよね。ActiveCell.Valueは、値の代入と値の取得が可能ですので、この値を事前に取得して 何か書かれていた場合には 警告メッセージを出して 上書きして良いかどうかの判定をするようにしましょう。コードは以下のようになります。

Sub ドロップ1_Change()
' ドロップ1_Change Macro
    Dim Ret As Long

If ActiveCell.Column <> 2 Then
    MsgBox "内容の列を選択してから、処理を開始してください", vbQuestion + vbOKOnly, "確認して下さい"
    Exit Sub
End If
'
If ActiveCell.Row < 3 Then
    MsgBox "3行目以降の行を選択してから、処理を開始してください", vbQuestion + vbOKOnly, "確認して下さい"
    Exit Sub
End If
'
If ActiveCell.Value <> "" Then
    Ret = MsgBox("データが既に入力されています" & Chr(13) & Chr(10) & "上書きしますか?", vbExclamation +     vbYesNo, "上書きの確認")
    If Ret = vbNo Then Exit Sub
End If
'
ActiveCell.Value = Worksheets("DB").Range("B2").Value

End Sub

図1−6−2ActiveCell.Valueの値が””(つまり何も入力されていない状態)で無いなら−逆に言えば何か既に入力されていたら、上書きするかどうかの確認メッセージを表示させます。
この例のMsgboxの使い方は 上の2つの例と違います。どのような処理をするかの判定を行う為、「はい」か「いいえ」を選べるようにし どちらを選んだのかをRetという変数に引渡しています。この使い方の場合にはMsgbox関数と呼びます。(関数は 何らかの値を返す処理です。詳しい説明は次回行います)
Ret変数には 「はい」を選択したのか「いいえ」を選択したのかの結果がVbyesかVbnoという値で返されていますので これを利用し、Vbnoの場合にはマクロを中断させています。(なお、メッセージの途中に「 & Chr(13) & Chr(10) & 」という文字が挿入されています。これはメッセージを改行させて 2段に表示することを宣言しています。Dim Ret As Longの部分も次回に解説します)。このようにすると、誤って入力する事を防止できますので より以上に使いやすくなります。

今回はさらに、値が入力された時、自動的に当日日付を設定する事もやってみましょう。マクロの記録を使用し、相対参照でB3のセルからA3のセルへアクテイブセルを移動させてみましょう。この時には

ActiveCell.Offset(0, -1).Range("A1").Select

という行が作成されています。B3のセルがアクテイブセルの時、コンボボックスの値を変更すると、B3に選択した内容が書き込まれます。この時、上のコードによってA3のセルがアクテイブとなります。そこで、日付のセルに移動して当日日付を返すDate関数を使用して 日付を設定すます。
次に、残高の列に移動させ残高=前の残高+入金−出金という計算式を書き込みます。その後で、出金の列へ移動させます。実際のコードは以下のようになります。図1−6−3

ActiveCell.Offset(0, -1).Range("A1").Select
ActiveCell.Value = Date
ActiveCell.Offset(0, 4).Range("A1").Select
ActiveCell.FormulaR1C1 = "=R[-1]C+RC[-2]-RC[-1]"
ActiveCell.Offset(0, -1).Range("A1").Select

相対参照を使用してマクロを記録させると、上のような形でマクロが作られます。ActiveCell.Offset(行、列)という形式で処理すべきセルを 現在アクティブなセルからの位置で求め、Rangeプロパティでカーソルを移動させます。(これは、実際にアクテイブセルが移動しています。この点に注意してください)。そのセルに対して値を設定するわけです。
ActiveCell.FormulaR1C1は 計算式をR1C1形式で作成する為のものです。この部分もマクロの記録で記録されますので このまま利用します。

このように、「マクロの記録」と「相対参照」を使用し さらにマクロの内容に若干の手を加える事で、かなり使いやすい形ができあがります。

戻 る