[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『Subの使いどころ』(void)
Subプロシージャを使うメリットがわかりません FunctionやPropertyと比較してSubは戻り値を返さないというのはわかるのですが それをメリットに感じることもなく全てFunctionまたはPropertyでよいのでは?と感じてしまいます Subを使うメリットと使うべき場面を教えてください
< 使用 Excel:Microsoft365、使用 OS:Windows10 >
ボタンに登録とかできないんじゃなかったっけ? https://daitaideit.com/vba-function-sub-difference/ (稲葉) 2023/03/08(水) 09:11:00
言語上SubとFunctionを区別しないのであれば、代わりに「void」キーワード相当が必要となる訳で、 逆に言えばvoidを使わない代わりにSubとFunctionに分かれているだけの、本質的には同じものだと。 そんな風に考えてます。
実際Main以外のサブルーチンはすべてFunctionで構成するプロジェクトなんて普通にザラにあると思いますけど それでもMainはやっぱvoidな訳ですから「Sub要らんじゃん」って話にはならないし、 メリットは要否判断の尺度にならないんじゃないすか?
(白茶) 2023/03/08(水) 09:41:25
個人的には
Function:オブジェクト以外の値を返す場合に使用 Property:オブジェクトを返す場合に使用 Sub :値を返さない場合に使用 と分けています。 (一見さん) 2023/03/08(水) 10:46:23
私は取り敢えず Sub()で書く。 それで何でも出来ますよね。 Functionなんて要らないんじゃないですか?
スニーカーがあれば長靴なんて要らない。 長靴があればスニーカーなんて要らない。 晴れだろうが、雨だろうが、どっちか一つでも外は歩ける。 我が家には、スニーカーと長靴がありますけど。
(半平太) 2023/03/08(水) 10:51:44
現在の私の使い方としては以下のように使い分けています Sub:値を返さなくてよい場合に使用する Function:値を返す場合に使用する(内容問わず) Property:クラスを自作した際やシートオブジェクト内に書き込んだローカル変数内の読み込み、シート内の所定の位置にある値やリストオブジェクトを呼び出す際に使用
なんか荒れた内容になってしまいましたが私が聞きたいのはSubを指定する際のメリットです 例えばあまり詳しくないので想像ですがFunctionやPropertyは値を返す性質上メモリに容量を確保しなければならないのでSubと比べれば動作が遅くなる(多分100億回ループとかしたら)から値を返さない際はSubがよいや稲葉さんの言われるようにボタンなどから呼び出しができないとか (void) 2023/03/08(水) 12:03:35
荒れてない荒れてない ^^; 普通に意見交流中でしょ
(白茶) 2023/03/08(水) 13:04:53
荒れてないと思いますよー 議論のベクトルがずれてる気はしますが・・・
>Subを指定する際のメリットです っていうのは、サブルーチン限定の話なのかしら?
配列を扱う場合 参照で渡して処理してもらいたいときは、Subで作っておくかなぁ・・・ Functionで使うときは、配列の要素の計算結果を返してもらうとかかしら。
>Property:(クラスはわかる)シートオブジェクト内に書き込んだローカル変数内の読み込み、シート内の所定の位置にある値やリストオブジェクトを呼び出す際に使用 コレの具体例が思い浮かばないんですが・・・ (稲葉) 2023/03/08(水) 13:25:52
「Subは他より単語が短いから打つのが早い」ではどうだろうか。
(物見遊山) 2023/03/08(水) 14:15:14
話が難しいので、首を突っ込まないでおこうと思ってましたが、 ちょっとだけ。単に私のお気持ちの表明です。
Subプロシジャがマクロ実行の入り口になるとかそういうことはおいといて、 単に長いコードを複数のプロシジャに分割する場合を想定して書きます
SubとFunctionで「速度とかメモリとかの実利」とかは無いんじゃないでしょうか 書きようでどっちでも書けるし。今まで感じた事無いし。
「速度とかメモリとかの実利」以外のメリットは、やはり可読性の向上なのではないかと思います。
>Sub:値を返さなくてよい場合に使用する >Function:値を返す場合に使用する(内容問わず) これが基本なので、それを明示した方が分かり易いし、そのように期待してコードを読みます。 他の言語も、返値のない関数は宣言時に明示するし、BasicではVoidがない代わりにSubがあるんでしょう。 (逆かな?Basicの歴史的には最初は関数がなかったのな?? Subがレガシー? )
値を返さない関数とか、関数の返値を変数で受け取らない とかは 読んでいて違和感ありというか「気持ち悪い」コードに感じます (長年の習慣ゆえか?Subにすればいいじゃんっておもっちゃう)
でも、どういうコードをを書こうが個人の自由で、書き方を強制することは出来ませんので、 Functionオンリーでコードを書くことのメリットを感じているならそうすればいいのではないでしょうか。
書き方の強制は、組織としてコードを書いているときに組織内の規約がある場合に、上長がすることですからね。
逆に、SubとFunctionを使い分けることのデメリットを感じているならそれを教えてほしいです。
あ、Propertyプロシジャは、プロパティに代入するように記述できる(AND代入したときの処理を書ける) のがメリットだと思っていて、プロパティの読み出しについては、通常のFunctionとあまり違いを感じた事無いです。 (´・ω・`) 2023/03/08(水) 14:38:02
ながくなったけど追記 オブジェクトのプロパティがFunctionで、メソッドがSubだとして Functionだけで書くってことは、メソッドがなくて、プロパティだけのオブジェクトって感じになりますが、 返値のない処理はやっぱりメソッドとして定義してもらうほうが分かり易いとおもいます (´・ω・`) 2023/03/08(水) 14:53:55
みなさんの意見わかりました 戻り値がないことを明示すること ボタンから等の呼び出しではFunction/Propertyは不十分であることという感じですかね
>>Property:(クラスはわかる)シートオブジェクト内に書き込んだローカル変数内の読み込み、シート >内の所定の位置にある値やリストオブジェクトを呼び出す際に使用 コレの具体例が思い浮かばないんですが・・・ リストオブジェクト等ですね抜けありました どうしても範囲に名前を付けたくない時等にSheet1.settingItem1("HOGE")のような形で使用しています
>逆に、SubとFunctionを使い分けることのデメリットを感じているならそれを教えてほしいです。 デメリットは感じていません ただ性格のせいかほとんどの処理には返り値を設け(本来返さなくてもよくてもBooleanで返したりする)処理結果を確認してるのでSubを使う頻度は少ないですね (void) 2023/03/09(木) 09:04:30
こんな風に使うってこと? 確かにObjectならConstで定義できないからなくもないけど・・・ Propertyを積極的に使って、Functionを使わない理由もあるって感じですか?
(´・ω・`)さんのおっしゃっている >プロパティの読み出しについては、通常のFunctionとあまり違いを感じた事無いです。 私も同意見なんですが、そう思うところがあって使い分けていると思うので、よろしければ教えていただけますか? 何となく、可読性を考えて 値を取るだけ = Get 処理をして戻す=Function の使い分けに拘ってらっしゃるのかと邪推してます。
Property Get settingItem1(moji As String) As Range Select Case moji Case "hoge" Set settingItem1 = Me.Range("A1") Case Else Set settingItem1 = Nothing End Select End Property
Sub test() Debug.Print Sheet1.settingItem1("hoge").Address End Sub
あとFunction使ったAPIでややこしいのが Private Declare Function GetWindowRect Lib "user32" (ByVal hWnd As LongPtr, lpRect As RECT) As Long '~~~~~~~~~~~~~~ こいつで、なんで戻り値あるのに、lpRectにほしい情報が戻ってくるねんっていつも思います。 戻り値が構造体じゃダメなんですかね?
(稲葉) 2023/03/09(木) 09:34:23
標準モジュールでPropertyを使った例(いや、「使ってみた」かな ^^;) 名前定義と連動させたRangeオブジェクトですね。
Private Property Get RangeA() As Range Dim n As Name For Each n In ThisWorkbook.Names If n.Name = "NAME_A" Then Set RangeA = n.RefersToRange Exit For End If Next End Property Private Property Set RangeA(newValue As Range) Dim n As Name For Each n In ThisWorkbook.Names If n.Name = "NAME_A" Then n.Delete Next ThisWorkbook.Names.Add "NAME_A", newValue End Property
中断⇒再開を前提とした仕組み(例:昨日の続きから...みたいな)なんかに組んでおけば、 見かけ上はRangeオブジェクトだから名前定義を意識しないでコードが書けるという。
Propertyを「あえて」使う時の理由って、だいたいこれだと思うんですよね。 「あたかも○○を扱っているかのように書きたかった」という。
あ。あと、 配列の生成を目的としたFunctionなんかは、配列を戻り値として受け取るより、 件数を戻してもらった方が都合良かったりします。(配列は引数で戻してもらうとして) 配列だけ返されると受け取り側でサイズ測らないといけなくなるんで。
IsArray とか Ubound とかしないでも
If Func1(v) Then ... とか
a = Func1(v) If a > 0 Then For i = 0 To a
という風に後続処理への流れをスムーズに書けちゃいます。
API関係ではそういったものが多い気がしますよねー。なんかいちいち。 「失敗したらゼロが返る」とか「成功したらゼロ以外が返る」とかね。 でもまあ確かにそれがないと、次行っていいのか分かんないですからねぇ。
(白茶) 2023/03/09(木) 11:50:34
Propertyはそのオブジェクトが持つ要素でFunction/Subは処理というイメージで書いています(なのでPropertyないで記述する処理は少なめにしています) 書き込んだ際VBE側の候補でも視認でわかりやすく出てくるので少し意識して書いてます
>不十分ではなく呼び出せないです。 FunctionプロシージャをSubを使わず呼び出す方法としてはWSHなどの外部アプリケーションからRunなどしてあげたり セルに書き込んで関数として呼び出したり CustomUIのOnActionで使用したり VBEを開いてマクロの実行やイミディエイトを使用という方法などがあります 不可能なことではないです (void) 2023/03/09(木) 13:12:24
ちょっと見落としてました >ほとんどの処理には返り値を設け(本来返さなくてもよくてもBooleanで返したりする)処理結果を確認してるのでSubを使う頻度は少ないですね 承知しました たぶん、どんなプログラム言語で育ってきたかor今主にどの言語をつかってるかで感じ方が違うかもしれませんね。 私はFORTRAN77の人なので、SUBROUTINE に抵抗が全然ないです (´・ω・`) 2023/03/09(木) 13:19:30
(初心者) 2023/03/10(金) 13:59:01
> 戻り値がないことを明示すること
そんなこと意識してSubを使っている人は居ないでしょう。 当たり前の事なんだから。
自分のスタイルに合わないステートメントってだけでしょう? 一般的とは言えないスタイルの視点から、メリットとか言われても困惑するだけです。
(半平太) 2023/03/10(金) 17:00:38
もう終わった感が強いですが >ボタンに登録 についてのみ
https://daitaideit.com/vba-function-sub-difference/ でも書かれていますが、マクロ登録ダイアログのマクロのリストに上がらないから登録できない的なニュアンスですが
リストにないなら手打ちで入力すればよいだけじゃないですか?↑なら「TEST2」と Option Private Module 宣言したモジュール内のSUBも同様にリストには出ませんが。登録はできますよね。
(チオチモリン) 2023/03/17(金) 10:52:40
オブジェクト指向的な考え方になると思いますが、
なにかしらのデータを管理しているオブジェクトがあるとして、
データを設定、追加する場合はSub、
計算結果やデータを取り出したい場合はFunctionにしてると
コードが読み書きしやすかった気がします。
(たつ) 2023/03/17(金) 11:21:28
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.