Page 407 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 通常モードに戻る ┃ INDEX ┃ ≪前へ │ 次へ≫ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ▼Subの使い方 ゆーすけ 02/11/25(月) 16:21 ┗Re:Subの使い方 りん 02/11/25(月) 22:46 ┗Re:Subの使い方 ゆーすけ 02/11/26(火) 10:12 ┗Re:Subの使い方 りん 02/11/26(火) 11:34 ┗Re:Subの使い方 ゆーすけ 02/11/26(火) 12:49 ┗Re:starから先 りん 02/11/27(水) 10:15 ┗Re:starから先 ゆーすけ 02/11/27(水) 12:04 ┗Re:starから先 りん 02/11/28(木) 10:57 ┗Re:starから先 ゆーすけ 02/11/28(木) 11:45 ┗Re:starから先 りん 02/11/28(木) 22:06 ┗Re:starから先 ゆーすけ 02/11/29(金) 10:26 ─────────────────────────────────────── ■題名 : Subの使い方 ■名前 : ゆーすけ ■日付 : 02/11/25(月) 16:21 -------------------------------------------------------------------------
subルーチンをほかのsubに呼び出してさらにそれをまた他のsubに…っというふいうに 使いたいのですがあるところからcallができていないようです。(途中までは呼び出して いることは確認済み) subまたは変数に制限というものはあるのでしょうか? |
ゆーすけ さん、こんばんわ。 >subまたは変数に制限というものはあるのでしょうか? ないとは言い切れませんが。 20回Callするマクロを作ってみました。 Mainを実行すると、メッセージを表示してからSubに文字を渡していきます。 Sub main() MsgBox "点呼" test1 "1!" 'Call Test1("確認") と同じ MsgBox "終了" End Sub Sub test1(a1 As String) MsgBox Now(), vbOKOnly, a1: test2 "2!" End Sub Sub test2(a1 As String) MsgBox Now(), vbOKOnly, a1: test3 "3!" End Sub Sub test3(a1 As String) MsgBox Now(), vbOKOnly, a1: test4 "4!" End Sub Sub test4(a1 As String) MsgBox Now(), vbOKOnly, a1: test5 "5!" End Sub Sub test5(a1 As String) MsgBox Now(), vbOKOnly, a1: test6 "6!" End Sub Sub test6(a1 As String) MsgBox Now(), vbOKOnly, a1: test7 "7!" End Sub Sub test7(a1 As String) MsgBox Now(), vbOKOnly, a1: test8 "8!" End Sub Sub test8(a1 As String) MsgBox Now(), vbOKOnly, a1: test9 "9!" End Sub Sub test9(a1 As String) MsgBox Now(), vbOKOnly, a1: Test10 "10!" End Sub Sub Test10(a1 As String) MsgBox Now(), vbOKOnly, a1: Test11 "11!" End Sub Sub Test11(a1 As String) MsgBox Now(), vbOKOnly, a1: Test12 "12!" End Sub Sub Test12(a1 As String) MsgBox Now(), vbOKOnly, a1: Test13 "13!" End Sub Sub Test13(a1 As String) MsgBox Now(), vbOKOnly, a1: Test14 "14!" End Sub Sub Test14(a1 As String) MsgBox Now(), vbOKOnly, a1: Test15 "15!" End Sub Sub Test15(a1 As String) MsgBox Now(), vbOKOnly, a1: Test16 "16!" End Sub Sub Test16(a1 As String) MsgBox Now(), vbOKOnly, a1: Test17 "17!" End Sub Sub Test17(a1 As String) MsgBox Now(), vbOKOnly, a1: Test18 "18!" End Sub Sub Test18(a1 As String) MsgBox Now(), vbOKOnly, a1: Test19 "19!" End Sub Sub Test19(a1 As String) MsgBox Now(), vbOKOnly, a1: Test20 "20!" End Sub Sub Test20(a1 As String) MsgBox Now(), vbOKOnly, a1 End Sub これだとちゃんと20まで表示されていたので、他の部分に原因があるとも考えられます。 >subルーチンをほかのsubに呼び出してさらにそれをまた他のsubに…っというふいうに >使いたいのですがあるところからcallができていないようです。(途中までは呼び出して >いることは確認済み) ソースを見ないとわかりませんが、ひとつだけ。 もし、Auto_Openや(This)Workbook_Openがからんでいるのならば http://www21.tok2.com/home/vbalab/bbs/c-board.cgi?cmd=one;no=11298;id=Excel からリンク先を見てください。 |
回答ありがとうございました。 プログラム自体はこんな感じです。 今までフォートランを使っていて今回はじめてVBAを使ったので いまいち使い方がわかっていません… Sub para(r, bc, m1, rhos1, ts1, ps1, vs1, m2, rhos2, ts2, ps2, vs2, r01, r02, eps1, eps2) ' 定数の設定、気体定数 r = 0.08205 bc = (1.38066E-23) * 0.009869 * 6.02E+23 ' CO2の特性パラメータ m1 = 44# rhos1 = 1.505 * 1000# / m1 ts1 = 208.9 + 0.459 * t - 0.000756 * t ^ (2#) ps1 = 720.3 / 0.101325 vs1 = bc * ts1 / ps1 ' PSの特性パラメータ m2 = 330000 rhos2 = 1.108 * 1000# / m2 ts2 = 739.9 ps2 = 387# / 0.101325 vs2 = bc * ts2 / ps2 eps1 = bc / ts1 eps2 = bc / ts2 r01 = 1# / rhos1 / vs1 r02 = 1# / rhos2 / vs2 End Sub Sub mix(bc, x1, x2, rm, r01, r02, r1, r2, vs1, vs2, ps1, ps2, fai1, fai2, r, ps12, kij) Call para(r, bc, m1, rhos1, ts1, ps1, vs1, m2, rhos2, ts2, ps2, vs2, r01, r02, eps1, eps2) ps12 = ps1 + ps2 - 2# * (1 - kij) * (ps1 * ps2) ^ 0.5 rm = x1 * r01 + x2 * r02 End Sub Sub fai(x1, x2, r1, r2, r01, r02, rm, vsm, fai01, fai02, fai1, fai2, vs1, vs2) Call para(r, bc, m1, rhos1, ts1, ps1, vs1, m2, rhos2, ts2, ps2, vs2, r01, r02, eps1, eps2) Call mix(bc, x1, x2, rm, r01, r02, r1, r2, vs1, vs2, ps1, ps2, fai1, fai2, r, ps12, kij) fai01 = x1 * r01 / rm fai02 = 1 - fai01 vsm = fai01 * vs1 + fai02 * vs2 r1 = vs1 / vsm * r01 r2 = vs2 / vsm * r02 fai1 = r1 / rm * x1 fai2 = 1 - fai1 End Sub Sub star(ps1, ps2, fai1, fai2, bc, ps12, psm, tsm, epsm, vsm) Call para(r, bc, m1, rhos1, ts1, ps1, vs1, m2, rhos2, ts2, ps2, vs2, r01, r02, eps1, eps2) Call mix(bc, x1, x2, rm, r01, r02, r1, r2, vs1, vs2, ps1, ps2, fai1, fai2, r, ps12, kij) Call fai(x1, x2, r1, r2, r01, r02, rm, vsm, fai01, fai02, fai1, fai2, vs1, vs2) psm = fai1 * ps1 + fai2 * ps2 - fai1 * fai2 * ps12 epsm = vsm * psm tsm = epsm / bc End Sub Sub mixrho(p, t, psm, tsm, rm, rhom1, rhom2, f1, df1, d) Call para(r, bc, m1, rhos1, ts1, ps1, vs1, m2, rhos2, ts2, ps2, vs2, r01, r02, eps1, eps2) Call mix(bc, x1, x2, rm, r01, r02, r1, r2, vs1, vs2, ps1, ps2, fai1, fai2, r, ps12, kij) Call fai(x1, x2, r1, r2, r01, r02, rm, vsm, fai01, fai02, fai1, fai2, vs1, vs2) Call star(ps1, ps2, fai1, fai2, bc, ps12, psm, tsm, epsm, vsm) Dim n As Integer rhom1 = 0# rhom2 = 0# d = 0.0001 For n = 1 To 10000 rhom1 = rhom1 + d f1 = rhom1 ^ 2# + p / psm + t / tsm * (Log(1# - rhom1) + (1# - 1# / rm) * rhom1) df1 = 2# * rhom1 + t / tsm * (1# / (rhom1 - 1#) + 1# - 1# / rm) If f1 < 0# Then GoTo endc Else End If Next endc: rhom1 = rhom1 - 0.0001 d2 = 0.00000001 For n = 1 To 10000 rhom1 = rhom1 + d2 f1 = rhom1 ^ 2# + p / psm + t / tsm * (Log(1# - rhom1) + (1# - 1# / rm) * rhom1) df1 = 2# * rhom1 + t / tsm * (1# / (rhom1 - 1#) + 1# - 1# / rm) If f1 < 0# Then rhom1 = rhom1 GoTo enda Else End If Next enda: End Sub Sub chemipote(r1, r2, r01, r02, t, ts1, ts2, p, ps12, bc, fai1, fai2, rhom1, cp1, cp2) Call para(r, bc, m1, rhos1, ts1, ps1, vs1, m2, rhos2, ts2, ps2, vs2, r01, r02, eps1, eps2) Call mix(bc, x1, x2, rm, r01, r02, r1, r2, vs1, vs2, ps1, ps2, fai1, fai2, r, ps12, kij) Call mixrho(p, t, psm, tsm, rm, rhom1, rhom2, f1, df1, d) Call fai(x1, x2, r1, r2, r01, r02, rm, vsm, fai01, fai02, fai1, fai2, vs1, vs2) cp1 = bc * t * (Log(fai1) + (1# - r1 / r2) * fai2 + Log(rhom1)) + r01 * bc * t * (-rhom1 / t * ts1 + p / ps1 / rhom1 / t * ts1 + 1# / rhom1 * (1# - rhom1) * Log(1 - rhom1)) + r01 * vs1 * rhom1 * ps12 * fai2 + fai2 cp2 = bc * t * (Log(fai2) + (1# - r2 / r1) * fai1 + Log(rhom1)) + r02 * bc * t * (-rhom1 / t * ts2 + p / ps2 / rhom1 / t * ts2 + 1# / rhom1 * (1# - rhom1) * Log(1 - rhom1)) + r02 * vs2 * rhom1 * ps12 * fai1 + fai1 End Sub Function rhov(t, p, kij, x) Call mixrho(p, t, psm, tsm, rm, rhom1, rhom2, f1, df1, d) rhov = rhom1 End Function |
ゆーすけ さん、こんにちわ。 >回答ありがとうございました。 >プログラム自体はこんな感じです。 全部関数や計算ステートメントのようですが、実行開始のSubはどこですか? どこで停止しているか確認しましたか? フォートランを使われていたのならば、テキストログをとることには慣れているでしょうから、ログをとって停止した場所(SubまたはFunction)と内容を確定してみてはいかがでしょうか。 |
> 全部関数や計算ステートメントのようですが、実行開始のSubはどこですか? > どこで停止しているか確認しましたか? > フォートランを使われていたのならば、テキストログをとることには慣れているでしょうから、ログをとって停止した場所(SubまたはFunction)と内容を確定してみてはいかがでしょうか。 sub star から停止しています。そこまでは動いています。 |
ゆーすけさん、おはようございます。 >> 全部関数や計算ステートメントのようですが、実行開始のSubはどこですか? これに答えがないですね。他にSubがいろいろあると考えていいですね。 > sub star から停止しています。そこまでは動いています。 どんな数値が入るかわからないので、変数を空(ゼロ)のままでエラースキップしながら動作ログをとったところ、 <<開始Sub>> In Sub star In Sub para In Sub para Out Sub mix In Sub para In Sub para Out Sub mix Out Sub fai In Sub para In Sub para Out Sub mix In Sub para In Sub para Out Sub mix Out Sub fai Out Sub star Out <<開始Sub>> Out 'マクロ終了 というふうにSub間を移動しているようですね。 paraに始めから行っていないのか、ある回数を超えたら行かなくなるのか、エラーでとまるのか、一見通常終了なのか。 ちゃんとコンパイルできているのか(パソコンを長い間再起動していないと、XL97でコンパイルされていないときがありました)。 こちらではこれ以上試すことができません。 |
> > paraに始めから行っていないのか、ある回数を超えたら行かなくなるのか、エラーでとまるのか、一見通常終了なのか。 > ちゃんとコンパイルできているのか(パソコンを長い間再起動していないと、XL97でコンパイルされていないときがありました)。 > こちらではこれ以上試すことができません。 ありがとうございました。 paraにはいってるようです。star以前にある適当な関数は動作していることはわかっているのである回数を超えたときに行かなくなるのですかね… う〜む、値としては(t=313,P=13,kij=0,x1=0.1)をいれて実験的に計算させています。 |
ゆーすけさん、おはようございます。 >paraにはいってるようです。star以前にある適当な関数は動作していることはわかっているのである回数を超えたときに行かなくなるのですかね… それをカウントしてみましたか? 正しい計算までたどりつけていないので、停止(中断?)を確認できません。 >う〜む、値としては(t=313,P=13,kij=0,x1=0.1)をいれて実験的に計算させています。 この4つということでrhov関数に代入という風に判断しましたが。 ↓標準モジュールで実験しました。 'パラメータ関係は全部グローバル変数にした Dim r, bc, m1, rhos1, ts1, ps1, vs1, m2, rhos2 Dim ts2, ps2, vs2, r01, r02, eps1, eps2 Dim Pflg As Boolean 'パラメータは一度呼び出すだけでよさそうなのでフラグで管理 Sub main() Pflg = False '関数を呼び出し MsgBox rhov(313, 13, 0, 0.1), vbInformation, "結果" 'こういう使い方でしょうか? End Sub Private Sub para() ' 定数の設定、気体定数 r = 0.08205 bc = (1.38066E-23) * 0.009869 * 6.02E+23 ' CO2の特性パラメータ m1 = 44# rhos1 = 1.505 * 1000# / m1 ts1 = 208.9 + 0.459 * t - 0.000756 * t ^ (2#) ps1 = 720.3 / 0.101325 vs1 = bc * ts1 / ps1 ' PSの特性パラメータ m2 = 330000 rhos2 = 1.108 * 1000# / m2 ts2 = 739.9 ps2 = 387# / 0.101325 vs2 = bc * ts2 / ps2 eps1 = bc / ts1 eps2 = bc / ts2 r01 = 1# / rhos1 / vs1 r02 = 1# / rhos2 / vs2 'パラメータ指定済 Pflg = True End Sub Sub mix(x1, x2, r1, r2, kij, ps12, rm) If Not Pflg = True Then Call para ps12 = ps1 + ps2 - 2# * (1 - kij) * (ps1 * ps2) ^ 0.5 'x1,x2が0(Empty)なのでrmもゼロ rm = x1 * r01 + x2 * r02 End Sub Sub fai(x1, x2, r1, r2, rm, vsm, fai01, fai02, fai1, fai2) If Not Pflg = True Then Call para On Error Resume Next 'rmによるゼロ割発生を防ぐためのスキップ Call mix(x1, x2, r1, r2, kij, ps12, rm) fai01 = x1 * r01 / rm fai02 = 1 - fai01 vsm = fai01 * vs1 + fai02 * vs2 r1 = vs1 / vsm * r01 r2 = vs2 / vsm * r02 fai1 = r1 / rm * x1 fai2 = 1 - fai1 End Sub Sub star(fai1, fai2, ps12, psm, tsm, epsm, vsm) If Not Pflg = True Then Call para Call mix(x1, x2, r1, r2, kij, ps12, rm) Call fai(x1, x2, r1, r2, rm, vsm, fai01, fai02, fai1, fai2) psm = fai1 * ps1 + fai2 * ps2 - fai1 * fai2 * ps12 epsm = vsm * psm tsm = epsm / bc End Sub Sub mixrho(p, t, psm, tsm, rm, rhom1, rhom2, f1, df1, d) If Not Pflg = True Then Call para On Error Resume Next Call mix(x1, x2, r1, r2, kij, ps12, rm) Call fai(x1, x2, r1, r2, rm, vsm, fai01, fai02, fai1, fai2) Call star(fai1, fai2, ps12, psm, tsm, epsm, vsm) Dim n As Integer rhom1 = 0#: rhom2 = 0# d = 0.0001 For n = 1 To 10000 rhom1 = rhom1 + d f1 = rhom1 ^ 2# + p / psm + t / tsm * (Log(1# - rhom1) + (1# - 1# / rm) * rhom1) df1 = 2# * rhom1 + t / tsm * (1# / (rhom1 - 1#) + 1# - 1# / rm) If f1 < 0# Then Exit For Next ' rhom1 = rhom1 - 0.0001 d2 = 0.00000001 For n = 1 To 10000 rhom1 = rhom1 + d2 f1 = rhom1 ^ 2# + p / psm + t / tsm * (Log(1# - rhom1) + (1# - 1# / rm) * rhom1) df1 = 2# * rhom1 + t / tsm * (1# / (rhom1 - 1#) + 1# - 1# / rm) If f1 < 0# Then rhom1 = rhom1 '何のために? Exit For End If Next End Sub Sub chemipote(r1, r2, t, p, ps12, bc, fai1, fai2, rhom1, cp1, cp2) Call mix(x1, x2, r1, r2, kij, ps12, rm) Call mixrho(p, t, psm, tsm, rm, rhom1, rhom2, f1, df1, d) Call fai(x1, x2, r1, r2, rm, vsm, fai01, fai02, fai1, fai2) cp1 = bc * t * (Log(fai1) + (1# - r1 / r2) * fai2 + Log(rhom1)) + r01 * bc * t * (-rhom1 / t * ts1 + p / ps1 / rhom1 / t * ts1 + 1# / rhom1 * (1# - rhom1) * Log(1 - rhom1)) + r01 * vs1 * rhom1 * ps12 * fai2 + fai2 cp2 = bc * t * (Log(fai2) + (1# - r2 / r1) * fai1 + Log(rhom1)) + r02 * bc * t * (-rhom1 / t * ts2 + p / ps2 / rhom1 / t * ts2 + 1# / rhom1 * (1# - rhom1) * Log(1 - rhom1)) + r02 * vs2 * rhom1 * ps12 * fai1 + fai1 End Sub Function rhov(t, p, kij, x) 'x1は? If Not Pflg = True Then Call para Call mixrho(p, t, psm, tsm, rm, rhom1, rhom2, f1, df1, d) rhov = rhom1 End Function Mainから関数rhovを呼び出して終了するまでの流れは <<Start>> Function rhov() In Sub Para() In Sub Para() Exit Sub Mixrho() In Sub Mix() In Sub Mix() Exit Sub Fai() In Sub Mix() In Sub Mix() Exit Sub Fai() Exit Sub Star() In Sub Mix() In Sub Mix() Exit Sub Fai() In Sub Mix() In Sub Mix() Exit Sub Fai() Exit Sub Star() Exit Sub Mixrho() Exit Function rhov() Exit <<End>> こんなのでした。 この流れの場合では、x1およびx2に値が入らない(指定がうまくいっていない)ので、faiでゼロ割が発生してオーバーフローするのでエラースキップでとばしてあります。 |
あっ、ちなみにx1は0〜1の範囲で1/1000分割したりとかして、ワークシートに直接記入して値を求めるつもりです。それをT,P,Kijなどを変えて比較しようかと。。。 |
ゆーすけさん、こんばんわ。 >あっ、ちなみにx1は0〜1の範囲で1/1000分割したりとかして、ワークシートに直接記入して値を求めるつもりです。それをT,P,Kijなどを変えて比較しようかと。。。 x2は? |
> x2は? プログラム上で x2=1−X1 としました。 |