最近、いつ泣きましたか?

以下のコードをご覧ください

変数について
aに1が入ります
その後、function sansyouに変数 a=1 が渡され bに1が入ります
ここの流れがわかりません。変数aに1が入っているのに、なぜ、b という違う
変数に 1を渡せるのでしょうか? 同じ 文字列の変数a なら渡せる意味が
分かります

ご存じの方、教えて下さい


(コード)
Sub 参照渡し()

Dim a As Long

a = 1

Call sansyou(a)

MsgBox a

End Sub

Function sansyou(ByRef b As Long)

b = b * 2

End Function

A 回答 (3件)

多くのプログラミング言語には、変数名等の有効な範囲というものがあります。


詳しくは「グローバル変数」「ローカル変数」「スコープ」といったキーワードで検索。

VBAの場合、sub 〜() から End Subまでや、Function 〜()からEnd Functionの中でDimで宣言した変数やByRefやByValで指定した引数用の変数等は、そのEnd〜までの中だけで有効です。

有効範囲外のものを使うことはできません。


今回のプログラムだと、変数aは Sub 参照渡し()からEnd Subの中で宣言されているので、有効範囲はその中だけです。
同様に引数bはFunction sansyou〜End Functionの中だけで有効です。

このため、sanyou関数の中から 「sub 参照渡しの中の変数a」を直接操作することはできません。
このことからも「同じ 文字列の変数a なら渡せる意味が分かります」というのが間違った考えだと言えます。


なお、VBAの場合、「Option Explicit」を指定しないときは、未使用の変数を使おうとするとDimで宣言されたと見做されます。
このため、一見エラーが無く動いたように見えて、全然違う動きをしてしまうことがあります。


Function sansyou(ByRef b As Long)
a = a * 2
End Function

で、Sub 参照渡し()のaを操作しているつもりでいても、
実際には

Function sansyou(ByRef b As Long)
Dim a As Variant
a = a * 2
End Function

と同じになっています。
    • good
    • 0

最初に。


MsgBoxは関数です。
https://learn.microsoft.com/ja-jp/office/vba/lan …
これによれば、最初ほ引数名は「prompt」です。

「変数aに1が入っているのに、なぜ、b という違う変数に1を渡せるのでしょうか? 同じ 文字列の変数a なら渡せる意味が分かります」
という考えだと、
MsgBox a

「変数aに1が入っているのに、なぜ、prompt という違う変数に1を渡せるのでしょうか? 同じ 文字列の変数a なら渡せる意味が分かります」
ということになります。


関数の仮引数というのは、呼び出し側で別々で指定されるものを、関数内で同じ名前で処理するための仕組みです。

MsgBox a だったら 仮引数prompt に 実引数a を渡した状態で MsgBoxを実行する
MsgBox "こんにちは" だったら 仮引数prompt に 実引数"こんにちは" を渡した状態で MsgBoxを実行する

Call sansyou(a) でも同様に、仮引数bに 実引数として a を渡した状態で sansyou関数を実行する、ということです。


その上で、値渡しと参照渡しとで動作が違います。

○値渡し:
Function sansyou(ByVal b As Long) としたき
・仮引数b は「 Longの値」を覚える変数になります。
・Call sansyou(a) で渡されるのは「aの値、つまり『1』」が渡されます。
仮引数b は 「値1」を受け取り記憶します。
・b = b * 2 で 「変数bの値である1」を2倍して「変数b」に記憶します。
・関数内の変数であるbと、関数外の変数aとの関係は無いので、実行後も変数aは1のままです。

○参照渡し:
Function sansyou(ByRef b As Long) としたき
・仮引数b は 「Long型変数への参照」を覚える変数になります。
このとき、bの値を読むときは「参照している変数の値」を読み出し、書き込むときは「参照している変数」へ書き込もうとします。
・Call sansyou(a) で渡されるのは「変数aそのもの(への参照)」が渡されます。
仮引数b は 「変数aそのもの(への参照)」」を受け取り記憶します。
・b = b * 2 で 「『変数bが参照している変数aの値』である1」を2倍して「変数bが参照している変数a」に記憶します。
これにより、実行後は変数aは2に変化します。
    • good
    • 1
この回答へのお礼

解説ありがとうございます。少しずつ理解できました

○値渡しについてなのですが

・関数内の変数であるbと、関数外の変数aとの関係は無いので、実行後も変数aは1のままです

ここでいう、関数内と関数外とは具体的に、何と何のことを
いっているのですようか?ご教授いただければと思います

お礼日時:2024/09/28 13:00

aとbは名前が違うだけで、実際には全く同じものだから <ー変数のアドレスが同じ



値がおなじになるのは当然です

名前が違うだけで同じものだから、sansyouという関数で計算した結果がそのまま使えるでしょ
    • good
    • 2
この回答へのお礼

メモリアドレスが同じ。名前は違うけども
実際に、値を入れる場所は同じっていう認識なんですかね

ご指摘ありがとうございます

お礼日時:2024/09/28 12:37

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

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


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