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

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

ただいまの
回答率

90.34%

  • VBA

    1906questions

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

見やすい 変数の 宣言位置

解決済

回答 6

投稿

  • 評価
  • クリップ 0
  • VIEW 979

kamikazelight

score 126

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

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

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

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

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

Sub tset()
    Dim i As Integer
    For i = 1 To 10
        Dim j As Integer
        j = j + 1
        Debug.Print j
    Next i
End Sub


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

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

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

checkベストアンサー

+5

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

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

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

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

それ以外の理由としては

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

などがあります。

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/26 09:41

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

    キャンセル

  • 2018/07/26 20:26

    実際の所、私が書く場合は使う直前で統一しています。

    書き方が上手ければ(十分な部品化が出来ていれば)、どちらの書き方でも大差は無い、という例と捉えていただければ。

    キャンセル

  • 2018/07/27 11:38

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

    キャンセル

+3

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/26 09:08 編集

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

    キャンセル

+2

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/26 09:32

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

    キャンセル

+2

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/26 09:11

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

    キャンセル

+1

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

【制限の例】

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/26 09: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 は読みやすくするために使う時と 税などの今後変わる可能性の値を入れるために
    使うことがあると思うのですが 後者の場合は 書き換えやすいように行頭に置いた方がいいのでしょうか
    それともこれも使う直前の方がいいのでしょうか...?

    キャンセル

  • 2018/07/26 09:40

    JavaScriptのconstとVBAのConstではかなり性格が違いますね。

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

    キャンセル

  • 2018/07/26 09:54

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

    キャンセル

-2

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

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

変数の宣言を先頭に書くことについてですが…、
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/11/08 22:45

    アライメントは初めて聞いたので勉強になりました。ただその後の説明にまとまりがなく、折角だれも書かなかった切り口を紹介してるのにもったいないです。

    VBAの再帰処理が50回でスタック不足とのことですが、末尾再帰を実装していない他の言語と比較されたのでしょうか。
    また、ai2018さんが経験された平衡二分探索木のエラーは再帰によるスタック不足とは関係ないと推測しています。その理由として関数呼び出し時にスタックされたデータは、呼び出し元に戻るとクリアされるはずだからです。

    意図されたことではないと思いますが、読んだ初心者を誤った方向(VBAで再帰はやめよう・メモリを節約するためアライメントを意識すべきだ)に導く可能性があるため低評価としました。

    マシンに優しいプログラミングは時代遅れになりつつあり、これからは人間にやさしいコードが良いコードになると思われます。書籍「ハッカーと画家」の一読をオススメします。

    キャンセル

  • 2018/11/09 00:01 編集

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

    キャンセル

  • 2018/11/10 20:27

    誤った方向に導いているつもりはありませんが、「再起をやめよう」「アライメントを意識すべきだ」が誤った考え方?これらも一つの考え方であってそれを誤りとするのはどういうことでしょう。何をもって誤りなんでしょうか。
    じゃあ、私の述べた意見は必要ないと?初心者を惑わすような意見は始めから言うなということでしょうか。

    マシンにとって優しいコードより、人間にとって優しいコードが「良い」?それも、何をもってして「良い」なのかわからない。

    作成したvbaを作成者自身で使うだけならまだしも、もし、それを企業内で、さらには、外部の方に使っていただくようなものなら、どう考えますか?

    極端な話、他人が作成したプログラムがメモリを馬鹿食いするようなものならどうなんでしょうか。

    あぁ、これも「初心者を惑わす」意見なんですね。申し訳ない。もう、これ以上は言わない。

    キャンセル

  • 2018/11/11 06:09

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

    キャンセル

  • 2018/11/11 12:46

    ai2018さん。気分を害されたようで、申し訳ないです。

    低評価をつけたのは決して私があなたの意見を気にくわないからではなく、個人的な信条(スピード至上主義やマシンリソース節約至上主義はナンセンスであり、シチュエーションによって手段は柔軟に使い分けるべきだ)に基づいた単なる個人的なフィードバックのつもりでした。

    アライメントの紹介は有用だと思っていますので、ai2018さんの意見はとても勉強になりました。
    私はai2018さん自身をマシンリソース節約至上主義者だとは考えていません。シチュエーションによって柔軟に手段を選択すべきだという点については同意いただけると思っています。

    ただ書かれた回答は少し偏りを感じたので、私が初心者ならマシンリソース節約至上主義の虜になるだろうなということで、低評価としました。あくまでこの回答に限定した私個人の所感であり、ai2018さんの紹介した事実や考えや人間性を否定したつもりはありません。

    おっしゃる通りメモリを意識したプログラムが必要とされるシチュエーションは確かに存在します。ですので、折角アライメントを紹介されたのだから、具体的にそうしたシチュエーションを述べられていたり、平衡二部探索木の再帰についてもエラーになる再現コードが掲載されていたりすれば、良回答になったのではないかと。そういう意味で冒頭でもったいないと感想を書きました。

    さて、ご質問の件ですが、企業内や、外部の方に使っていただくものであれば、私はバグの出しにくさとメンテナンス性を重視しますので、基本的には人が読んで分かりやすいコードを書くよう心がけるます。パフォーマンスに有意差が出るケースでは一部高速化のテクニックを採用しますが、コードの分かりやすさを犠牲にすることもあるので、実用上の有意差が出なければ基本的にはリーダブルコードを優先させます。

    メモリを馬鹿食いし、それが他に悪影響を与えるプログラムは、いただけませんね。もし誤った再帰の適応が原因なら、再帰をやめるべきでしょう。アライメントを意識して大きな改善が見込めるならそうすべきでしょう。
    ただし、ご自身も極端な話と書かれているとおり、これは極端な話ですね。

    ai2018さんの回答は、メンテナンス性を重視したコードを書いた後、パフォーマンスが期待値を下回った場合に、知識として持っておくと有用だと思いましたので、その点は高評価です。

    ただteratailには評価軸が一つしかないので、低評価ボタンを押さざるを得なかった点はごめんなさい。

    キャンセル

  • 2018/11/11 13:34

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

    キャンセル

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

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • VBA

    1906questions

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