親プロシージャに数値を渡すときに、引数付のFuncitonプロシージャと引数付のSUBプロシージャは、結果を見ると同じ動きをするように思います。
このような場合、両者には、どのような違いがあるのでしょうか?
Sub 親プロシージャ()
Cells(1,MyNOend)=123
end Sub
・子プロシージャ
Function FMyRowCnt(MyNOend As Integer)
MyNOend = TMYKanriBkWs1.Range("D1").CurrentRegion.Rows.Count
End Function
Sub FMyRowCnt(MyNOend As Integer)
MyNOend = TMYKanriBkWs1.Range("D1").CurrentRegion.Rows.Count
End Sub
以上 よろしくお願い致します。
No.6ベストアンサー
- 回答日時:
こんにちは。
#2,#4 を書いたものです。#5 さんの回答について、数点書かせていいだきます。
専門家さんとしていますが、ちょっと内容には疑問を感じました。
Excel VBAとAccess VBAとは赴きは違っていても、Sub プロシージャも、Function ユーザー定義も、サブルーチンで使用する分には、基本的には変わりません。ただ、Access VBAでは、呼び出しの必要があって、関数にするかもしれませんが、Excelでは、関数の呼び出しは、Access のようにはしません。それは、ワークシートが一つのコントロール・オブジェクトになっているからです。
> 『Sub』プロシージャは引数の変数を書き換えると呼び出し元『親』で書き換えた値が反映します。→処理部分を『サブルーチン』として分離しただけです。
Subプロシージャは、戻り値自身はありませんが、デフォルトで、参照渡しになっていますが、値渡しも可能です。
例題1
>・『Function』プロシージャは引数の変数を書き換えても呼び出し元『親』の値は変化しません。
参照渡し(byRef)にすれば、親の変数は変わります。
例題2
以下は、初歩的なサンプルです。
--------------------------------------------------
例題1:
'値渡し、参照渡しの例
Sub Test1()
Dim a
Dim b
a = 1
b = 1
subTest1 a, b
MsgBox "a: " & a & ",b: " & b
End Sub
Sub subTest1(ByVal a, ByRef b)
a = a + 1
b = a
End Sub
例題2:
'参照渡しの例
Sub Test2()
Dim a
Dim b
a = 1
b = 0
subTest2 a, b
MsgBox "a: " & a & ",b:" & b
End Sub
Function subTest2(ByVal a, ByRef b)
a = a + 1
b = a
End Function
No.5
- 回答日時:
★簡単に説明すると『引数』と『戻り値』の扱いです。
・両方とも『親』プロシージャから呼ばれますが、
『Sub』プロシージャは引数の変数を書き換えると呼び出し元『親』で書き換えた値が
反映します。→処理部分を『サブルーチン』として分離しただけです。
・それで『Function』プロシージャは引数の変数を書き換えても呼び出し元『親』の値は
変化しません。また、他の言語と同じように『関数』としての仕組みとして『戻り値』
が『親』へ戻せます。→ここの部分が『Sub』プロシージャと大きく違います。『Sub』
プロシージャは『戻り値』を返せません。
●使い分け
・変数(引数)の操作を『親』プロシージャと共有したい場合は『Sub』プロシージャを使う。
または、複数の処理結果を返したい場合に使う。
・変数(引数)の操作を『親』プロシージャと別に扱いたい場合は『Function』プロシージャを使う。
または、『関数』という意味で『戻り値』で処理結果を返したい場合に使います。
最後に:
・昔、Basic 言語には『Sub』プロシージャしか記述できませんでした。
その後、他の言語のような『関数』機能を自分で定義できる『Function』プロシージャが
登場しました。この登場により、呼び出し元『親』の処理で『戻り値』として処理結果を
受け取れるように便利になりました。
・以上。おわり。
すばらしい文章能力に感激です。
いままで回答してくださった皆様のアドバイスを読み、さらにOh-Orangeさんの回答を読む。これで、完璧に頭に入りかつ、仕える知識になりました。
ありがとうございました。
No.4
- 回答日時:
#2です。
補足:
Excel VBAの場合は、動的な作業に対しては、サブルーチン・プロシージャがよいです。静的なものは、サブルーチン関数でもよいかと思います。Access VBAとは、この点で違ってくると思います。その関数は、必ずしも呼び出しに使うわけではありません。
ただ、本質的に何のためにするか、ということです。
参照渡しと値渡しの処理スピードの違いというものはあります。しかし、それ以上に、分散処理のため(たぶん、使用メモリも減る)と、デバッグのしやすさ、つまりコードの読みやすさがあると思います。そういうことを心がければ、自ずと選択は決まってくるのではないか、と私は思います。
>このような場合、両者には、どのような違いがあるのでしょうか?
違いはないれど、不自然です。
以下のように、戻り値を与えたほうがよいです。
引数の方は、Long 型です。
Function FMyRowCnt(MyNOend As Long)
FMyRowCnt = TMYKanriBkWs1.Range("D1").CurrentRegion.Rows.Count
End Function
質問の仕方から、内容への回答まで、どうもありがとうございました。
素人のため、盛り沢山で有用な回答のすべてを、うちに取り入れることができませんでしたが、ご丁重な回答どうもありがとうございました。
また、「違いはないけれど、不自然です」のようなニュアンスも教えていただけたことが、大変ありがたく思います。
No.3
- 回答日時:
小生も、その昔、疑問に思ったことです。
小生なりに理解したことを書いて見ます。
functionは、返す答えが1つの場合。
従って、 functionの場合は、
a=FMyRowCnt(xxxx)、であったり、
或いは、 if FMyRowCnt<>"" thenであったりします。
functionでありがたいのは、下記のような場合です。
if mysheetExsits("xxxxxxx")=true then xxxxxxxx
(勿論、mysheetExsitsはfunctionです)
subroutineでも、1つ(以上)の値を返すことが可能です。
sub test(byval aaa as integer, byref bbb as interger, byref ccc as interger)
byvalは、親から、子への一方向のみ、
byrefは、双方向です。従って、子で、値を書き換えると親はそれを参照することができます。
小生は、サブルーチンで、処理をして、結果がfailとなった時に
byrefにて、親に返してやります。
先ほど書きました、
if mysheetExsits("xxxxxxx")=true then xxxxxxxx
と変わらないです。
結局、サブルーチンは、何となく、使いやすいので、使ってしまいます。
if mysheetExsits("xxxxxxx")=true then xxxxxxxx
このような、使い方は、絶対に、functionでなければやれないと思います。
とても平易にかつ有用に、そして、例題たっぷりに教えてくださり、どうもありがとうございました。
大変よくわかりました。なるほどってかんじでした。
No.2
- 回答日時:
こんばんは。
たぶん、サンプルのために書いただけのコードで、そのコードの完成型をご存知の上で書いているとは思います。簡単なサンプルでも、出来れば、きちんとした完成型で書いていただいたほうがよいかと思います。この質問は、わずかな差でしかありませんが、あえて、そのような質問をする場合は、それなりの力も問われることになるかと思います。
Excel VBAでは、そのような内容のコードは、あえて、サブルーチンにする必要はありませんが、いわゆる戻り値を明示的に持つようにすべきものなので、関数タイプだと思います。しかし、関数は、共有性を重視しますので、Excel VBAでは、いくら参照渡しでも、関数にキメウチ的なコードは、書きません。
MyNOend = TMYKanriBkWs1.Range("D1").CurrentRegion.Rows.Count
こういう細かい部分を抜きにして言うなら、その大きな違いは、そのメイン・プロシージャの読みやすさだと思います。参照渡しにする場合、いきなり、サブルーチン側の引数で現れるような変数は存在しません。その分だけ、手数が多くなり複雑になっていきます。メイン側で、意味が分かりにくい変数が出てきます。
Excel VBAでは、あくまでも、関数は、プロジェクト全体の共有性を持たせて、独立性は高くなる、と思います。そして、通常、1つの値を返すことを目的として作ります。また、サブルーチン・プロシージャは、同じモジュール内で操作するのが一般的です。そして、より独立性を高くするなら、クラス側で設定させます。
No.1
- 回答日時:
普通、Functionで定義したものはその定義名に結果を代入して値を返すように使います。
この例だとFMyRowCnt=TMYKanriBkWs1.Range("D1").CurrentRegion.Rows.Count
として、親の方は
Cells(1,FMyRowCnt)=123
と書けます。
このあたりはVBAだとあまりありがたみがないかも知れません。他のプログラミング言語だと引数に値をいれてもその値が変わらないという風になっているものもあります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) 標準モジュール Public mOnTime As Date Sub sample() '実行プロシ 1 2023/02/22 15:44
- Visual Basic(VBA) vbaのvlookup関数エラー原因を教えていただけないでしょうか。 3 2022/04/25 16:16
- Visual Basic(VBA) 動きっぱなしです。止め方とプロシージャの間違いを教えて下さい! 5 2022/08/15 23:08
- Visual Basic(VBA) VBAが止まります。 1 2022/09/02 14:51
- Visual Basic(VBA) ①ExcelVBAでカレンダーを作り、別のユザーフォームで日付を入力したいのですがエラーになります。 1 2023/02/17 18:39
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) VBAの指示の内容 昨日こちらでご教示頂いたのですが初心者な為、一つ一つの指示が何をやっているのかわ 2 2022/10/25 18:08
- Visual Basic(VBA) オブジェクトが見つかりません 1 2023/06/24 19:43
- Excel(エクセル) VBA カゥントで数値の範囲を規制 1 2022/05/20 06:20
- Excel(エクセル) エクセルで同じ数字同士を自動で線で結ぶVBAを教えてください 6 2022/04/26 23:13
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・「黒歴史」教えて下さい
- ・2024年においていきたいもの
- ・我が家のお雑煮スタイル、教えて下さい
- ・店員も客も斜め上を行くデパートの福袋
- ・食べられるかと思ったけど…ダメでした
- ・【大喜利】【投稿~12/28】こんなおせち料理は嫌だ
- ・前回の年越しの瞬間、何してた?
- ・【お題】マッチョ習字
- ・モテ期を経験した方いらっしゃいますか?
- ・一番最初にネットにつないだのはいつ?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・2024年に成し遂げたこと
- ・3分あったら何をしますか?
- ・何歳が一番楽しかった?
- ・治せない「クセ」を教えてください
- ・【大喜利】【投稿~12/17】 ありそうだけど絶対に無いことわざ
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・集合写真、どこに映る?
- ・自分の通っていた小学校のあるある
- ・フォントについて教えてください!
- ・これが怖いの自分だけ?というものありますか?
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・10代と話して驚いたこと
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Accessのマクロでモジュールを...
-
エクセルVBAでUserFormを起動し...
-
Access VBAで行ラベルが定義さ...
-
callで順に実行されるプロシー...
-
【Excel VBA】 WorksheetやRa...
-
或るプロシージャの呼び出し元判定
-
VBA プロシージャの名前の取得
-
Accessでグローバル変数を宣言...
-
Excel VBAで「プログラム実行」...
-
OutlookVBAで作成したマクロに...
-
DBMS_OUTPUT.PUT_LINEを実行し...
-
excel/vba/public変数
-
sp_executesqlを実行してもテー...
-
Excel2000 セルデータ検索ウィ...
-
エクセルVBAが対応できるプログ...
-
引数付のFuncitonプロシージャ...
-
Statement ignored というエラー
-
キャッシュを使わずにSELECTを...
-
全角空白のTRIMができない...
-
sqlplusのspoolで空白行出現
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Access VBAで行ラベルが定義さ...
-
Accessのマクロでモジュールを...
-
エクセルVBAでUserFormを起動し...
-
VBA プロシージャの名前の取得
-
callで順に実行されるプロシー...
-
【Excel VBA】 WorksheetやRa...
-
或るプロシージャの呼び出し元判定
-
OutlookVBAで作成したマクロに...
-
DBMS_OUTPUT.PUT_LINEを実行し...
-
Accessでグローバル変数を宣言...
-
ACCESS2007インポート時の空白...
-
エクセルVBAが対応できるプログ...
-
excel/vba/public変数
-
ACCESS マクロをモジュールに変...
-
ブックオープン時にテキストボ...
-
Excel VBAで「プログラム実行」...
-
PL/SQLのエラーについて
-
Excel2000 セルデータ検索ウィ...
-
DB2でのストアドプロシージャの...
-
Accessのプロシージャ名が勝手...
おすすめ情報