モジュールとクラスモジュール(イベントプロシージャ)に違いがあることや、モジュールを超えて変数を利用したいときは、Publicで宣言する、という辺りを本を読んでおおまかに理解しました。
帳票管理フォームというフォームに受付CDという主キーの番号があります。そのフォーム上に帳票の詳細な事項を入力するフォームを呼び出すボタンがあります。フォームのイベントプロシージャの一番上のOption Compare Database,Option Explicitの直下行にPublic UketukeCD as Integerと宣言し、
ボタンのイベントプロシージャで、
UketukeCD = Me![受付CD].Value
などと記述しました。
新規入力データの受付CDが例えば452ならUketukeCDには452が代入されればいいんです。
帳票の詳細な事項を入力するフォーム(報告書フォームとします)の「読みこみ時」のイベントプロシージャに以下のように記述しました。
こちらのモジュールの一番上にもPublic UketukeCD as Integerと宣言し、(←これは必要なんでしょうか?)
Me![受付CD].Value = UketukeCDと書きました。
過去のデータを検索するときはレコードソースのテーブルの受付CDのデータを受付CDフィールドに持ってき、新規入力の場合は、受付CDは帳票管理フォームのものを代入するという設計で、UketukeCDの値(例:452)を報告書フォーム内の受付CDフィールド内に出力する、という感じですが、なぜかUketukeCDにはいつも0が代入されています。
変数は他のモジュールで利用できても代入された値までは移行されないのですか?
イベントプロシージャだからできないんですか?
字数の制限上、コードをかなり省略しています。
足りない部分は補足で補いますのでおっしゃって下さい。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

どうも変数のスコープ(変数の有効範囲)を理解していないようですね。


例えば
------モジュールのモジュール1
Option Compare Database
Public a As Integer
Sub aaa()
a = 3
End Sub

------フォーム1のモジュール
Option Compare Database
Public a As Integer
Private Sub Form_Load()
Dim a As Integer
a = 1
MsgBox CStr(a)
End Sub

Private Sub コマンド1_Click()
a = 2
Call aaa
End Sub

Private Sub コマンド2_Click()
MsgBox CStr(a)
End Sub

-------フォーム2のモジュール
Option Compare Database

Private Sub Form_Load()
MsgBox CStr(a)
End Sub


ではこれをフォーム1を開いて、ボタン1を押して、ボタン2を押して、フォーム2を開くと
メッセージボックスは



との順で表示されます。

これはスコープが
関数内が宣言
フォーム共通の宣言
DB全体(モジュール)の宣言

の順に優先度が高いためです。一番したが一番低い
各々スコープは

関数内は
sub

End sub
が有効範囲で

フォーム共通の宣言は同一フォーム内で有効

モジュールの場合は同一DB内で有効です。

通常、Publicを宣言して別のフォームに値を渡す場合はモジュールにPublic宣言をします。

よって今回の場合はフォームAにPublic変数を定義してもフォームBに対しては有効では有りません。
このような場合はモジュールでPublic変数の定義をする必要があります。

フォーム内は宣言不要!!
    • good
    • 0
この回答へのお礼

回答ありがとうございます!!
上記のプログラムを新規に作ってみて試してやっとわかりました。
例えばフォーム1を開いた後、すぐにコマンド2をクリックすると、
(無知な私は1が出ると思った)0が出るのは、
フォーム1のモジュールの
Dim a As Integer

End Sub
はコマンド2には適用されないからですね。
適用範囲がそうなっていたんですね。
マイクロソフトのオフィシャルマニュアル読んでも
なかなか理解できなかったんです。
おかげさまでうまくVBAで作り上げることができました。
お礼を申し上げます。

お礼日時:2001/11/16 12:25

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q標準モジュールにpublicで宣言するしかない?

フォームモジュールと標準モジュールで同じ変数を使って値を行き来したい場合、
標準モジュールにpublicで宣言するしかないのでしょうか?

【フォームモジュール】
Private Sub cmd_コマンド0_Click()
test = "aaa"
Call 標準モジュールtest
End Sub

【標準モジュール】
Public test As String
Sub 標準モジュールtest()
MsgBox test
End Sub

でいいのですか?

Aベストアンサー

> 標準モジュールにpublicで宣言するしかないのでしょうか?

例えば、「自身のPath」のように実行後の変動がないものや、
「ファイルのプロパティ」のように呼出元によらず共通になるもの
などは、「標準モジュールにPublicで宣言」でいいと思いますが、
「ある処理の開始時間と終了時間」のように【都度変化する
値】のような場合は「SubやFunctionの引数として渡す」という
方法を採った方がよいかと思います。
(そうした方が、「うっかり古いままの値を使用してしまった」と
 いった失敗を防げる、と)

この場合、「フォームモジュールのSubの中」と「Subの引数」の
2箇所で、同じ値を受け取る変数を宣言することになります。
(もしくは、下で「または~」としたように、フォームモジュール側での
 変数宣言はせずに、引数に直接記述)

【フォームモジュール】
Private Sub cmd_コマンド0_Click()
  Dim test As String
  test = "aaa"
  Call 標準モジュールtest(test)
  'または、変数「test」は宣言せずに文字列を引数に直接記述
  'Call 標準モジュールtest("aaa")
End Sub

【標準モジュール】
Sub 標準モジュールtest(test As String)
  MsgBox test
End Sub

> 標準モジュールにpublicで宣言するしかないのでしょうか?

例えば、「自身のPath」のように実行後の変動がないものや、
「ファイルのプロパティ」のように呼出元によらず共通になるもの
などは、「標準モジュールにPublicで宣言」でいいと思いますが、
「ある処理の開始時間と終了時間」のように【都度変化する
値】のような場合は「SubやFunctionの引数として渡す」という
方法を採った方がよいかと思います。
(そうした方が、「うっかり古いままの値を使用してしまった」と
 いった失敗を防げる、と)

この...続きを読む

QACCESS2000の帳票フォームでカーソルのあるレコードの他のフィールドの書式変更のモジュール

ACCESS2000の帳票フォームで、一番左のフィールドが得意先名、
間にいくつかのフィールドがあり、一番右のフィールドが金額を入金フィールドとして、
入金フィールドにカーソルがある場合、今どの得意先にいるか分かるように、今いるレコードの得意先フィールドの色を変えたいと思ってます。
この場合のモジュールの書き方を教えて頂けますでしょうか?
条件付書式設定でも無理なので、今はレコードセレクタを使ってます。
でもフィールドが多いため、右のほうに行けばどのレコードにいるのか分からなくなってしまうのです。
宜しくお願いいたします。

Aベストアンサー

>"テキスト72"="SHIIRE_CD"
これじゃ文字列の比較式です
[テキスト72]=[SHIIRE_CD]

Qアクセスのフォームビューの帳票フォームではレコード

アクセスのフォームビューの帳票フォームではレコードを削除する事は出来ないのでしょうか?

データシートビューではレコードセレクタを選択し右クリックをすると
「レコードの削除(R)」という項目が出てきますが
帳票フォームでは出てきません。

帳票フォームでレコードを削除する方法を教えてください。
よろしくお願いいたします。

Aベストアンサー

ツールバー上の[レコードの削除]コマンドボタン か
レコードセレクタを選択し、[Delete]キー

Q単票フォームと帳票フォームを連動 アクセス

どういう構成にすればいいか教えてください。

元データはT_testのみですが
T_testを元に、単票フォームと帳票フォームを作り、
この二つのフォームをサブフォームにし、1つの親フォームにはめて、
帳票フォームのレコードをクリックする(カレントレコードが変わる)度に
単票フォームは、帳票フォームのデータを表示させたいのですが
どうすればいいでしょう?

レコードソースは親フォームに設定すればいいのでしょうか?
それとも単票フォームと帳票フォームそれぞれにT_testを設定すればいいでしょうか?

帳票フォームのレコードをクリックして単票フォームのデータを表示させる際は、
帳票フォームの値を取得して単票フォームにフィルタをかければいいのでしょうか?

Aベストアンサー

No2 さんの方法を VBA を使用しないで実現。

hatena さんのを拝借して

帳票フォームの埋め込んであるサブフォームコントロール名を、SubForm1
単票フォームの埋め込んであるサブフォームコントロール名を、SubForm2
とします。

「T_test」の中に、オートナンバ「an」フィールドがあると仮定します。
オートナンバでなくてもレコードを一意に決定できるフィールドなら OKです。

細工1)
メインに不可視のテキストボックス「txt1」を配置します。
txt1 のコントロールソースを
=[subform1].[Form].[an]

細工2)
SubForm2 の リンク親/子フィールドを設定します。
(直接の手入力で:ビルドは使いません(この状況では使えません))
・リンク親フィールド : txt1
・リンク子フィールド : an

Q帳票フォームの自動計算

毎度おせわになります。

商品  購入金額  比率(%)
-------------------------------
A     99,999  99.9
B
C
:
:
-------------------------------
TOTAL  99,999   100.0

上記のような帳票フォームがあり
各商品の購入金額を入力すると、各商品毎の購入金額合計に対する
の割合(比率)が自動計算されるようにする
という、フォームを作りたいのです。
フォームにはテーブルが連結されていて、上記の項目はテーブルから
貼り付けています。
購入金額をA,B,C…と入力していくと、それぞれの比率も変わってるの
ですが、カレントレコードしか計算ができません。
どのようにしたら全レコードの比率を再計算して表示できるのでしょうか?

Aベストアンサー

自信なしです。
間違っているかもしれないので、他の方の回答を優先してください。

表形式フォーム上で、「比率」という項目のレコードソースプロパティをあるテーブルのレコードソースにしているならば難しいと思います。
現在フォームで開いて編集中であるテーブルの複数のレコードの「比率」という項目の更新をしなければいけないからです。

【案】
(1)テキストボックス「比率」のプロパティで以下のように設定する
 コントロールソース  「=[購入金額]/Sum([購入金額])」
 書式         「パーセント」
 →テーブルの「比率」項目には設定されませんので注意してください
(2)テキストボックス「購入金額」の更新後処理イベントに以下の記述をする
SendKeys "{F9}"
 →これで再計算が行われるので、テキストボックス「比率」も再計算されます。
  最クエリーの場合は、フォーカスが先頭レコードに戻ってしまうので、この方法をとっています。

「比率」をテーブルに格納したい場合は、これだけではだめですけど・・・。

ご参考まで・・・

自信なしです。
間違っているかもしれないので、他の方の回答を優先してください。

表形式フォーム上で、「比率」という項目のレコードソースプロパティをあるテーブルのレコードソースにしているならば難しいと思います。
現在フォームで開いて編集中であるテーブルの複数のレコードの「比率」という項目の更新をしなければいけないからです。

【案】
(1)テキストボックス「比率」のプロパティで以下のように設定する
 コントロールソース  「=[購入金額]/Sum([購入金額])」
 書式       ...続きを読む


人気Q&Aランキング

おすすめ情報