好きなおでんの具材ドラフト会議しましょう

Access2003のVBAで疑問に思ったことがあります。

VBA自体はVB6のサブセット?だと理解していますがAccess独特の記述の仕方があり、
まだ理解しておりません。
各変数や、オブジェクトへのアクセスの仕方でわからないことがありました。

'Meはフォーム
'text_nameはフォーム上の0番目のテキストオブジェクトです。
'テキストオブジェクトに書かれているデータを取得しています。

dim data as string
data = Me.text_name '--- A

これでも動作していたのですが、Aの部分で以下の書き方があるのですがAも含めて
どれが正しく、どれが一番お勧めの書き方なのでしょうか?

data = Me.texst_name.Value
data = Me!texst_name.Value
data = Me![texst_name].Value
data = Me("texst_name").Value
data = Me(0).Value

あと、Access特有?のOption Privateステートメントは、皆さんどういう時に
使っていますか?

A 回答 (3件)

私が現在使用しているのはAccess2000であり、


他のバージョンで同様のことが言えるかについては不明ですが、
それをご了解いただいた上でコメントさせていただきます。

まず、疑問点を整理すると、
1.Valueプロパティ付加の有無。
2.「.」演算子と「!」演算子の使い分け。
3.コントロール名の[ ]括りの有無。
4.("コントロール名")との使い分け。
5.コントロール名とインデックスでの参照との使い分け。
6.(ご質問にはないですが、) Controlsコレクションの明示的指定
といったところでしょうか?


はじめに、それぞれの実行速度をテストしてみました。
(Access2000、OS:Windows2000、CPU:Athlon64 2800+)

ループを組んで以下の
data = 1)~8) を1,000万回実行させたときの時間を計ったところ、

1)Me.text_name
2)Me.text_name.Value
3)Me!text_name.Value
4)Me![text_name].Value
5)Me("text_name").Value
6)Me.Controls!text_name.Value
7)Me(0).Value
8)Me.Controls(0).Value

1)2) 75秒
3)~6) 89秒
7)8) 81秒

上記の結果は、あくまで私の環境でのものであり、
Accessのバージョン、マシンの性能、MDBの構造(コントロールの数など)、
コンパイル等で異なってくることは当然考えられますが、
どちらにしても10万分の1秒レベルの差であり、体感的にはあまり意味はなさそうです。
(ただ、何万件以上のレコードに、テキストボックスの値で検索や更新を掛ける際に、もしかしたら意味が生じるか?よくわかりません。)


で、各疑問点ですが、

1.Valueプロパティ付加の有無、については、Access2000のHELPの Valueプロパティに、
「Value プロパティは、コントロールの既定のプロパティの参照または設定を行います。既定のプロパティとは、プロパティ名を明示的に指定しなかったときに、指定したものと見なされるプロパティです。」
との記述があり、処理上は省略しても何ら問題はなさそうで、
テストの結果では、処理速度にも差はないようです。


2.「.」演算子と「!」演算子の使い分け、は判断が難しいです。
HELPの式の使用での「式で ! 演算子およびドット (.) 演算子を使用する」の項に、
「すぐ次のアイテムの種類を示すには、識別子で ! およびドット (.) 演算子を使用します。
! 演算子は、次のアイテムがユーザー定義アイテム (コレクションの要素) であることを示します。たとえば、~・・・コントロールが参照されます。
通常、ドット (.) 演算子は次のアイテムが Access で定義されているアイテムであることを示します。たとえば、~・・・プロパティが参照されます。」
との記載があります。

また、MS のホワイトペーパー「Microsoft Access 2002 への変換」
http://support.microsoft.com/kb/319400/ja の Conv2002JPN.doc (日本語版) では、
「旧バージョンからコードを変換した後によく発生する問題の 1 つは、参照オブジェクトへのドット (.) 演算子の誤用による性能の低下です。通常、ユーザーがコード内で参照している名前が Microsoft Access またはいずれかの参照先ライブラリで作成されていない場合は、この名前の前にドット (.) 演算子ではなく感嘆符 (!) を付ける必要があります。」
といった記載もあり、MSでは「!」の使用を推奨しているようです。

また、ユーザー定義のコントロール名に、既定のプロパティと同じ名前を使った場合には、
(そんな名前を使わなければいいだけのことですが、)
例えば、"Name"テキストボックスを定義したとすると、
Me!Name(テキストボックス)と Me.Name(Nameプロパティ)では意味が違ってきます。
それから、Me.text_name はOKですが、Me.Controls.text_nameはダメ
(Me.Controls!text_nameならOK)のようです。

ただ、通常は「.」でも問題なく動作します。
また、「.」ならVBAのコード入力時に自動メンバー表示入力支援が機能します。
また、コンパイル時に存在しないコントロールの参照があっても、「!」ではエラーになりませんが、
「.」使用ならコンパイルエラーで見つかるなど、利点もあります。

今回のテストでは「.」使用の方が処理が速く、Accessの内部処理に違いもありそうです。
以下は私の個人的見解で、根拠はありませんが、
「!」では、ユーザー定義コントロール名をテキストとして探しに行くのに対し、
「.」では、VBAの自動入力支援が働くということは、既にフォームのメンバーとして
インデックスが張られている中から選択されるといった違いがあるのかもしれません?

「.」には上記のような利点もあり、「MSが正式にアナウンスしている使用法でない。」
ということを心得ての上でなら、好みで使ってもよいかもしれません。


3.コントロール名の[ ]括りの有無。
これは、[ ] の省略に問題はないでしょう。
ただし、コントロール名に " "(スペース)や記号を使った場合には省略できません。
例えば、Me!text_name は OK ですが、Me!text name は不可(Me![text name]ならOK)です。
まあ、名前にスペースや記号を使わなければいいだけのことではありますが。


4.("コントロール名")との使い分け。は好みの問題でしょう。
No.2さんの回答にもあるように、HELPには処理速度が少し遅くなるとの記載がありますが、
今回のテストでは差が出ていません。

なお、例えばコントロール名を
strName = "text_name"
data = Me(strName).Value
とか、
For I = 1 to 5
strName = "text_" & CStr$(I)
data = Me(strName).Value
のように変数値で扱いたいときなどには、
Me! ではなく Me( ) での記述が必要になります。
私は使い分けをしていますが、Me( )方式で統一した方がわかりやすいかもしれません。


5.コントロール名とインデックスでの参照との使い分け。は、
テストでは、Me!text_nameよりも、Me(0) や Me.Controls(0) の方が若干処理が早くなっています。
ただ、メンテナンス性の点ではかなりわかりずらく、お勧めはできません。


6.Controlsコレクションの明示的指定、については、
No.2さんの回答にもあるように、明示しない方が速く参照できるとありますが、
今回のテストでは、差が確認できませんでした。
好みで統一しておけばいい(私は普通は明示的には書いてません)と思います。

参考URL:http://msdn.microsoft.com/library/ja/default.asp …
    • good
    • 6

長文にて失礼致します(汗)



Access97のヘルプには、『Controls コレクション』の項目に以下のような説明があります。
(原文抜粋、但し改行については適宜追加・削除しています)

> 次の使用例では、[受注] という名前のフォームの [新規データ] というコントロールを参照します。
> Controls コレクションを明示しない方が速く参照できます。以下の構文例では、1 番目の方法が
> 最も速くコントロールを参照できます。
>
> Me!新規データ        ' または Forms!受注!新規データ。
> Me![新規データ]       ' コントロール名にスペースが含まれている場合。
> Me("新規データ")      ' この参照の場合、処理速度が少し遅くなります。
>
> Controls コレクションを明示的に指定して、それぞれのコントロールを参照することもできます。
>
> Me.Controls!新規データ  ' または Forms!受注.Controls!新規データ
> Me.Controls![新規データ]
> Me.Controls("新規データ")
>
> また、コレクションのインデックスでコントロールを参照することもできます。Controls コレクションは、
> 0 から順にインデックスが付けられています。
>
> Me(0)             ' コレクションの最初の項目を参照します。
> Me.Controls(0)

従って、最もシンプルな「data = Me!text_name」が処理速度としては有利と記憶して、今まで使用して
きました。
(なお、「!」と「.」の違いについてですが、「.」ではフォームのプロパティも参照可能なことから、探す先が
 増える分、遅くなるのではないか・・・と個人的には推測しています)

ちなみに、同じヘルプの『Value プロパティ』の項では、速度については触れられていませんが、
「.」を使用して「Value」を指定した場合、そのコントロールのプロパティ群から「Value」に該当する値を
探すことになる・・・ように思われますので、指定しないほうが早いのではないかと推測します。
(・・・テストは行ったことがありません)


従って、私のお勧めは、「コントロールの参照は、可能な限りシンプルに」です。
(但し、ヘルプにもある通り、コントロール名がSpaceを含む場合は角括弧をしないのは「不可能」なので、
 その場合は、「角括弧を使用するのが正しい」です)


> Option Privateステートメントは、皆さんどういう時に使っていますか?

例えば「入力項目が複数あって、そのすべてが埋められたらコマンドボタンを使用可にする」といった
制御をする場合など、そのフォームのコントロール内で共通して使用するSubを作成するときには、
「Private Function AllControlCheck() As Boolean」といったように使っています。
(こういった、別のフォームで、まったく異なるコントロール群に対して同様の評価を行う可能性がある場合、
 私はフォームごとにPrivate宣言したSub/Functionを使用し、フォーム間で名前の重複が可能なように
 しています。
 ・・・最近は、こういったものでさえも、「ParamArray」を使うなどしてフォーム間で共通化させようと
 画策したりもしていますが(笑))


なお、No.1の方が言われている「コントロール型として参照したい場合との区別」についてですが、
この場合は「Set」を使用しないとエラーになったはずなので、問題ないのではないかと思います。
    • good
    • 2

どれも間違いじゃないと思います。

ただ、Aの場合もしプロパティにValueを持たないオブジェクトの場合(例:ラベルオブジェクト)エラーとなりますし、コントロール型として参照したい場合との区別が付きませんのでお勧めしません。

私は後から修正等するときにわかりやすい方がいいので、明示的な表記、、、Me.Controls("text_name").Valueといった表記をするようにしています。

!(感嘆符)を使った場合(” ”)で囲む必要がなくなる、、とぐらいに思っておけばよいかと思います。
    • good
    • 1

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

このQ&Aを見た人はこんなQ&Aも見ています


おすすめ情報

このQ&Aを見た人がよく見るQ&A