「栄養計算ソフトにユーザーフォームを導入しよう」の連載第5回です。
以下の記事の続きになります。
前回は,リストボックスに食品群ごとに食品を表示する処理を実装しました。今回は,食品をシートに追加する際の処理を見直し,もっとスムーズに追加できるようにしていきます
では行きましょう。
食品入力時の問題点
はじめに,現在実装している食品入力機能の,実際に行う際の問題点を列挙します。
アクティブセルが変更できない
まず第一の問題点はこれです。フォームを開き,食品を入力していく際に,アクティブセルを変更することができません。
現在の仕様では,アクティブセルのある行に食品番号は入力されます。しかし,フォームを開いた状態では,アクティブセルを変更できないので,違う場所に食品番号を入力したければ,一度フォームを閉じなければなりません。これでは非常に不便です。
連続して食品入力できない
次の問題点は,連続した食品入力ができないという点です。
これは1番目の問題点とも関連していますが,今の仕様では,食品を入力した後,アクティブセルが移動しません。そのため,食品を続けて入力しても,最初に選択したアクティブセルが上書きされるだけで,連続した食品入力ができません。これでは多くの食品を入力するのは難しくなります。
食品番号以外の場所に入力してしまう
次の問題点は,食品番号以外の場所に,食品を入力してしまうという点です。現在の設定では,アクティブセルのある行に食品番号が入力されるため,たとえば誤って項目行のある行をアクティブにしてしまった場合には,その行に食品番号が入力されてしまいます。以下のような状態ですね。
これでは,せっかく作ったフィーマットが崩れてしまいかねません。
問題点を解消していこう
では,順番に問題点を改善していきましょう。
アクティブセルを変更できるようにしよう
まずはアクティブセルを変更できるようにしていきましょう。
これの解消法は,フォームを,モードレスで開くということです。
フォームの表示法には,モーダルとモードレスがあります。
通常のフォームの表示にはモーダルが用いられます。モーダルは,モードがある状態を意味し,機能が制限された状態を意味します。つまり,フォームをモーダルで開いた場合は,機能がフォームでできることに制限されます。そのために,アクティブセルを変更することができません。
それに対して,フォームをモードレスで開いた場合は,機能が制限されません。つまり,フォーム以外の機能を使うことができるようになり,アクティブセルの変更も可能になります。
そのため,アクティブセルを変更したい場合には,フォームをモードレスで開く必要があります。VBAの場合は,フォームのshowメソッドの引数にモードレスを指定することで行えます。栄養計算シートのコードを以下のように変更してください。
Private Sub CommandButton1_Click()
frmFoodGroup.show (vbModeless)
End Sub
Private Sub CommandButton2_Click()
frmSerch.show (vbModeless)
End Sub
それぞれのフォームをモードレスで開くうように設定しました。これで,アクティブセルの変更が可能になります。
食品入力→アクティブセルを1行下に
次は,連続した食品入力を可能にするために,食品を入力したらアクティブセルが1行下に移動するように設定しましょう。追加ボタンをクリックした際のコードを以下のように変更します。
Private Sub btnAdd_Click()
Dim foodNum As String
foodNum = Left(lstFood.Value, 5)
Cells(ActiveCell.Row, 2).Value = foodNum
ActiveCell.Offset(1, 0).Activate
End Sub
Offset関数を用いて,アクティブセルの1行下の行をアクティブにしています。これで,食品入力毎にアクティブセルが1行下に移動するので,連続した食品入力が可能になりますね。
項目行がアクティブだと警告をだそう
次は,食品番号を入力する行以外の場所に食品番号を入力してしまうことを防ぎましょう。食品を追加するボタンを以下のように変更しましょう。
Private Sub btnAdd_Click()
If ActiveCell.Row < 5 Then
MsgBox "項目行より下を選択してください", vbCritical, "注意"
Exit Sub
End If
Dim foodNum As String
foodNum = Left(lstFood.Value, 5)
Cells(ActiveCell.Row, 2).Value = foodNum
ActiveCell.Offset(1, 0).Activate
End Sub
アクティブセルの行が5未満(項目行)の場合に,メッセージを表示しています。また,それより下のコードが実行されないように,Exit sub で処理を抜けています。
こうすることで,以下のようなアラートが表示され,処理を中断させることができます。
まとめ
今回は,食品入力スムーズにするために,何点かの問題点を解消しました。次回は,現在のコードを少し改善し,読みやすく・メンテナンスのし易いコードにしていこうと思います。