[リストへもどる]   [VBレスキュー(花ちゃん)]
一括表示

投稿時間:2004/11/05(Fri) 11:04
投稿者名:ダンボ
URL :
タイトル:
Setコマンドが省略できない理由
先ほど、Picture2.Container = Picture1と書いて、IDEに怒られました。
(正しくはSet Picture2.Container = Picture1)

「オブジェクト変数に関する代入文はSet、単純変数に関する代入文はLet、そしてLetは省略可能」
という文法規則は分かっているのですが、何故Microsoftは「Setも省略可能」にしなかったのかな?

変数Xがオブジェクトなのか単純変数なのかはDim宣言で分かるはず。
Dimが省略された場合はVariantで単純変数ですわね。

既に論議し尽くされた疑問かも知れませんし、真相はMicrosoftに聞かなければ分からないこと
ですが、息抜きネタとして、識者の推測をちょっと聞いてみたいです。

投稿時間:2004/11/05(Fri) 11:20
投稿者名:LESIA
Eメール:
URL :
タイトル:
Re: Setコマンドが省略できない理由
> 先ほど、Picture2.Container = Picture1と書いて、IDEに怒られました。
> (正しくはSet Picture2.Container = Picture1)
>
> 「オブジェクト変数に関する代入文はSet、単純変数に関する代入文はLet、そしてLetは省略可能」
> という文法規則は分かっているのですが、何故Microsoftは「Setも省略可能」にしなかったのかな?
>
> 変数Xがオブジェクトなのか単純変数なのかはDim宣言で分かるはず。
> Dimが省略された場合はVariantで単純変数ですわね。

Variant型変数にもオブジェクトは代入できますよ。

以下のコードを実行してみれば省略できない理由がわかるかも

Dim a As Variant

'変数aにテキストボックスText1を代入
Set a = Text1
Debug.Print TypeName(a)
Debug.Print a.Text

'変数aにテキストボックスText1のデフォルトプロパティTextの値を代入
a = Text1
Debug.Print TypeName(a)
Debug.Print a

投稿時間:2004/11/05(Fri) 15:07
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^2: Setコマンドが省略できない理由
自分で「プロパティ」を実装してみると、わかるかも知れませんね。
代入プロパティの宣言には、「Property Let」と「Propert Set」という2種類がありますから。

ちなみに、Pictureオブジェクトの代入に対しては、
  Set Picture1.Picutre = LoadPicture("C:\A.BMP")
と、
  Picture1.Picutre = LoadPicture("C:\A.BMP")
のどちらの構文も使えます。


本来であれば、Pictureオブジェクトの代入時にも、Setを使うべきなのですが、
古いバージョンとの互換性維持のため、後者の記述も例外的にサポートされています。

ただ、Setを使わなくて良いのは、「標準コントロール」の場合だけであり、
ActiveXコントロールの場合は、Setを使って代入しなければなりませんので、
結局の所、「オブジェクトの代入では、常にSetを使う」と覚えておくのが吉でしょうね。


> > Dimが省略された場合はVariantで単純変数ですわね。
Option Explicitを有効にしている場合は、Dimは省略できませんね。
(その場合でも、As句の記載を省略する事はできますが)

で、より正確に表現するなら、「Variant型になる」というよりは、
「規定のデータ型になる」という事ですね。
(規定のデータ型の指定も無い場合は、Variantが使われる)


> 以下のコードを実行してみれば省略できない理由がわかるかも

代入時は、Setが使えるから良いのですが、引数指定で渡すときには、
処理が曖昧になるので、厄介なんですよね…。

  Dim RS As ADODB.Recordset
  Set RS = New ADODB.Recordset
  RS.Fields.Append "NUMBER", adInteger
  RS.Open
  RS.AddNew "NUMBER", 123456

  '========
 ' 括弧を付けるだけで、結果が変化します。
  '========
  Debug.Print TypeName(  RS  )
  Debug.Print TypeName( (RS) )
  Debug.Print TypeName(  RS() )

  Debug.Print TypeName(   RS!Number   )
  Debug.Print TypeName(  (RS!Number)  )
  Debug.Print TypeName(  RS!Number()  )
  Debug.Print TypeName( (RS!Number()) )
  Debug.Print TypeName( RS!Number()() )

# それぞれの TypeName 関数が、どのような値を返すのかを、
# 実行せずに正しく答えられるようなら、上級者と呼べるかな。(^^;

投稿時間:2004/11/06(Sat) 17:04
投稿者名:java.lang.Nullpo
Eメール:
URL :
タイトル:
Re: Setコマンドが省略できない理由
> 何故Microsoftは「Setも省略可能」にしなかったのかな?

1番納得のいく理由は、オブジェクトそのものなのか、
デフォルトプロパティなのか、判別できないからじゃないのでしょうか?

投稿時間:2004/11/06(Sat) 23:41
投稿者名:K.J.K.
Eメール:akiya@koalanet.ne.jp
URL :
タイトル:
Re: Setコマンドが省略できない理由
IUnknown::QueryInterfaceを用いるかどうか、で必要かどうかが決まります。
# QueryInterfaceが要るときは、VB上でも異なる型ですよね。

VB4以前のオブジェクト型は、全てIDispatch(= As Object)で済みましたが、
VB5以降では、Vtblインターフェースの型を使う頻度も増えましたし。