質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.53%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

6回答

33686閲覧

見やすい 変数の 宣言位置

kamikazelight

総合スコア305

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

1グッド

0クリップ

投稿2018/07/25 09:10

変数の宣言は最初でなくてもいいのでしょうか

最近コードの再利用などを考えるようになってから
多少の実行速度の差 等よりも見やすさを重視しているのですが、
変数の宣言位置に疑問を抱くようになりました。

その中で不要になったコードを消した際にそこで使われていた
変数が宣言されたまま取り残されていることが多々あることに気づきました。

その対策として変数を使う場所で宣言した方が管理がしやすいのではないかと
思うようになり一度試しに過去の質問で出してみたところ
「→VBでの文化はちょっと分からないんですがJavaなどでは変数の宣言は使う前がいいと言われてますね。」と言われたので
やめました。

でも実際のところ変数の宣言を途中で行ったとしてもバグの原因にはそんなにならないですよね?
極端な話

VBA

1Sub tset() 2 Dim i As Integer 3 For i = 1 To 10 4 Dim j As Integer 5 j = j + 1 6 Debug.Print j 7 Next i 8End Sub

こんなことをしてもエラーにならず ちゃんとJの値も保持されますし...

でも、文化として定着しているからにはそれなりの理由があるのではないかという
考えが頭をよぎり
変えたほうが見やすい or 変えない方がいい の葛藤で毎度の様に手が止まります...

皆さまはどう考えますか?
教えて頂きたいです。

na-01👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

ベストアンサー

人によって変わると思いますが、私は「変数を使う場所で宣言」派です。

理由の一つは、質問内でも言及されている

不要になったコードを消した際にそこで使われていた

変数が宣言されたまま取り残されていることが多々あることに気づきました。

というコードを見ることが多く、それを反面教師としたためです。

それ以外の理由としては

  • 変数の有効範囲を狭めるため(コードを読むとき考慮すべき事項を減らす)
  • 処理の一部をプロシージャに分離するときに、コピーする範囲が少なくて済む

などがあります。

「最初で宣言する」派の意見の一つとして、
「まとめて宣言しておいた方が、どんな変数か確認しやすい」というものもありますが、
Ctrl + IShift + F2といったショートカットキーを使えば簡単に確認出来るため、理由としては弱いと考えています。

ただ、「一画面に容易に収まる程度の短いプロシージャ」であれば最初でまとめて宣言した方が見やすく感じることもあります。

投稿2018/07/25 10:12

imihito

総合スコア2166

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/26 00:41

他の方も先頭行で宣言して 不要になった変数の宣言の消し忘れがあるのですね >ただ、「一画面に容易に収まる程度の短いプロシージャ」であれば最初でまとめて宣言した方が見やすく感>じることもあります。 これは悩みどこですが一画面に入るときは先頭行で宣言そうでないときは使う直前とすると 線引きが曖昧になると思うのですが先頭行で宣言しているプロシージャとそうでないものが混在していてもいいのでしょうか? 同じモジュール内くらいは統一した方がいいでしょうか?
imihito

2018/07/26 11:26

実際の所、私が書く場合は使う直前で統一しています。 書き方が上手ければ(十分な部品化が出来ていれば)、どちらの書き方でも大差は無い、という例と捉えていただければ。
kamikazelight

2018/07/27 02:38

やはり、統一はしたほうが良いのですね。 ありがとうございました。
guest

0

私も先頭ではなく使用する直前がベストだと思います。

「→VBでの文化はちょっと分からないんですがJavaなどでは変数の宣言は使う前がいいと言われてますね。」と言われたのでやめました。

この部分で該当の過去の質問のベストアンサーを見てみましたが、kamikazelightさんが言ってる「変数を使う場所で宣言」と、unz.horiさんが言ってる「使う前」は、どちらも「使用する直前」を指しているように思えます。やめてしまったのは勘違いだったのでは。

投稿2018/07/25 14:40

thom.jp

総合スコア686

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/26 00:35 編集

勘違いしていたみたいですね^^; たぶん別の方に頂いた例題が先頭宣言だったのでごっちゃになってしまったのでしょう... ありがとうございました。
guest

0

下記のリンク先では、変数を使用する直前で宣言した場合のメリットを実例を含めて分かり安く解説しています。
私自身、今まで習慣的に最初で宣言していましたが、これを読んで、直前宣言派に転向しました。

VBA ローカル変数は使用する直前で宣言する - t-hom’s diary

投稿2018/07/25 11:51

hatena19

総合スコア33551

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/26 00:11

分かりやすいサイトでした。 紹介してくださりありがとうございました。
guest

0

昔のコンパイラや言語では変数宣言を先頭で行う必要があった、というのが今も残っている……というのが正直なところでしょう。

個人的には「初期値を決定する時点で宣言する」ですね。
特殊な理由で初期値を設定できない場合(まずありませんが)は先頭に持っていきますが。

投稿2018/07/25 10:19

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/26 00:32

文化として定着しているからにはそれなりの理由があるからと警戒していたのですが 先頭で宣言するのは 名残 なんですね ありがとうございました。
guest

0

制約あるいはコーディングルールがない限りは、使う直前に宣言したほうがわかりやすいでしょう。特に、JavaScriptでconstな変数を、ほかの値から生成するような場合、値が揃ったより後に宣言文を書くしか方法がありません。

【制限の例】

  • C言語では、C99以前には関数の先頭、あるいはブロックの先頭でしか変数宣言が認められていませんでした。
  • JavaScriptのvarは「巻き上げ」と言って宣言より上でもアクセスできてしまうので、先頭に書くほうが、変数の有効範囲と一致するようになるので逆にわかりやすくなります。

また、Rubyでは変数に明示的な宣言をする構文がなく、はじめての代入が宣言になるので、「先に宣言だけ」することがそもそもできません。

投稿2018/07/25 10:24

maisumakun

総合スコア145025

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kamikazelight

2018/07/26 00:28

JavaScript は 宣言より上でもアクセスできてしまう のですね 初めて知りました。 JavaScriptでconstな変数を、ほかの値から生成 できるんですね VBAだと Sub tset() Dim A As Long Dim B As Long A = 1 B = 2 Const C As Long = A + B Debug.Print C End Sub と書くと「定数式が必要です。」っと出てしまい Const の値には変数が使えないっぽいですね 主に Const は読みやすくするために使う時と 税などの今後変わる可能性の値を入れるために 使うことがあると思うのですが 後者の場合は 書き換えやすいように行頭に置いた方がいいのでしょうか それともこれも使う直前の方がいいのでしょうか...?
maisumakun

2018/07/26 00:40

JavaScriptのconstとVBAのConstではかなり性格が違いますね。 消費税率のような、システム全体で一元管理すべき定数であればグローバル、あるいは何かのオブジェクト内に宣言するのが適当かと思います。
kamikazelight

2018/07/26 00:54

それもそうですね... すみませんでした。 ではとある表から抜粋した情報を別表に書き出す処理があり 抜き出す 列数 をConst で宣言していた.... っとします。 この場合はどうでしょうか?
guest

0

解決済でもう誰も見ていないかとは思いますが…。

※以下は私の考えであり、かつ、勉強不足があるため、間違いだらけかもしれません。

変数の宣言を先頭に書くことについてですが…、
C/C++は先頭に書かなくてはならないという制約がありましたが、そもそも変数はスタックメモリに配置されるもので、記述する順番によってはアライメントの影響を受け、スタックメモリを余計に消費することがあったりする。そのアライメントを意識してプログラムするような企業なんかもあったりする。今はメモリも大容量なのでその辺どうなのかはわかりませんが。
vbaも宣言する順番によってアライメントの影響を受ける。

例えば、以下の順番で宣言したもの
Dim a As Long
Dim b As Long
Dim c As Long
Dim d As Byte
Dim e As Byte
を、次のような順番にしたら…
Dim a As Long
Dim d As Byte
Dim b As Long
Dim e As Byte
Dim c As Long
後者の方が前者より6バイトほど余計にスタックメモリを消費する。(多分)あ、32ビットCPUで。

たかが数バイトじゃないか、と言われればそうなんですが、
vbaって再起処理を50回くらいループさせるだけでスタック不足のエラーが起こってしまうなど、とかくスタック領域が小さいように思える。平衡二部探索木を再起にしてもエラーが起こったり、たかだか深さlog(n)程度やのになんでやねん!と思ったことがある。今のvbaはどうかは知りませんが、その辺を考えると数バイトももったいないかなと思ったりもします。

しかし、vbaは変数が何バイト使われるかがわからないようになっていて、
例えばObject型変数はポインタ変数としてスタックメモリ上に4バイト(+インスタンスがヒープメモリだかなんだかに配置される)、String型変数もポインタ変数としてスタックメモリ上に4バイト(BSTRへの参照)、など、普通にはわからない事だらけ。あ、32ビットの場合です。

そんな状況でアライメントもクソもあるかと思ったりもします。

ここまでアライメントの事について書いておきながら、結局はどうでもいいんかい、という事になりますw

まー、要するに、
宣言する位置は、それぞれの考え、それぞれの思いのままになさったらいいんじゃないでしょうか。
という事ですw

投稿2018/10/30 15:26

ai2018

総合スコア18

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thom.jp

2018/11/08 13:45

アライメントは初めて聞いたので勉強になりました。ただその後の説明にまとまりがなく、折角だれも書かなかった切り口を紹介してるのにもったいないです。 VBAの再帰処理が50回でスタック不足とのことですが、末尾再帰を実装していない他の言語と比較されたのでしょうか。 また、ai2018さんが経験された平衡二分探索木のエラーは再帰によるスタック不足とは関係ないと推測しています。その理由として関数呼び出し時にスタックされたデータは、呼び出し元に戻るとクリアされるはずだからです。 意図されたことではないと思いますが、読んだ初心者を誤った方向(VBAで再帰はやめよう・メモリを節約するためアライメントを意識すべきだ)に導く可能性があるため低評価としました。 マシンに優しいプログラミングは時代遅れになりつつあり、これからは人間にやさしいコードが良いコードになると思われます。書籍「ハッカーと画家」の一読をオススメします。
TanakaHiroaki

2018/11/08 15:04 編集

thom.jpさんと同意見です。 質問は「見やすい 変数の 宣言位置」、つまりリーダブルコードを追及する中で、 For-Next 構文中の変数宣言が、VBAであり得るのかを回答することが求められ ていたと理解します。 私はパフォーマンスよりも管理を重視した変数宣言が美しいコードと考えます。
ai2018

2018/11/10 11:27

誤った方向に導いているつもりはありませんが、「再起をやめよう」「アライメントを意識すべきだ」が誤った考え方?これらも一つの考え方であってそれを誤りとするのはどういうことでしょう。何をもって誤りなんでしょうか。 じゃあ、私の述べた意見は必要ないと?初心者を惑わすような意見は始めから言うなということでしょうか。 マシンにとって優しいコードより、人間にとって優しいコードが「良い」?それも、何をもってして「良い」なのかわからない。 作成したvbaを作成者自身で使うだけならまだしも、もし、それを企業内で、さらには、外部の方に使っていただくようなものなら、どう考えますか? 極端な話、他人が作成したプログラムがメモリを馬鹿食いするようなものならどうなんでしょうか。 あぁ、これも「初心者を惑わす」意見なんですね。申し訳ない。もう、これ以上は言わない。
TanakaHiroaki

2018/11/10 21:09

ご質問者の「最近コードの再利用などを考えるようになってから・・・」は、個人利用と理解しますので、下記記事の考え方が質問者への回答にふさわしいと思います。 https://thom.hateblo.jp/entry/2015/12/21/043948
thom.jp

2018/11/11 03:46

ai2018さん。気分を害されたようで、申し訳ないです。 低評価をつけたのは決して私があなたの意見を気にくわないからではなく、個人的な信条(スピード至上主義やマシンリソース節約至上主義はナンセンスであり、シチュエーションによって手段は柔軟に使い分けるべきだ)に基づいた単なる個人的なフィードバックのつもりでした。 アライメントの紹介は有用だと思っていますので、ai2018さんの意見はとても勉強になりました。 私はai2018さん自身をマシンリソース節約至上主義者だとは考えていません。シチュエーションによって柔軟に手段を選択すべきだという点については同意いただけると思っています。 ただ書かれた回答は少し偏りを感じたので、私が初心者ならマシンリソース節約至上主義の虜になるだろうなということで、低評価としました。あくまでこの回答に限定した私個人の所感であり、ai2018さんの紹介した事実や考えや人間性を否定したつもりはありません。 おっしゃる通りメモリを意識したプログラムが必要とされるシチュエーションは確かに存在します。ですので、折角アライメントを紹介されたのだから、具体的にそうしたシチュエーションを述べられていたり、平衡二部探索木の再帰についてもエラーになる再現コードが掲載されていたりすれば、良回答になったのではないかと。そういう意味で冒頭でもったいないと感想を書きました。 さて、ご質問の件ですが、企業内や、外部の方に使っていただくものであれば、私はバグの出しにくさとメンテナンス性を重視しますので、基本的には人が読んで分かりやすいコードを書くよう心がけるます。パフォーマンスに有意差が出るケースでは一部高速化のテクニックを採用しますが、コードの分かりやすさを犠牲にすることもあるので、実用上の有意差が出なければ基本的にはリーダブルコードを優先させます。 メモリを馬鹿食いし、それが他に悪影響を与えるプログラムは、いただけませんね。もし誤った再帰の適応が原因なら、再帰をやめるべきでしょう。アライメントを意識して大きな改善が見込めるならそうすべきでしょう。 ただし、ご自身も極端な話と書かれているとおり、これは極端な話ですね。 ai2018さんの回答は、メンテナンス性を重視したコードを書いた後、パフォーマンスが期待値を下回った場合に、知識として持っておくと有用だと思いましたので、その点は高評価です。 ただteratailには評価軸が一つしかないので、低評価ボタンを押さざるを得なかった点はごめんなさい。
pepperleaf

2018/11/11 04:34

プラスもマイナスも付けていませんが、、、 今時、アライメントを考えるのは、特殊な場合だけではないでしょうか? 確かに、C言語は(大抵)スタックにローカル変数を置きます。で、int, char, int なんて並べたら、効率が悪いかも知れません。 ... て、今時のコンパイラではどうなのでしょうか? 最適化で並べ替えくらいはしないのか? また、コンパイラは、必要に応じて勝手に内部変数を作成する事があります。 そして、VBAの場合、この考えが通用するのか? それより、まずは、見やすいコードではないでしょうか。 また、下手な人の高速化/効率化よりも、コンパイラの最適化の方が圧倒的に効率が良いです。 そして、こうした細かな最適化より、無駄なコードは無いか? アルゴリズムは適切かを考えるのが優先と思います。 (あと、メンテナンスは容易か)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.53%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問