Excel VBA質問箱 IV

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

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


3215 / 13646 ツリー ←次へ | 前へ→

【63524】callで呼び出すとき タルジャ 09/11/15(日) 19:58 質問[未読]
【63526】Re:callで呼び出すとき よろずや 09/11/15(日) 21:12 回答[未読]
【63527】Re:callで呼び出すとき ichinose 09/11/15(日) 21:35 発言[未読]
【63528】Re:callで呼び出すとき タルジャ 09/11/15(日) 22:30 お礼[未読]
【63532】Re:callで呼び出すとき ichinose 09/11/16(月) 7:11 発言[未読]
【63541】Re:callで呼び出すとき タルジャ 09/11/16(月) 19:36 お礼[未読]
【63530】Re:callで呼び出すとき タルジャ 09/11/15(日) 22:45 お礼[未読]

【63524】callで呼び出すとき
質問  タルジャ  - 09/11/15(日) 19:58 -

引用なし
パスワード
   モジュール1
Sub サンプル1()

Dim i As Integer
Dim a As Integer

a = Cells(Rows.Count, 1).End(xlUp).Row
  For i = 1 To a
    If Cells(i, 1).Value = "みかん" Then
    Cells(i, 2).Value = "おいしい"
    Else
    Exit For
    
    End If
    
  Next
モジュール2

Sub サンプル2()

Dim i As Integer
Dim a As Integer
a = Cells(Rows.Count, 1).End(xlUp).Row
For i = 1 To a
  If Cells(i, 1).Value = "いちご" Then
    Cells(i, 3).Value = "こっちもおいしい"
  End If
Next

End Sub

モジュール3
Sub サンプル3()


Call サンプル1
Call サンプル2

End Sub

上記のようにCallで呼び出していますが
モジュール1で条件が合わない時は処理を抜けているのに
次のCallに進んでしまうのはなぜでしょう?
Callサンプル1で条件が合わない時はプログラムをを一旦中止
したいのです。
どなたかお分かりになる方、よろしくお願いいたします。

【63526】Re:callで呼び出すとき
回答  よろずや  - 09/11/15(日) 21:12 -

引用なし
パスワード
   10個位下のスレッドを見てください。

▼ 【63464】エラー発生後、次のプロシージャを呼び出さない なみ 09/11/9(月) 9:46

【63527】Re:callで呼び出すとき
発言  ichinose  - 09/11/15(日) 21:35 -

引用なし
パスワード
   こんばんは。
>モジュール1で条件が合わない時は処理を抜けているのに
>次のCallに進んでしまうのはなぜでしょう?
サンプル3のコードは、

>Sub サンプル3()
>Call サンプル1
>Call サンプル2
>End Sub

これは、サンプル1を実行した後、
サンプル2を実行するコードですよね?

サンプル1は、

>Sub サンプル1()
>
>Dim i As Integer
>Dim a As Integer
>
>a = Cells(Rows.Count, 1).End(xlUp).Row
>  For i = 1 To a
>    If Cells(i, 1).Value = "みかん" Then
>    Cells(i, 2).Value = "おいしい"
>    Else
>    Exit For
>    
>    End If
>    
>  Next
End Sub

>モジュール1で条件が合わない時は処理を抜けているのに
このサンプル1の仕様が本当は何をしたいのか分かりませんが・・・。
上記のコードで処理を抜けているコードって、

>    Exit For
これのことですか?
これが抜けているのは For〜Nextのループを抜けているのですよ!!
プログラムの流れは、For〜Nextのループを抜ければ、End Subですから、
呼び出されたサンプル3に戻ります。
よって、戻ってきたサンプル3では、只、サンプル2を呼び出しているだけですから、
サンプル1の結果には、関係なく、サンプル2が呼び出されます。

仕様は想像ですが、

Sub サンプル3()
  Dim retcode As Boolean
  Call サンプル1(retcode)
  If retcode Then Call サンプル2
End Sub


Sub サンプル1(ret As Boolean)
  Dim i As Integer
  Dim a As Integer
  ret = False
  a = Cells(Rows.Count, 1).End(xlUp).Row
  For i = 1 To a
    If Cells(i, 1).Value = "みかん" Then
      Cells(i, 2).Value = "おいしい"
      ret = True '条件に合った
    End If
  Next
End Sub


Sub サンプル2()
  Dim i As Integer
  Dim a As Integer
  a = Cells(Rows.Count, 1).End(xlUp).Row
  For i = 1 To a
   If Cells(i, 1).Value = "いちご" Then
     Cells(i, 3).Value = "こっちもおいしい"
   End If
  Next
End Sub


というようにパラメータ(Retcode)を使って
サンプル1での実行結果がサンプル3のプロシジャーにわかるように
すると、そのパラメータの内容で処理を分けることが出来ます。

実際には、Functionを使う方が一般的ですが、今回は、Subを使って、
パラメータで結果を返す方法をとりました。

【63528】Re:callで呼び出すとき
お礼  タルジャ  - 09/11/15(日) 22:30 -

引用なし
パスワード
   ▼ichinose さん:
>こんばんは。
>>モジュール1で条件が合わない時は処理を抜けているのに
>>次のCallに進んでしまうのはなぜでしょう?
>サンプル3のコードは、
>
>>Sub サンプル3()
>>Call サンプル1
>>Call サンプル2
>>End Sub
>
>これは、サンプル1を実行した後、
>サンプル2を実行するコードですよね?
>
>サンプル1は、
>
>>Sub サンプル1()
>>
>>Dim i As Integer
>>Dim a As Integer
>>
>>a = Cells(Rows.Count, 1).End(xlUp).Row
>>  For i = 1 To a
>>    If Cells(i, 1).Value = "みかん" Then
>>    Cells(i, 2).Value = "おいしい"
>>    Else
>>    Exit For
>>    
>>    End If
>>    
>>  Next
>End Sub
>
>>モジュール1で条件が合わない時は処理を抜けているのに
>このサンプル1の仕様が本当は何をしたいのか分かりませんが・・・。
>上記のコードで処理を抜けているコードって、
>
>>    Exit For
>これのことですか?
>これが抜けているのは For〜Nextのループを抜けているのですよ!!
>プログラムの流れは、For〜Nextのループを抜ければ、End Subですから、
>呼び出されたサンプル3に戻ります。
>よって、戻ってきたサンプル3では、只、サンプル2を呼び出しているだけですから、
>サンプル1の結果には、関係なく、サンプル2が呼び出されます。
>
>仕様は想像ですが、
>
>Sub サンプル3()
>  Dim retcode As Boolean
>  Call サンプル1(retcode)
>  If retcode Then Call サンプル2
>End Sub
>
>
>Sub サンプル1(ret As Boolean)
>  Dim i As Integer
>  Dim a As Integer
>  ret = False
>  a = Cells(Rows.Count, 1).End(xlUp).Row
>  For i = 1 To a
>    If Cells(i, 1).Value = "みかん" Then
>      Cells(i, 2).Value = "おいしい"
>      ret = True '条件に合った
>    End If
>  Next
>End Sub
>
>
>Sub サンプル2()
>  Dim i As Integer
>  Dim a As Integer
>  a = Cells(Rows.Count, 1).End(xlUp).Row
>  For i = 1 To a
>   If Cells(i, 1).Value = "いちご" Then
>     Cells(i, 3).Value = "こっちもおいしい"
>   End If
>  Next
>End Sub
>
>
>というようにパラメータ(Retcode)を使って
>サンプル1での実行結果がサンプル3のプロシジャーにわかるように
>すると、そのパラメータの内容で処理を分けることが出来ます。
>
>実際には、Functionを使う方が一般的ですが、今回は、Subを使って、
>パラメータで結果を返す方法をとりました。


ichinoseさん、ありがとうございます。
パラメータ(Retcode)がよくわかりません。
ichinoseさんのアドバイスを元に勉強しなおします。
ありがとうございました。

【63530】Re:callで呼び出すとき
お礼  タルジャ  - 09/11/15(日) 22:45 -

引用なし
パスワード
   ▼よろずや さん:
>10個位下のスレッドを見てください。
>
> ▼ 【63464】エラー発生後、次のプロシージャを呼び出さない なみ 09/11/9(月) 9:46

よろずやさん
ありがとうございます。
よく読んで勉強しなおします。

【63532】Re:callで呼び出すとき
発言  ichinose  - 09/11/16(月) 7:11 -

引用なし
パスワード
   ▼タルジャ さん:
おはようございます。
>パラメータ(Retcode)がよくわかりません。

別の例で・・・。

新規ブックの標準モジュールに

Sub test()
  MsgBox "タルジャ さん、おはようございます"
End Sub

というコードを実行すると、メッセージボックスに体裁よく指定された
「タルジャ さん、おはようございます」という文字列が表示されますよね?
これ、私たちは、MsgBox 〜  の一行でメッセージボックスを表示させていますが、
MsgBoxもVBAではないですが、既成の「プログラム」です。
中身は表示文字列の長さによって表示位置のバランスを取ったりで結構のプログラムが作られているはずです。
こういう便利なものがあるので、それを私たちは、MsgBox 〜  の一行でメッセージを表示できています。
この時、MsgBoxに渡している「タルジャ さん、おはようございます」という文字列をパラメータとか
引数(アーギュメント)等と呼んでいます。
厳密には、規定がありますが、忘れました。

これと同様に私たちが作成するVBAコードにもパラメータを付けることが出来ます。

今、四則演算を行なうプログラムを考えます。

標準モジュールに

Sub 四則演算(x As Variant, y As Variant, enzan As Variant, ans As Variant)
  '四則演算を行なう
  'input : x,y 四則演算を行なう二つの数値
  '    : enzan 演算の種類 1 足し算 2 引き算 3 掛け算 4 割り算
  'output : ans 演算の結果
  Select Case enzan
    Case 1
     ans = x + y
    Case 2
     ans = x - y
    Case 3
     ans = x * y
    Case 4
     ans = x / y
  End Select
End Sub


これは、簡単例題ですが、
このように作っておくと、四則演算がしたければ、どのプログラムからでも呼び出すことが出来ます。
(実際には、y=0で割り算すると、エラーになるので、対処が必要)。

Sub test1()
  Dim a As Long
  Dim b As Long
  Dim 答え As Long
  a = 10
  b = 2
  Call 四則演算(a, b, 1, 答え)
  MsgBox a & " + " & b & " = " & 答え
  Call 四則演算(a, b, 2, 答え)
  MsgBox a & " - " & b & " = " & 答え
  Call 四則演算(a, b, 3, 答え)
  MsgBox a & " × " & b & " = " & 答え
  Call 四則演算(a, b, 4, 答え)
  MsgBox a & " ÷ " & b & " = " & 答え
End Sub

test1を実行すれば、指定するパラメータによって、四則演算を行なってくれます。
パラメータを使う方法が情報をプロシジャーから、プロシジャーに渡す方法としては、一番良い方法とされています。

こんな説明でどうでしょうか?

【63541】Re:callで呼び出すとき
お礼  タルジャ  - 09/11/16(月) 19:36 -

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


あれから本を読んだりしましたが パラメータについてのって
いなかったのでichinoseさんの説明でよくわかりました。
ありがとうございます。
VBAは難しいですが いろんなことがわかってくると
楽しいです。

ご丁寧にありがとうございます。

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