Access VBAのイベント共有について

このQ&Aのポイント
  • Access VBAのイベントを共有化する方法を学びたい。
  • クラスモジュールについて基礎から勉強しなければならない。
  • フォーム上のラベルの背景色をマウスカーソルが乗った時に変えるコードを効率的に実現したい。
回答を見る
  • ベストアンサー

Access VBAのイベント共有について

こんにちは。 初めて質問をさせて頂きますcimappleと申します。よろしくお願いいたします。 現在、業務にて使用するデータベースをAccessにて作成しておりまして、VBAにてフォームの各処理を記述しています。 ちなみに、当方Access、VBAについて超初心者ですので、そもそもの誤解がある部分もあるかと思いますが、ご容赦ください。 さて、質問の内容ですが、今回フォーム上にある14個のラベルを、マウスカーソルが乗った時(MouseMoveイベント)にそのラベルの背景色を変えるコードを組みたいと考えています。 現状としては、それぞれのラベルのMouseMoveイベントに背景色を変えたり、戻したりといったコードを記述していますが、当然非効率かつ面倒なのです。 そこで、このイベントを共有化したいと考え、いろいろと検索したところ、クラスモジュール(Private WithEvents)にてそういったことができそう・・・というところまでは辿り着いたのですが、その先が全く分かりません。 Excelについてのクラスモジュールの記事はたくさん見つけて、コピーペースト見よう見まででマネてはみたのですが、当然うまくいかず、そこから先に進めないでおります。 クラスモジュールについて基礎から勉強しなさいと言われればその通りなのですが、どうかお知恵をお貸し頂きたく質問させていただきました。 よろしくお願いいたします。 以下、見よう見まねの現在のコードです。 ちなみに、フォーム名はFRM1、ラベル名はそれぞれLbl○、クラスモジュール名はCLS1となっています。 Form(FRM1)のコード ======================================================= Option Compare Database Option Explicit Dim MyLbl(14) As CLS1 Private Sub Form_Load() Dim Lbl As Access.Label Dim i As Integer For i = 1 To 14 Set Lbl = Me.Controls("Lbl" & i) Set MyLbl(i) = New CLS1 Set MyLbl(i).Label = Lbl Next End Sub ======================================================= Class(CLS1)のコード ======================================================= Option Compare Database Option Explicit Public WithEvents Label As Access.Label Private Sub Label_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) Label.BackColor = 225 End Sub ======================================================= 長文かつ駄文で申し訳ありませんでした。

質問者が選んだベストアンサー

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.1

とりあえずラベル2個だけ。Acc2010で試しています。 先日、帳票フォームのテキストボックスのクリックイベントを、テキストボックス名を決め打ちしないで汎用的に処理したいと悩みまくったところですので、若干のアドバイスをさせていただきます。ご参考まで。 ☆フォームモジュール Private MyLbl(2) As Class1 Private Sub Form_Load() Dim Lbl As Access.label Dim i As Integer For i = 1 To 2 Set Lbl = Me.Controls("Lbl" & i) Set MyLbl(i) = New Class1 Set MyLbl(i).label = Lbl Next End Sub ☆クラスモジュール 'Publicだとエラーになる '変数名がlabelだと、コントロール名と重なって変なエラーになると嫌なので変更 Private WithEvents myLabel As Access.label 'このプロパティのセット部が欠落-クラスモジュールの理解不足 Public Property Set label(newLabel As Access.label) Set myLabel = newLabel 'Accessではこれの設定が必要 - 先日はまったところです myLabel.OnMouseMove = "[Event Procedure]" End Property '引数がVBEで自動生成されるものと違っていた Private Sub myLabel_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) myLabel.BackColor = 225 End Sub

cimapple
質問者

お礼

早速のご回答ありがとうございます!! mitarashi様のおっしゃる通りコードを記述したら、やりたいことができました! なるほど、プロパティのセットとは全然理解できておりませんでした。 "[Event Procedure]"の所も、全く理解できていませんが、どこかでそんな記事を見たような・・・という感じでした。 私にはやっぱりまだクラスを理解するには勉強が足りないと思いました。 大変勉強になりました! 今後もっとしっかり勉強します! 今回は本当にありがとうございました!! 助かりました。

関連するQ&A

  • ExcelVBAでユーザーフォームのイベント対応

    Excel2010です。ユーザーフォーム上に配置した6個のComboBox(1から6)があります。 それぞれのComboBox上にマウスポインターを当てた際、そこが選択されていれば(="名称" 以外であれば)同じユーザーフォーム上にあるLabel23に説明の文字を表示させたいのです。 以下のようにComboBox1からComboBox6までComboBoxの番号以外は全く同じコードを書けばそうできると思いますが、これをもっと簡単に書くことはできないでしょうか?教えてください。 あと、もう1点 下記のコードの変数(Button、Shift、X、Y)の意味と役割は何でしょうか? Private Sub ComboBox1_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) If Me.ComboBox1.Value = "名称" Then Exit Sub Me.Label23.Caption = Me.ComboBox1.Value & Range(Me.ComboBox1.ControlSource).Offset(, 9).Value End Sub 途中ComboBox 2から5は省略 Private Sub ComboBox2_MouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Single, ByVal Y As Single) If Me.ComboBox6.Value = "名称" Then Exit Sub Me.Label23.Caption = Me.ComboBox6.Value & Range(Me.ComboBox6.ControlSource).Offset(, 9).Value End Sub

  • VBで動的に作成したパネルの上にラベルを乗せるには?

    VB6にてプログラムで動的に作成したフレーム(Frame)の上に、動的に作成したラベル(Label)を乗せることが出来ません。 どうすれば、ラベルをフレームの上に乗せることが出来るようになるでしょうか? どなたか分かる方がいらっしゃいましたら、ご教授願います。 なお、フレームとラベルの作成は以下のようなやり方で行っています。 ' Form1 : 表示フォーム Private lbl As New LabelClass ' ラベル作成クラス Private frm As New FrameClass ' フレーム作成クラス Private Sub Form_Load() Call lbl.LabelMake(Form1, "lbl1") With lbl.makelbl .Caption = "テストラベル" .AutoSize = True .Top = 500 .Left = 500 .Visible = True End With Call frm.FrameMake(Form1, "frm1") With frm.makefrm .Caption = "テストフレーム" .Width = 2000 .Height = 2000 .Visible = True End With End Sub ' LabelClass : ラベル作成クラス Public WithEvents makelbl As Label Public Sub LabelMake(form As Object, name As String) Set makelbl = form.Controls.Add("VB.Label", name) End Sub ' FrameClass : フレーム作成クラス Public WithEvents makefrm As Frame Public Sub FrameMake(form As Object, name As String) Set makefrm = form.Controls.Add("VB.Frame", name) End Sub ※nameはオブジェクト名です

  • vbaのイベントについて質問

    vbaでマクロを組んでおります。 mouseupイベント、GetChartElementをもちいて散布図の中のグラフ要素の値を取得したいのですが、 これらのコマンドはグラフシートにしか適用できないでしょうか?グラフシートではうまくいくのですが埋め込みグラフに対して行うとうまくいきません。分かる方いらっしゃいましたら、お願いいたします。 クラスモジュールClass1にて↓ Public WithEvents myChart As Chart Private Sub myChart_MouseUp _ (ByVal Button As Long, _ ByVal Shift As Long, _ ByVal x As Long, _ ByVal y As Long) Dim ElemID As Long, Arg1 As Long, Arg2 As Long myChart.GetChartElement x, y, ElemID, Arg1, Arg2 Select Case ElemID Case xlSeries MsgBox ("データ系列") '⇒データ系列と認識されればメッセージボックスがでるはず Case Else MsgBox ("その他") End Select End Sub 標準モジュールに入力↓ Dim myClass As New Class1 Sub InitializeChart() Set myClass.myChart = ActiveChart End Sub

  • カレンダーの日付をTextBoxに表示するには?

     Access の VBA を最後に書いたのは18年前。でも、どうしても気になっていることがあって、今日、ちょっとクラスモジュールとやらに挑戦してみた。それは、添付図のようなカレンダーの日付ラベルをクリックしたら、”日”という名のテキストボックスに表示させるというもの。 【クラスモジュール】 Option Compare Database Public WithEvents accLabel As Access.Label Public accOutput      As Access.TextBox Public Sub Bind(xLabel As Label, xTextBox AS TextBox)   Set Me.accLabel = xLabel   Set Me.accOutput =xTextBox   accLabel.OnClick = "[EVENT PROCEDURE]" End Sub Private Sub accLabel_Click()   Me.accOutput = accLabel.Caption End Sub 【フォームのコード】 Option Compare Database Dim myMulti(37) As New Class1 Private Sub Form_Open(Cancel As Integer)   Dim I As Integer      For I = 1 To 37     myMulti(I).Bind Me.Controls(Format(I, "日付_00")), Me.日   Next I End Sub  一応は、これで目的を達したが・・・。今一、しっくりしない。ラベル一個ごとに書き込むテキストボックスを設定しない書き方があるように思えてしょうーがない。  当方、IT業界とは縁もゆかりもないど素人の爺(69歳8ヶ月)。その辺りを考慮されて、優しーく手ほどきの程をお願いします。 PS、マルチイベントで発生した値の受け渡しは懸案事項。  かって、同様のクラスモジュールを書いたことがあるが、その時も、値の受け渡しでは中途半端に終わった。まあ、もはや、どうでもよいことだが・・・。気になって、気になって

  • VBAのクラスのインスタンス化のタイミングについて

    こんにちはvbaのクラスのインスタンス化について質問があります。 私は普段使えないイベントを使用するときにクラスモジュールに WithEventsを使ってイベントを作成し それをプロシージャからインスタンス化して 作成したイベントを有効にするという手法をよく使います。 Excelのように最初からワークブックにイベントがある場合は、 ワークブックを開いたと同時にWorkbook_Openプロシージャから クラスをインスタンス化して作成したイベントを有効にするということが可能なのですが、 CATIAやInventorなど、一部のアプリケーションでは、 最初から使えるイベントが見つからず、 Subプロシージャでインスタンス化する方法しかみつかりません。 しかし、Subプロシージャを実行させるためには、 ボタンなどユーザー側に何らかのアクションとってもらうしかなく、 自動化するために作成したイベントなのに、そのイベントを有効にするために ユーザーにボタンを押してもらうという矛盾した構成になってしまいます。 クラスをインスタンス化する方法はSubプロシージャに記述するしかないのでしょうか? 自分がよく使っているコードを下に記述します。 下の例は、Excelで新しくブックを開いたときにメッセージを出すプログラムです。 アプリケーションレベルのイベントをクラスモジュールで作成しています。 これを有効にするためには標準モジュール内の Event_ONプロシージャを実行しなければなりません。 モジュールを実行する前まではいくら新しいブックを開いてもメッセージは出ません これをどのうようにしたらいいかご教授ください。 Excelの例 Classモジュール「Class1」に記述 -------------------------------------------------------------------- Private WithEvents APP As Application Private Sub APP_NewWorkbook(ByVal Wb As Workbook) MsgBox "新しいブックが開かれました" End Sub Private Sub Class_Initialize() Set APP = Application End Sub -------------------------------------------------------------------- 標準モジュール「Module1」に記述 -------------------------------------------------------------------- Dim CLS As class1 Public Sub Event_ON() Set CLS = New class1 End Sub --------------------------------------------------------------------

  • VBA書き込み数値の加算?

    エクセル2000のVBAにて下記のコードを書き込み コマンドボタン1にてエクセルに入力処理後 Label8数値の加算をエクセル関数SUNを使用して =SUM(E4:E1000)を行ったのですが、加算数値が0になってしまいます。 =E4+E5+E6・・・・だと加算した数値が表示されます。 (さすがにこれは避けたいです) 何か方法があると思いますが教えていただけますでしょうか? Dim i As Integer Dim k As Integer Private Sub CommandButton1_Click() With ActiveSheet For k = 4 To 1000 If .Cells(k, 1) = "" Then .Cells(k, 1) = TextBox1 .Cells(k, 2) = Label6 .Cells(k, 3) = Label7 .Cells(k, 4) = TextBox2 .Cells(k, 5) = Label8 TextBox1 = "" Label6 = "" TextBox2 = "" Label7 = "" Label8 = "" Exit Sub End If Next k End With End Sub Private Sub TextBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If KeyCode = 13 Then Label8 = Application.WorksheetFunction.Round(Val(Label7) * Val(TextBox2), 0) Label8 = Format(Label8, "#,##0") End If End Sub

  • VBAでクラス設定

    (標準モジュール) Option Explicit Sub test() Dim Class As Class1 Set Class = New Class1 Class.Obj = 1000 Set Class = Nothing Set Class = New Class1 Range("a1").Value = Class.Obj Set Class = Nothing End Sub (クラスモジュールClass1) Option Explicit Private a As Integer Public Property Get Obj() As Integer Obj = 2000 End Property Public Property Let Obj(ByVal NewNumber As Integer) a = NewNumber End Property 上のマクロではやり取り1変数になってますがこれを配列に変えたいのですがどうすればいいでしょうか?

  • 複数フォームへのイベントの通知方法について

    Visual Basic2005にてプログラミングをしております。プログラミング初心者です。 以下、どなたかご教授いただけませんでしょうか? あるクラスを定義し、そのクラスの1つのインスタントがイベントを出した時に、 フォーム1~フォーム3の各Formにイベントを通知する様なプログラムを作成しております。 複数フォームへのイベントの通知方法として、以下の様なやり方は一般的に正しいのでしょうか? プログラムを実行させて見ると、動作上は何の問題もなく動いている様に見えますが、 プログラミング経験が少ない事もあり、以下のやり方が本当に正しいのかどうか、あまり自信が持てません。 どなたかご教授いただけると助かります。宜しくお願い致します。 =================================================================================== 'クラスA Public Class classA   Public Event StatusChange(ByVal status As Integer)   Public Event MassageOutput(ByVal message As String)   Private status As Integer   Private Sub EventReport1()       status = 5       'statusの変更を通知するイベントを生成させる       RaiseEvent StatusChange(status)   End Sub   Private Sub EventReport2()       'メッセージを通知するイベントを生成させる       RaiseEvent MassageOutput("メッセージを通知します")   End Sub End Class 'モジュール Module moduleA   Public myInstance As New classA End Module 'フォーム1 Public Class form1   Private WithEvents myInstance1 As classA   Public Sub New()       InitializeComponent()       myInstance1 = myInstance   End Sub   Private Sub StatusChange(ByVal message As String) _                Handles myInstance1.MassageOutput       TextBox1.Text = message   End Sub End Class 'フォーム2 Public Class form2   Private WithEvents myInstance1 As classA   Public Sub New()       InitializeComponent()       myInstance1 = myInstance   End Sub   Private Sub StatusChange(ByVal status As Byte) _                Handles myInstance1.MassageOutput       TextBox1.Text = status.ToString   End Sub End Class 'フォーム3 Public Class form3   Private WithEvents myInstance1 As classA   Public Sub New()       InitializeComponent()       myInstance1 = myInstance   End Sub   Private Sub StatusChange(ByVal status As Byte) _                Handles myInstance1.MassageOutput       TextBox1.Text = (status + 10).ToString   End Sub End Class ===================================================================================

  • VBA DoEvents関数の働きと使い方を知りたい

    下記のような UserForm上の Module コードを書いてももらったのですが、DoEvents の働きが分からないのです。どなたか分かりやすく説明していただけませんでしょうか? Private i As Integer Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean) If Me.TextBox1.Value = Me.Label1.Caption Then Me.Label2.Caption = "正解です" Else Me.Label2.Caption = "不正解です" End If DoEvents If i < 20 Then i = i + 1 Label_Up Me.TextBox1.Value = "" Cancel = True Else MsgBox "終了です" End If End Sub Private Sub UserForm_Initialize() i = 1 Label_Up End Sub Private Sub Label_Up() Me.Label1.Caption = Sheets("Sheet1").Range("A1:A20").Cells(i).Value DoEvents End Sub

  • エクセル2010のvbaについて

    押されたコマンドボタンの名前を取得したいです (調べてみましたがエラーになり取得できませんでした) 後コマンドボタンがたくさんあり、コードも長く とても邪魔なので省略したいのですができますか? (左クリックと右クリックで違う処理をした後       MouseDown コマンドボタンの名前で少し処理を変えるコードです) MouseUp (下のコードのような感じです) 回答お願いします Private Sub CommandButton1_MouseDown(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single) Select Case Button Case 1 Range("A1") = 1 Case 2 Range("A1") = 2 End Select End Sub Private Sub CommandButton1_MouseUp(ByVal Button As Integer, ByVal Shift As Integer, ByVal x As Single, ByVal y As Single) If (コマンドボタンの名前を取得) = "aaa" Then Range("A1") = Range("A1") + 1 Else Range("A1") = Range("A1") - 1 End If End Sub

専門家に質問してみよう