Excel VBA質問箱 IV

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

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


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

【18561】数値計算について ジュン 04/9/29(水) 16:55 質問[未読]
【18563】Re:数値計算について ichinose 04/9/29(水) 19:11 回答[未読]
【18570】Re:数値計算について(一箇所訂正) ichinose 04/9/29(水) 22:39 発言[未読]
【18573】Re:数値計算について ジュン 04/9/29(水) 23:10 お礼[未読]
【18577】Re:数値計算についての質問2 ジュン 04/9/30(木) 2:19 質問[未読]
【18579】Re:数値計算についての質問2 ichinose 04/9/30(木) 7:39 発言[未読]
【18582】Re:数値計算についての質問2 ジュン 04/9/30(木) 8:47 お礼[未読]
【18587】数値計算についての質問3 ジュン 04/9/30(木) 15:09 質問[未読]
【18595】Re:数値計算についての質問3 ichinose 04/9/30(木) 21:09 発言[未読]
【18644】Re:数値計算についての質問3 ジュン 04/10/2(土) 21:11 お礼[未読]

【18561】数値計算について
質問  ジュン  - 04/9/29(水) 16:55 -

引用なし
パスワード
   例えば,Tn=Σ(i=1⇒n)Wi×Tn-i という数値計算をexcelで行いたいとき,
初期条件として,
T0=0
Wi:i=1〜nのときの値(既知)
が与えられたときのTnの値を求めたいのですが,

1.T1を求めるとき,T1=W1×T0
2.T2を求めるとき,T2=W1×T1+W2×T0
3.Tnを求めるとき,Tn=W1×Tn-1+W2×Tn-2+・・・
となっていきますよね。nの値が小さければ問題ないのですが,
nが100以上とかになると,Wi×Tn-1をうまく表現することができません。
どういう式をたてればよいでしょうか

【18563】Re:数値計算について
回答  ichinose  - 04/9/29(水) 19:11 -

引用なし
パスワード
   ▼ジュン さん:
こんばんは。

>例えば,Tn=Σ(i=1⇒n)Wi×Tn-i という数値計算をexcelで行いたいとき,
>初期条件として,
>T0=0
>Wi:i=1〜nのときの値(既知)
>が与えられたときのTnの値を求めたいのですが,
>
>1.T1を求めるとき,T1=W1×T0
>2.T2を求めるとき,T2=W1×T1+W2×T0
>3.Tnを求めるとき,Tn=W1×Tn-1+W2×Tn-2+・・・
>となっていきますよね。nの値が小さければ問題ないのですが,
>nが100以上とかになると,Wi×Tn-1をうまく表現することができません。
>どういう式をたてればよいでしょうか
VBAで良いんですよね?
W1〜Wnは、アクティブシートのセルA1〜Anに想定値を乱数で発生させた例です。

'================================================================
Sub test()
  Dim n As Long
  n = 100 '←この値を変更して確認してみて下さい
  With Range("a1:a" & n)
   .Formula = "=int(rand()*" & n & ")+1"
   .Value = .Value
   End With
 MsgBox tn(n, 2)
End Sub
'=============================================================
Function tn(n As Long, t0 As Long) As Double
'Tn=Σ(i=1⇒n)Wi×Tn-iを計算する
'input : n 求めたい数列値、t0--初期値
'output: tn 結果
  Dim idx As Long
  Dim jdx As Long
  ReDim ans(n) As Double
  ans(0) = t0
  For idx = 1 To n
   ans(idx) = 0
   For jdx = idx - 1 To 0 Step -1
    ans(idx) = ans(idx) + Range("a" & (idx - jdx)).Value * ans(jdx)
    Next
   Next
  tn = ans(UBound(ans()))
End Function

ただ、値がかなり大きくなるので有効桁数をオーバーしてしまいますね!!
まずは、nに小さい数字を指定して確認してみて下さい。

【18570】Re:数値計算について(一箇所訂正)
発言  ichinose  - 04/9/29(水) 22:39 -

引用なし
パスワード
   訂正があります。


>'================================================================
>Sub test()
>  Dim n As Long
>  n = 100 '←この値を変更して確認してみて下さい
  if n>0 then 'こうしないとn=0のとき、エラーになるので
>   With Range("a1:a" & n)
>    .Formula = "=int(rand()*" & n & ")+1"
>    .Value = .Value
>    End With
    end if
> MsgBox tn(n, 2)
>End Sub
>'=============================================================
>Function tn(n As Long, t0 As Long) As Double
>'Tn=Σ(i=1⇒n)Wi×Tn-iを計算する
>'input : n 求めたい数列値、t0--初期値
>'output: tn 結果
>  Dim idx As Long
>  Dim jdx As Long
>  ReDim ans(n) As Double
>  ans(0) = t0
>  For idx = 1 To n
>   ans(idx) = 0
>   For jdx = idx - 1 To 0 Step -1
>    ans(idx) = ans(idx) + Range("a" & (idx - jdx)).Value * ans(jdx)
>    Next
>   Next
>  tn = ans(UBound(ans()))
>End Function

【18573】Re:数値計算について
お礼  ジュン  - 04/9/29(水) 23:10 -

引用なし
パスワード
   ▼ichinose さん:
ありがとうございます.
早速試してみたいと思います.
最近エクセルを始めたばかりなので,また問題が生じたら
質問したいと思います.よろしくお願いします

【18577】Re:数値計算についての質問2
質問  ジュン  - 04/9/30(木) 2:19 -

引用なし
パスワード
   ▼ichinose さん
こんばんは.
とりあえず手計算で確認できるように,
初期条件として,
T0=0
n=5
Wi:i=1〜nのときの値
W1=0.2 W2=0.4 ・・・ W5=1.0

と置いて解いているのですが,
   .Formula = "=int(rand()*" & n & ")+1"

の部分でエラーが発生してしまいます.VBAについての
知識が浅いのに加え,めったに使用しないのでエラーの原因が
何なのかも良く分かりません.よろしくお願いします.

また,このような数値計算を解くにはやはりVBAでないと無理なのでしょうか.
今までは,セルに(=B1*J3+K8)のような式をつくり,
コピー&ペーストで値を算出することが多かったので・・・.
Tn=Σ(i=1⇒n)Wi×Tn-iをうまく表現する式があれば,ぜひ教えて頂けたらと思います.

【18579】Re:数値計算についての質問2
発言  ichinose  - 04/9/30(木) 7:39 -

引用なし
パスワード
   ▼ジュン さん:
おはようございます。

>とりあえず手計算で確認できるように,
>初期条件として,
>T0=0
>n=5
>Wi:i=1〜nのときの値
>W1=0.2 W2=0.4 ・・・ W5=1.0
↑、このWをどのようにせっていしたのかわかりません。
'=============================
Sub test()
  Dim n As Long
  n = 5 'ここを5としたのですよね?
'******************************************
  If n > 0 Then
   With Range("a1:a" & n)
    .Formula = "=int(rand()*" & n & ")+1"
    .Value = .Value
    End With
   End If
'このコードでセルA1からA5にw1〜w5に相当するサンプル値を
'設定しています。このコードからw1=0.2というサンプル値は作れないんですが・・。
'サンプル値は、整数だけの設定になっています。
'もし、w1・・・に自由に値を設定したいなら、
'******* で囲んだコードは削除して下さい。
'代わりにセルA1〜A5に0.2 0.4 ・・・ 1.0と設定して下さい
'**********************************************


 MsgBox tn(n, 1)
End Sub

'=======================================================
Function tn(n As Long, t0 As double) As Double
'              ↑ついでに ここも訂正して下さい
'Tn=Σ(i=1⇒n)Wi×Tn-iを計算する
'input : n 求めたい数列値、t0--初期値
'output: tn 結果
  Dim idx As Long
  Dim jdx As Long
  ReDim ans(n) As Double
  ans(0) = t0
  For idx = 1 To n
   ans(idx) = 0
   For jdx = idx - 1 To 0 Step -1
    ans(idx) = ans(idx) + Range("a" & (idx - jdx)).Value * ans(jdx)
    Next
   Next
  tn = ans(UBound(ans()))
End Function


>
>と置いて解いているのですが,
>   .Formula = "=int(rand()*" & n & ")+1"
>
>の部分でエラーが発生してしまいます.VBAについての
どんなエラーが内容ですか?

W1〜W5の値をどこに設定したのですか?
私が投稿したコードをそのまま実行すると
w1〜w5に値を自由に設定することはできないんですが・・・。
どこか変更しましたか?


それと私の解釈が違っているのでしょうか?
この計算結果って、T0=0の時って、常にTnは、0になるのではないのですか?
仮に
w1=1
w2=2
w3=3
として、
t0=0のとき、T3って、いくつになるんですか?0ではないんですか?
投稿したコードは、初期値が0のときは、解は0になっています。
解釈が違うなら教えて下さい。


>知識が浅いのに加え,めったに使用しないのでエラーの原因が
>何なのかも良く分かりません.よろしくお願いします.
>
>また,このような数値計算を解くにはやはりVBAでないと無理なのでしょうか.
数式では、難しいと思いますが・・・。


ちょっと、はっきり私にもエラーの内容が把握できませんが、

まず、私が投稿したコードを新規ブックで実行してみて下さい。

【18582】Re:数値計算についての質問2
お礼  ジュン  - 04/9/30(木) 8:47 -

引用なし
パスワード
   ▼ichinose さん:
おはようございます

新規で実行したところ,エラーがなくなり問題が解決しました.
私の単純なミスだったのだと思います.
ichinose さんのコードも実行して計算できることも確認しました.
本当にありがとうございます

【18587】数値計算についての質問3
質問  ジュン  - 04/9/30(木) 15:09 -

引用なし
パスワード
   ▼ichinose さん:
こんにちは.
以前の問題と似ているのですが,新たな問題を課せられて困っています.

Tn=A*Pn+B*((Σ(i=1⇒n)Wi×Pn-i)-(Σ(i=1⇒n)Wi×Tn-i)) 
という数値計算を行いたいとき,
A=B=定数
T0=P0=0
Pn:=nのときの値(既知)
Wi:i=1〜nのときの値(既知)
が与えられたときのTnの値を求めたいのですが,

例えば,
A=10
B=20
n=5
Pn=1,2,3,4,5 (n=1〜5)
Wi=0.2,0.4,0.6,0.8,1.0 (i=1〜5)

と与えたとき,T5を求めるためにはどのようなプログラムを作成すれば
よいでしょうか.以前教えていただいたVBAのプログラムに
数値や条件を新たに加えて試みたのですが,手計算で解いた答えと
違う値が算出されたり,エラーが生じたりします.
よろしくおねがいします.

【18595】Re:数値計算についての質問3
発言  ichinose  - 04/9/30(木) 21:09 -

引用なし
パスワード
   ▼ジュン さん:
こんばんは。

>以前の問題と似ているのですが,新たな問題を課せられて困っています.
本当はね、前回のコードをじっくり見ていただいて理解していただくと
以下の問題のアルゴリズムはわかってくると思うのですが・・・。


>
>Tn=A*Pn+B*((Σ(i=1⇒n)Wi×Pn-i)-(Σ(i=1⇒n)Wi×Tn-i)) 
>という数値計算を行いたいとき,
>A=B=定数
>T0=P0=0
>Pn:=nのときの値(既知)
>Wi:i=1〜nのときの値(既知)
>が与えられたときのTnの値を求めたいのですが,
>
>例えば,
>A=10
>B=20
>n=5
>Pn=1,2,3,4,5 (n=1〜5)
>Wi=0.2,0.4,0.6,0.8,1.0 (i=1〜5)

例題として、

・P0及び、Pn(1〜5)は、
 アクティブシートのセルA1〜A6に0,1,2,3,4,5と入力して下さい。
・Wi(1〜5)は、セルB2〜B6に0.2,0.4,0.6,0.8,1と入力して下さい。


コードは、以下のとおりです。前回のコードとは違うコードも記述されていますが、
もっうちょっと使いやすくした結果です。

'===============================================================
Sub test()
  MsgBox newtn(5, 0, Range("a1:a6"), Range("b2:b6"), 10, 20)
End Sub
'===========================================================
Function newtn(n As Long, t0 As Variant, _
             p_rng As Range, _
             w_rng As Range, _
             a As Variant, _
             b As Variant)
'newTn=A*Pn+B*((Σ(i=1⇒n)Wi×Pn-i)-(Σ(i=1⇒n)Wi×Tn-i))を計算する
'input : n 求めたい数列値、t0--初期値
'    p_rng p0〜pnに相当するセル範囲
'    w_rng w1〜wnに相当するセル範囲
'    a 、b 定数
'output: newtn 結果
  Dim idx As Long
  Dim jdx As Long
  Dim pn() As Variant
  Dim wn() As Variant
  Dim Swixpnm1 As Variant
  Dim Swixtnm1 As Variant
  ReDim ans(n) As Variant
'この'***********で挟んである間のコードはあまり気にしないでよいです
'ただ、指定されたセル範囲データの配列変数にセットしなおしているだけです
'************************************************************
  With p_rng
   If .Rows.Count > 1 Then
     ReDim pn(.Rows.Count)
     For idx = 1 To .Rows.Count
      pn(idx - 1) = CDec(.Cells(idx, 1).Value)
      Next idx
   ElseIf .Columns.Count > 1 Then
     ReDim pn(.Columns.Count)
     For idx = 1 To .Columns.Count
      pn(idx - 1) = CDec(.Cells(1, idx).Value)
      Next idx
   Else
     ReDim pn(0)
     pn(0) = CDec(Cells(1, 1).Value)
     End If
   End With
  With w_rng
   If .Rows.Count > 1 Then
     ReDim wn(1 To .Rows.Count)
     For idx = 1 To .Rows.Count
      wn(idx) = CDec(.Cells(idx, 1).Value)
      Next idx
   ElseIf .Columns.Count > 1 Then
     ReDim wn(1 To .Columns.Count)
     For idx = 1 To .Columns.Count
      wn(idx) = CDec(.Cells(1, idx).Value)
      Next idx
   Else
     ReDim wn(0)
     wn(0) = CDec(Cells(1, 1).Value)
     End If
   End With
'***********************************************************
'問題解決のコードはここからです
'
  ans(0) = CDec(t0)
  For idx = 1 To n
   Swixpnm1 = 0
   Swixtnm1 = 0
   For jdx = idx - 1 To 0 Step -1
    Swixpnm1 = Swixpnm1 + wn(idx - jdx) * pn(jdx)
    Swixtnm1 = Swixtnm1 + wn(idx - jdx) * ans(jdx)
    Next
   ans(idx) = CDec(a) * pn(idx) + CDec(b) * (Swixpnm1 - Swixtnm1)
   Next
  newtn = ans(UBound(ans()))
End Function


Cdec関数というのが出てきていますが、小数計算の小さい誤差がでないように
使いました(これは、前回のコードにも入れたほうがよさそうです)
アルゴリズムの基本的なところは変わっていません。

上記の「newtn」は、ワークシート関数としても使えます。

例えば、セルC6に「=newtn(5,0,$A$1:$A$6,$B$2:$B$6,10,20)」
という数式を指定して確認してみて下さい。

こういうの漸下式って言うんでしたっけ?
こういう式からループのアルゴリズムを書くのは良い練習問題になりますよ!!

【18644】Re:数値計算についての質問3
お礼  ジュン  - 04/10/2(土) 21:11 -

引用なし
パスワード
   ▼ichinose さん:
こんばんは.
本当にありがとうございます.
何とかなりそうです.前回と今回のプログラムを
しっかりと見直して,さらにVBAを理解しようと思います.

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