- 締切済み
VBAに関して、プロシージャが大きく悩んでいます。
回答よろしくおねがいします。 現在、全国の各都道府県のある数値を測るプログラムを改良しています。 入力画面に人口等の数値を入力すれば自動的に計算が行われるプログラムなんですが、現在改良する際にプログラムが大きくなりすぎて悩んでいます。 入力画面はユーザーフォームで作成してあるのですが、改良を行うとプロシージャが大きすぎますと警告が出ます。 そこでprivate subを用いて3つにプログラムを分け、最後にcallでそれらを選択したが計算されませんでした。 元々あったプログラム(改良前のものなので普通ならばできるはず)をprivate sub1、private sub2、private sub3として同じユーザーフォーム内に3つに分割しました。それぞれきちんと定義はしてあります。最後にcallで3つを呼び出したのですが、何一つ計算されませんでした。エラーが出るわけでもありません。入力画面にて入力された数値はひとつのprivate subにのみ有効なんですか? 現在この問題に対して考えているのは、本筋(ユーザーフォーム内のプログラム)を定義のみとし、ifやcallを使い別のモジュールで計算させ結果だけ本筋に戻すことを考えています。こういったことは可能でしょうか? 可能な場合は具体的にどういうプログラムになるのか教えていただければありがたいです。 よろしくお願いいたします。
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- chayamati
- ベストアンサー率41% (260/624)
- WindFaller
- ベストアンサー率57% (465/803)
こんにちは。 他の方がお答えになっていない点を回答させていただきます。 >改良を行うとプロシージャが大きすぎますと警告が出ます。 「プロシージャが大きすぎます」というのは、残念ながら、コードの書き方そのものが失敗しています。確かに行数が多いという事実の他に、コードにセル座標が散りばめてあるということで、それは、VBAのコードとして、マクロの用をなさないのです。私は、何万行というコードでシステムを書いたことがありますが、そのような警告表示はでません。 そういう場合は、設計の段階から、構造的に組み立て、はじめから書きなおさないと、直しようがないのです。 >元々あったプログラム(改良前のものなので普通ならばできるはず)をprivate sub1、>private sub2、private sub3として同じユーザーフォーム内に3つに分割しました。 同じユーザーフォーム内にあるのなら、ローカルモジュールへのPrivate ステートメントでも問題はないのですが、その内容にもよります。 あまり、いろんなことを言っても混乱するだけでしょうから、丁寧に、ステップ(F8)でコードを追いかけてみることでしょうか、それ以上は、今の段階では分かりません。
- tsubuyuki
- ベストアンサー率45% (699/1545)
> 入力画面にて入力された数値はひとつのprivate subにのみ有効なんですか? とりあえず、ここに関して簡単に説明すると、 プロシージャのはじめで宣言、つまり以下 Dim AAA As Integer Private Sub Sub1() AAA=10 Call Sub2 End Sub Private Sub Sub2() Range("A1")=AAA Call Sub3 End Sub Private Sub Sub3() Range("A2")=AAA End Sub のような構成にすると、全てで同じ変数を使えます。 良かったら、新規ブックにでも貼り付けてお試しくださいませ。 Private Sub ~ Sub 内で宣言すると、その中でしか使えません。 で、大きすぎる件ですが・・ 残念ながら、私もそんなに大きなモノを組んだことが無いので何とも言えません。 取り得る手段としては、やはり分割するとか、無駄な処理を省くだとか、 逆に同じ処理をするところをなんとかループさせるとか・・ そのくらいしか思いつかないです。 中身を見れば何か思いつくかもしれませんが、ココではそれも不可能です。 1番さんもおっしゃる通り、ツールを駆使して地道にデバッグしていくしかないかなぁ・・ と言うのが正直なところです。
- ap_2
- ベストアンサー率64% (70/109)
> 何一つ計算されませんでした。 たぶん・・・関数間で値の受け渡しができてないと思う。"変数"は関数内でのみ有効です。 > 別のモジュールで計算させ結果だけ本筋に Private宣言しなければ、他モジュールから呼び出せます。Public Sub か、Sub (デフォルトがPublicなので省略可能)。 'こんな感じで Private Sub 元の関数() 変数 = フォーム '取得 Call 処理1(変数) '情報渡す Call 処理2(変数) フォーム = 変数 '出力 End Sub '~別モジュール~ Sub 処理1(引数) 引数 = 引数 + 1 '引数は読書可能 End Sub ※モジュール間で関数名が重複する場合は、Module1.処理1()と区別します。 > プロシージャが大きすぎますと警告 相当なサイズですよね。ループ使うとか、処理を工夫した方がよさそうです。配列を使えるとループしやすいかも。 言ってるコトはソレっぽいので、ちょっと入門書かじれば出来るはず。「ステップ実行」「ブレイクポイント」「ローカルウィンドウ」あたりは便利な機能なので、使えるようになっとくといいですよ。 ・・・こんな感じでよいかな?