Microsoft Access 掲示板

モジュールでカレントフォームのコントロールを使うには

6 コメント
views

お世話になります。入力フォームに日付フィールドがありそれを+-ボタンで加算しています。複数のフォームを同様にしてますので、コードを共通化したいと思い下記のコードをモジュールに記述しました。

 Function AddDt(taDt As Variant,reqNum As Integer)

  '対象日付の加算をする(+1,-1)。※reqNumで処理を分ける
    
      If IsNull(taDt) Or IsDate(taDt) = False Then  '対象日付がNULL、日付型ではない場合は抜け出す
          Exit Function
      End If
   
      Dim foName As String
      foName = Screen.ActiveForm.Name  

      With  Forms(foName).Controls(taDt)
           Select Case reqNum 
                  Case 1
                        .Value = DateAdd("d", 1, .Value)  '対象日付に1日プラス
                   Case -1
                        .Value = DateAdd("d", -1, .Value)  '対象日付に1日マイナス
               Case Else
                        Exit Function
          End Select
        End with
      
End Function

そしてフォームからボタンクリック時にCALLで呼び出すと ”実行時エラー2458 コントロールの数よりも大きな番号になっている” となります。なにかが足りないと思いますがそれが解決できません。アドバイス宜しくお願いします。

kameo
作成: 2026/03/18 (水) 09:55:31
通報 ...
1
sk 2026/03/18 (水) 11:06:35 修正 97383@4e51d
Forms(foName).Controls(taDt)

上記のコードは、Controls オブジェクト/コレクションの既定のプロパティである Item の記述を省略したものです。
Item プロパティの引数 Index に渡すことが出来るのは、次のいずれかです。

  1. 参照したいコントロールの番号を示す整数

  2. 参照したいコントロールの名前を示す文字列

引数 Index に整数(番号)を渡す場合、その最小値は 0、最大値は Controls コレクションに含まれるコントロールの総数から 1 を減じた結果です。

Function AddDt(taDt As Variant,reqNum As Integer)

そして例示されたコードでは、Controls.Item プロパティの引数 Index に対して AddDt プロシージャの引数 taDt を渡しているわけですが、

If IsNull(taDt) Or IsDate(taDt) = False Then

もし Variant 型の引数 taDt に渡されたのが Date 型のデータである場合、Controls.Item プロパティの引数 Index にそれを渡した際、暗黙的に整数データに型変換され、上記 1 のケース(番号を渡す)として処理されます。

例えば、渡された Date 型の値が #2026/03/18# だった場合は 46099 という整数に置き換わります。

実行時エラー2458 コントロールの数よりも大きな番号になっている

この時、渡された整数が Index に渡すことのできる番号の上限(フォーム上に配置されている全てのコントロールの数から 1 を減じた結果)を超えていれば、実行時エラー 2458 (正しいメッセージは「コントロールの数よりも大きなコントロール番号が指定されています。」)が発生することになります。

つまり、コントロールを参照するための引数(番号または名前)に対して Date 型のデータを渡していることがまず誤りである、ということです。

入力フォームに日付フィールドがありそれを+-ボタンで加算しています。

複数のフォームを同様にしてますので、コードを共通化したい

「日付フィールド」が連結コントロールであるか否か、「+-ボタン」のコントロールの種類は何か、といった要件等によりますが、恐らく標準モジュールよりクラスモジュールを使用した方が良いケースではないかと思います。

2

エラーの原因はskさんからの指摘通りだと思います。


入力フォームに日付フィールドがありそれを+-ボタンで加算しています。複数のフォームを同様にしてますので、コードを共通化したいと思い下記のコードをモジュールに記述しました。

上記の要件の場合、私は下記のようなFunctionを標準モジュールにおいて利用してます。

Function AddDt(ctDt As Control, reqNum As Long)
    
    If IsDate(ctDt.Value) = False Then  '対象コントロールの値が日付型ではない場合は抜け出す
        Exit Function
    End If

    ctDt.Value = DateAdd("d", reqNum, ctDt.Value)  '

End Function

+ボタンの「クリック時」プロパティに下記のように設定

=AddDt([日付テキストボックス], 1)

+ボタンの「クリック時」プロパティに下記のように設定

=AddDt([日付テキストボックス], -1)

これならフォームモジュールにコードを書く必要はないです。
もしフォームモジュールからCallしたいということなら

Private Sub DateAdd_Click()
    Call AddDt(Me.日付テキストボックス, 1)
End Sub
3
kameo 2026/03/18 (水) 12:48:55 9eaf4@2128d

sk様・hatena様 ありがとうございます。なるほどそういう事なのですね。
hatena様のコードで機能しました。それで教えて頂きたいのですが  Call AddDt(Me.日付テキストボックス, 1) のMe.***部を変数にするとエラーになるのは何故でしょうか? Dim dt As Control で宣言して dt=Me.日付テキストボックスとして Call AddDt(dt, 1) を実行するとエラー。変数使わなければエラーになりません、それが不思議で。(多分私がsk様の内容をなんとなくでしか理解してないと思いますが・・・)

4

VBAの変数には値変数とオブジェクト変数があります。
前者は数値や文字列などの値を格納します。
後者はフォームやコントロールなどのオブジェクトを格納します。

オブジェクト変数に代入するときはSetステートメントが必要になります。

    Dim dt As Control
    Set dt = Me.日付テキストボックス
5

Dim dt As Control で宣言

  • 変数 dt をどこで宣言しているのか。

dt=Me.日付テキストボックスとして

  • 上記のステートメントをフォームモジュールのどのイベントプロシージャで実行しているのか。

  • そのフォームモジュールのモジュールレベルには Option Explicit ステートメントが記述されていないのか。

Call AddDt(dt, 1) を実行するとエラー。変数使わなければエラーになりません

  • AddDt プロシージャをフォームモジュールのどのイベントプロシージャ内で呼び出しているのか。

  • 発生しているのは実行時エラーコンパイルエラーのどちらなのか。

  • そのエラーが発生した際にどのようなメッセージが表示されるのか。

以上の点について明記されることをお奨めします。

6
kameo 2026/03/18 (水) 14:51:24 9eaf4@2128d

hatena様ありがとうございました。変数のそんなルールがあったのですね。Setで問題なく出来ました。
sk様 情報不足ですみません。変数dtは実行ボタンのクリック時イベントで宣言してます。 Option Explicitは記述しています。エラーは実行時です。実行時エラー91 オブジェクト変数またはWITHブロック変数が設定されていない の内容でした。