Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


4705 / 13644 ツリー ←次へ | 前へ→

【55033】プロシージャを分けて実行したい ぺっぱー 08/4/11(金) 18:11 質問[未読]
【55034】Re:プロシージャを分けて実行したい neptune 08/4/11(金) 18:47 回答[未読]
【55035】Re:プロシージャを分けて実行したい ichinose 08/4/11(金) 19:08 発言[未読]
【55036】大変、参考になりました! ぺっぱー 08/4/11(金) 20:34 お礼[未読]
【55037】Re:大変、参考になりました! neptune 08/4/11(金) 21:15 発言[未読]
【55039】Re:大変、参考になりました! ぺっぱー 08/4/12(土) 0:04 お礼[未読]

【55033】プロシージャを分けて実行したい
質問  ぺっぱー  - 08/4/11(金) 18:11 -

引用なし
パスワード
   こんにちわ。お世話になります。

ユーザーフォームのOptionButtonのイベントプロシージャを
書いているのですが、行数が長すぎてしまうため
「プロシージャが大きすぎます」とエラー文が出てしまいました。

そこで、途中までイベントを書いて
残りを標準モジュール内に書き、Callを使って呼び出そうと考えました。
ですが、標準モジュール内に書いた文章にはフォーム内で使われている
TextBoxのオブジェクト名や、フォーム内で使用している変数が載っています。

つくった物の一部分を乗せます。(はしょって書いてますが大体こんな感じです。)
オプションボタンが3つあり、それぞれクリックするとBox1に
値が入力されます。

Private Sub OpButton0_Click()
  If OpButton0 = True Then
    Box1.Value = Empty
  Else
  End If
End Sub

Private Sub OpButton1_Click()
Dim Money1 As Integer
Money1 = 500
  If OpButton1 = True Then
    Box1.Value = Money1
  Else
  End If
End Sub

Private Sub OpButton2_Click()
Dim Money2 As Integer
Money2 = 1000
  If OpButton2 = True Then
    Box1.Value = Money2
  Else
  End If
End Sub

■各ボタンがTrueになったときに、書き込む部分が多くなってしまったので、
Callを使いました。以下に書きます。

■ユーザーフォーム内↓
Private Sub OpButton0_Click()
  If OpButton0 = True Then
    Box1.Value = Empty
  Else
  End If
End Sub

Private Sub OpButton1_Click()
Dim Money1 As Integer
Money1 = 500
  If OpButton1 = True Then
    Call 収納データ1
  Else
  End If
End Sub

Private Sub OpButton2_Click()
Dim Money2 As Integer
Money2 = 1000
  If OpButton2 = True Then
    Call 収納データ2
  Else
  End If
End Sub

■標準モジュール内↓

Public Sub 収納データ1()
  Box1.Value = Money1
End Sub
Public Sub 収納データ2()
  Box1.Value = Money2
End Sub

…これだと、変数が設定されていません。とエラーが出てしまうのですが、
エラーが出ないように正しくデータを読み取らせるにはどうすれば
よいのでしょうか?

もう一度標準モジュール内で変数の設定をし直す必要があるのでしょうか?
その場合の書き方もできれば教えてほしいです。
(特にフォーム内で使用されているオブジェクトに関しての設定について)

よろしくおねがいします。

【55034】Re:プロシージャを分けて実行したい
回答  neptune  - 08/4/11(金) 18:47 -

引用なし
パスワード
   ▼ぺっぱー さん:
こんにちは

>変数が設定されていません。
の原因は
>Box1.Value = Money1
のBoxがどこのものかがわからないためです。Excelには判らないのです。
Money1がどこで宣言されているのか良く見てませんが、恐らくそれも
見えてないのではないでしょうか?
その親オブジェクトからたどって行ってboxを指定しなければなりません。

手っ取り早い解決方法は
分けたプロシージャをformモジュール内に書きましょう。

それで駄目なら、前述の書き方をしましょう。

【55035】Re:プロシージャを分けて実行したい
発言  ichinose  - 08/4/11(金) 19:08 -

引用なし
パスワード
   ▼ぺっぱー さん:
こんばんは。
>
>ユーザーフォームのOptionButtonのイベントプロシージャを
>書いているのですが、行数が長すぎてしまうため
>「プロシージャが大きすぎます」とエラー文が出てしまいました。
>
>そこで、途中までイベントを書いて
>残りを標準モジュール内に書き、Callを使って呼び出そうと考えました。
>ですが、標準モジュール内に書いた文章にはフォーム内で使われている
>TextBoxのオブジェクト名や、フォーム内で使用している変数が載っています。
まず、標準モジュールに記述すべきプロシジャーか否かをよくよく検討してみてください。

このような場合に標準モジュールにプロシジャーを記述する理由としては、

 そのプロシジャーが他のモジュールからも呼び出される可能性があるような
 汎用的な機能を持ったプロシジャーである場合が考えれます。
 例えば、印刷関連を一手に引き受けてくれるプロシジャーとか
 いろんな種類のファイルの読み込みや書き込みを行うプロシジャーといったように
 再利用可能なプロシジャー等。

 今回の標準モジュールに記述したプロシジャーがそのような汎用性を持っているか
 否かを検討してみてください。

 もし、標準モジュールに記述した内容がこれは、このユーザーフォームに深く関わったコードで汎用的なコードではない と判断したならば、このユーザーフォーム内に記述するべきです。プロシジャーは機能分割して関わりのあるコードは、同じモジュール内に
記述するべきですよ(複合設計法より)!!
このような考え方は、御自分でオブジェクトを作成する時に(クラスモジュールの作成)大いに役に立つと思います。

検討してみてください。


>
>つくった物の一部分を乗せます。(はしょって書いてますが大体こんな感じです。)
>オプションボタンが3つあり、それぞれクリックするとBox1に
>値が入力されます。
>
>Private Sub OpButton0_Click()
>  If OpButton0 = True Then
>    Box1.Value = Empty
>  Else
>  End If
>End Sub
>
>Private Sub OpButton1_Click()
>Dim Money1 As Integer
>Money1 = 500
>  If OpButton1 = True Then
>    Box1.Value = Money1
>  Else
>  End If
>End Sub
>
>Private Sub OpButton2_Click()
>Dim Money2 As Integer
>Money2 = 1000
>  If OpButton2 = True Then
>    Box1.Value = Money2
>  Else
>  End If
>End Sub
>
>■各ボタンがTrueになったときに、書き込む部分が多くなってしまったので、
>Callを使いました。以下に書きます。
>
>■ユーザーフォーム内↓
>Private Sub OpButton0_Click()
>  If OpButton0 = True Then
>    Box1.Value = Empty
>  Else
>  End If
>End Sub
>
>Private Sub OpButton1_Click()
>Dim Money1 As Integer
>Money1 = 500
>  If OpButton1 = True Then
    Call 収納データ1(Box1,Money1)
>  Else
>  End If
>End Sub
>
>Private Sub OpButton2_Click()
>Dim Money2 As Integer
>Money2 = 1000
>  If OpButton2 = True Then
    Call 収納データ1(Box1,Money2)
>  Else
>  End If
>End Sub
>
>■標準モジュール内↓

Public Sub 収納データ1(byval txt as msforms.textbox,byval vl as integer)
  txt.Value = vl
End Sub
>Public Sub 収納データ2()
>  Box1.Value = Money2
>End Sub
ちなみにこういう場合は、なるべくパラメータ渡しでデータを受け渡すことを
考えてください。

理由は、

www.vbalab.net/vbaqa/c-board.cgi?cmd=one;no=28808;id=excel

と以前記述しました。

【55036】大変、参考になりました!
お礼  ぺっぱー  - 08/4/11(金) 20:34 -

引用なし
パスワード
   neptuneさん、ichinoseさん。
とても勉強になる回答ありがとうございました。

neptuneさんの言っていた
>>その親オブジェクトからたどって行ってboxを指定しなければなりません。
ということの答えが

ichinoseさんの言っている
>>Call 収納データ1(Box1,Money2)
↑のことで、
>>Public Sub 収納データ1(byval txt as msforms.textbox,byval vl as integer)
>>  txt.Value = vl
>>End Sub
と指定すればよかったのですね。

byval txt as msforms.textboxのように、
フォームのオブジェクトを示す書き方がわからなかったので
とても助かりました。
ちなみに、
>>Call 収納データ1(Box1,Money2)
というのが「パラメーター渡し」というやつなんですね?
きちんと頭にいれときます。

また、フォーム内で使用しているオブジェクト名を
byval txt as myforms.textbox
    ↑(Box1じゃなくていい)
ここに入れなくても、別のもので代用できるということも
はじめて知りました。

まだまだ勉強不足なところが多いので、また質問することが
あると思いますが、その時もよろしくお願いします。
ありがとうございました!

【55037】Re:大変、参考になりました!
発言  neptune  - 08/4/11(金) 21:15 -

引用なし
パスワード
   ▼ぺっぱー さん:
こんにちは

>neptuneさんの言っていた
>>>その親オブジェクトからたどって行ってboxを指定しなければなりません。
>ということの答えが
>
>ichinoseさんの言っている
>>>Call 収納データ1(Box1,Money2)
>↑のことで、
>>>Public Sub 収納データ1(byval txt as msforms.textbox,byval vl as integer)
>>>  txt.Value = vl
>>>End Sub
>と指定すればよかったのですね。
違います。
public sub 収納データ()
userform1.box1.value=変数
end sub
というような書き方になります。変数についてもどの様なスコープを持たせて
どこに宣言しているかによって書き方が違ってきます。

ichinoseさんの紹介されている方法は
Box1の参照を収納データ1プロシージャに引数として渡しています。
これを「参照渡し(ByRef)」といいます。

私の紹介した方法とは考え方が全く違うので、又勉強して下さい。

【55039】Re:大変、参考になりました!
お礼  ぺっぱー  - 08/4/12(土) 0:04 -

引用なし
パスワード
   neptuneさん、こんばんわ。

ichinoseさんの方法とはまた違う方法を
紹介していたのですね。どうすればフォーム内のオブジェクトと
標準モジュール間を繋ぐか、わからなかったもので。
お二人とも同じ手段を教えていたものかと勘違いしてしまいました。
ichinoseさんの方法とは別にneptuneさんの方法で作ってみました。

■ユーザーフォーム内↓
Private Sub OpButton1_Click()
  If OpButton1 = True Then
    Call 収納データ
  Else
  End If
End Sub

■標準モジュール内↓ 
Public Sub 収納データ()
Dim Money As Integer
Money = 1000
  UserForm1.Box1.Value = Money
End Sub

という書き方で、エラーが出ずに動いてくれました。
今のところ、2パターンの方法しかわかっていませんが
これを足掛かりに、本を片手に勉強しなおしてみます。

わざわざ返信していただいて、ありがとうございました!

4705 / 13644 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free