【ExcelVBA】ユーザーフォームにエラー処理を実装しよう!【ユーザーフォーム】

Excel

「栄養計算ソフトにユーザーフォームを導入しよう」の連載第5回です。

以下の記事の続きになります。

【ExcelVBA】オプションボタンから動的にリストボックスの内容を変更しよう!【ユーザーフォーム】
「栄養計算ソフトにユーザーフォームを導入しよう」の連載第4回。ExcelVBAのユーザーフォームを栄養計算ソフトに導入します。今回は、オプションボタンを変更するとリストボックスの内容も動的に変更されるという処理を実装したいと思います。

前回は、リストボックスに食品群ごとに食品を表示する処理を実装しました。今回は、食品をシートに追加する際の処理を見直し、もっとスムーズに追加できるようにしていきます

では行きましょう。

食品入力時の問題点

はじめに、現在実装している食品入力機能の、実際に行う際の問題点を列挙します。

アクティブセルが変更できない

まず第一の問題点はこれです。フォームを開き、食品を入力していく際に、アクティブセルを変更することができません。

現在の仕様では、アクティブセルのある行に食品番号は入力されます。しかし、フォームを開いた状態では、アクティブセルを変更できないので、違う場所に食品番号を入力したければ、一度フォームを閉じなければなりません。これでは非常に不便です。

連続して食品入力できない

次の問題点は、連続した食品入力ができないという点です。

これは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 で処理を抜けています。

こうすることで、以下のようなアラートが表示され、処理を中断させることができます。

 

まとめ

今回は、食品入力スムーズにするために、何点かの問題点を解消しました。次回は、現在のコードを少し改善し、読みやすく・メンテナンスのし易いコードにしていこうと思います。

 

連載目次

  1. ユーザーフォームを始める最初の1歩
  2. フォームを設置→開くをやってみよう!
  3. リストボックスからシートに食品を追加してみよう!
  4. オプションボタンから動的にリストボックスの内容を変更しよう!
  5. ユーザーフォームにエラー処理を実装しよう!
  6. コードを読みやすいリーダブルコードに改善しよう!
  7. 食品成分表から検索→食品入力をしてみよう!
  8. 栄養計算ソフト+ユーザーフォームの完成!DLも可