Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


7643 / 13644 ツリー ←次へ | 前へ→

【37748】メンバの参照渡し Yj 06/5/17(水) 19:00 質問[未読]
【37750】Re:メンバの参照渡し neptune 06/5/17(水) 21:06 発言[未読]
【37751】Re:メンバの参照渡し neptune 06/5/17(水) 21:08 発言[未読]
【37765】Re:メンバの参照渡し Yj 06/5/18(木) 13:03 お礼[未読]
【37754】Re:メンバの参照渡し ichinose 06/5/17(水) 22:46 発言[未読]
【37756】Re:メンバの参照渡し kobasan 06/5/17(水) 23:56 発言[未読]
【37766】Re:メンバの参照渡し Yj 06/5/18(木) 13:40 お礼[未読]
【37796】Re:メンバの参照渡し Yj 06/5/18(木) 21:06 発言[未読]
【37811】Re:メンバの参照渡し ichinose 06/5/19(金) 9:27 発言[未読]

【37748】メンバの参照渡し
質問  Yj  - 06/5/17(水) 19:00 -

引用なし
パスワード
   はじめまして。

Excel 2003 の VBA について質問です。

 標準モジュールで定義している関数の引数に、メンバ変数を「参照渡し」で渡し、結果をメンバ変数へ代入するというものです。つまり、参照渡しの引数を戻り値のように使用するというものなんですが、出来ないです。

 下記に確認したコードを記します。
 ご返答頂けると助かります。

<コードの概要>
 内容は、クラスモジュールの String 型のメンバ変数(sTargetFolder)を、r2 関数へ参照渡しで渡し、r2 関数内で値を変更。その後、Debug.Print でイミディエイト・ウィンドウへ出力する、というものです。


<クラスモジュール「CWork」>
public sTargetFolder as string


<標準モジュール「main」>
Private Sub r2(ByRef lpValue As String)
'サンプルとして、アクティブ・セルの内容を代入する処理にしていますが、
'本来は色々な計算を行った結果を代入するものになります。
'また、戻り値は関数にあたえた引数の成否の結果を示す値に使うため、
'戻り値で計算結果返すことはできません。
  lpValue = ActiveCell.value
End Sub

Private Sub r()
  Dim wk As New CWork

  r2 wk.sTargetFolder

  Debug.Print "1.""" & wk.sTargetFolder & """"


  Dim s As String

  r2 s

  Debug.Print "2.""" & s & """"

  '何故 1 と 2 の出力結果がことなるの?
End Sub

【37750】Re:メンバの参照渡し
発言  neptune  - 06/5/17(水) 21:06 -

引用なし
パスワード
   ▼Yj さん:
確認しました。出来ませんね。
>r2 wk.sTargetFolder
ですが、気になるのはCでいうポインタのポインタを渡すことになるんですよね?

自信はありませんが、こういうのはVBではナシなんじゃないかと思います。
仕様外ということなんじゃないかな?

>また、戻り値は関数にあたえた引数の成否の結果を示す値に使うため、
>'戻り値で計算結果返すことはできません
解決策としてはrの方でr2に渡す変数を用意して、
これで受け取り、改めて、wk.sTargetFolderに代入するという
まどろっこしい方法ですか。
若しくは計算結果を包含したユーザー定義型(Cで言う構造体)を用意して
r2の戻り値をそのユーザー定義型にするという手もありますね。

間違ってたらごめんなさい。(仕様うんぬんのレベルで自信なし)

【37751】Re:メンバの参照渡し
発言  neptune  - 06/5/17(水) 21:08 -

引用なし
パスワード
   念のため追記
>r2の戻り値をそのユーザー定義型にするという手もありますね。
はr2をsubからFunctionにする必要があります。

【37754】Re:メンバの参照渡し
発言  ichinose  - 06/5/17(水) 22:46 -

引用なし
パスワード
   こんばんは。

>Excel 2003 の VBA について質問です。
>
> 標準モジュールで定義している関数の引数に、メンバ変数を「参照渡し」で渡し、結果をメンバ変数へ代入するというものです。つまり、参照渡しの引数を戻り値のように使用するというものなんですが、出来ないです。

オブジェクトのプロパティは全て値渡しだと思いますが・・・。

Sub test()
  call test1(range("a1").value)
end sub

sub test1(myvalue as variant)
  myvalue=123
end sub


これだって、セルA1に値ははいりませんよね?

Call aaa(thisworkbook)

これも値渡しです(Thisworkbook Applicationのプロパティです)

【37756】Re:メンバの参照渡し
発言  kobasan  - 06/5/17(水) 23:56 -

引用なし
パスワード
   皆さん 今晩は。
私も勉強のために、ちょと書いてみます。

ByRef のヘルプを見ると

参照渡し
プロシージャに引数として変数を渡す方法の 1 つ。参照渡し (参照による引き渡し) で変数をプロシージャに渡すと、その変数の内容は、呼び出されたプロシージャ内で変更することができます。参照渡しでは、呼び出されたプロシージャ内では、渡された変数のメモリ内の格納場所に対して、直接操作を行います。したがって、呼び出されたプロシージャ内で渡された変数の値を変更すると、呼び出し側のプロシージャで参照する元の変数の値も変更されます。

とありますね。

クラスモジュールは別として、下記を実行すると、1回目の MsgBox "s= " & s は、"BB" を表示しますね。
2回目の MsgBox "s= " & s は、"AA" を表示しますね。

この変化が、参照渡しということだと思います。
こんな変化をさせたいということでしょうか?

それから、これだけでは、クラスモジュールについては、よく分りません?


Sub rrr()
  Dim wk As New CWork

  'r2 wk.sTargetFolder = "WW"

  'Debug.Print "1.""" & wk.sTargetFolder & """"


  Dim s As String
  s = "BB"
  MsgBox "s= " & s
  r2 s
  
  MsgBox "s= " & s

  'Debug.Print "2.""" & s & """"

  '何故 1 と 2 の出力結果がことなるの?
End Sub

Private Sub r2(ByRef lpValue As String)
'サンプルとして、アクティブ・セルの内容を代入する処理にしていますが、
'本来は色々な計算を行った結果を代入するものになります。
'また、戻り値は関数にあたえた引数の成否の結果を示す値に使うため、
'戻り値で計算結果返すことはできません。

  lpValue = "AA"  'ActiveCell.Value

End Sub


>
>オブジェクトのプロパティは全て値渡しだと思いますが・・・。
>
>Sub test()
>  call test1(range("a1").value)
>end sub
>
>sub test1(myvalue as variant)
>  myvalue=123
>end sub
>
>
>これだって、セルA1に値ははいりませんよね?
>
>Call aaa(thisworkbook)
>
>これも値渡しです(Thisworkbook Applicationのプロパティです)

【37765】Re:メンバの参照渡し
お礼  Yj  - 06/5/18(木) 13:03 -

引用なし
パスワード
   neptune さん、ご返答ありがとうございます。

neptune さんの仰るとおり、ユーザ定義型の戻り値か、変数を別途用意するコードが素直な解答のように思えました。

変数を別途用意する事で対応したいと思います。
有難うございました。

【37766】Re:メンバの参照渡し
お礼  Yj  - 06/5/18(木) 13:40 -

引用なし
パスワード
   ichinose さん、kobasan さん、返答ありがとうございます。

> オブジェクトのプロパティは全て値渡しだと思いますが・・・。

 Property プロシージャから間接的にアクセスする場合は「値渡し」になるのは理解できるのですが、直接メンバ変数にアクセスする場合も「値渡し」になるのは、なんか納得できないですね(笑)。

 メンバ変数の型を String から Long に変更した場合を試してみたところ、「参照渡し」になっていました。


>クラスモジュールは別として、下記を実行すると、
>1回目の MsgBox "s= " & s は、"BB" を表示しますね。
>2回目の MsgBox "s= " & s は、"AA" を表示しますね。
>この変化が、参照渡しということだと思います。

 はい。この様な変化を行いたいと考えています。


 現状は neptune さんから提案頂いた、「参照渡し」ように変数を用意することで対応したいと思います。

 有難うございました。

【37796】Re:メンバの参照渡し
発言  Yj  - 06/5/18(木) 21:06 -

引用なし
パスワード
   Yj です。

> メンバ変数の型を String から Long に変更した場合を試してみたところ、「参照渡し」になっていました。

 これは勘違いです。Long 型に対しても「値渡し」になっていました。


 失礼致しました。

【37811】Re:メンバの参照渡し
発言  ichinose  - 06/5/19(金) 9:27 -

引用なし
パスワード
   ▼Yj さん:
おはようございます。

>> メンバ変数の型を String から Long に変更した場合を試してみたところ、「参照渡し」になっていました。

> これは勘違いです。Long 型に対しても「値渡し」になっていました。
ですよね?
私も以前これは、試してみたことがあったので・・・。

例えば、クラスモジュールClass1では

Public cvalue As Long

という変数宣言だけのクラスを定義して

標準モジュールにて、

'==================================================
Sub main()
  Dim cls As New Class1
  Call test(cls.cvalue)
  MsgBox cls.cvalue
  
End Sub
'===================================================
Sub main1()
  Dim myvalue As Long
  Call test(myvalue)
  MsgBox myvalue
End Sub
'====================================================
Sub test(tvalue As Integer)
  tvalue = 100
End Sub

上記のmainは、取りあえず作動しますが、
main1は、型が一致しないというエラーが呼び出し(Call test(myvalue))
で発生します(これは、コンパイルエラーですね?)

つまり、クラスのプロパティの型までは、VBAはチェックしていません。
Vbaでは、オブジェクトは、クラスモジュールで作成しているオブジェクトのみしか
扱えないわけではありませんよね?


型のチェックをしていない(できない)プロパティに対して、
参照渡しでのパラメータを許すことは、Excelの立場になって考えると
大変だったのではないでしょうかねえ??
値渡しなら、安心だということだったのではないかと推測します。

7643 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free