0

WC(1)の単一の値を読み込もうとしています。次に、条件付きループでWC(j)の初期値を使用したいと思います。WC(j)の最初の値をスムーズに実行します(ループの最初の条件を満たします)が、最初の条件はWC(j)配列の次の値を確立することになっています。ただし、空と表示されるだけの配列には値が設定されません。具体的には、次の行にあります。WC(j)= fc WCinit(j)= WC(j-1)

コードをステップスルーすると、fc = 0.3と表示されますが、WC(j)は、互いに等しく設定していても空です。WC(j)値は空なので、ループの「else」条件のみを満たします。

次のコード行でも同じ問題があり、WC(j-1)の値があり、WCinit(j)と等しく設定されていますが、WCinit(j)は空のままです。

  Dim Month() As Double
  Dim WC() As Variant
  Dim WCinit() As Variant
  Dim NumMonth As Long, i As Long, j As Long

  Dim Precip() As Double
  Dim RefET() As Double
  Dim Runoff() As Double
  Dim Percolation() As Double

  Sub main()
    WaterBalanceReadMediterranean
    WaterBalanceMediterranean
    WaterBalanceReadPlains
    WaterBalancePlains
End Sub
Sub WaterBalanceReadMediterranean()
    NumMonth = 12

    ReDim Month(1 To NumMonth)
    ReDim WCinit(1 To NumMonth + 1)
    ReDim WC(1 To NumMonth + 1)
    ReDim Precip(1 To NumMonth)
    ReDim RefET(1 To NumMonth)
    ReDim Percolation(1 To NumMonth + 1)
    ReDim Runoff(1 To NumMonth + 1)

   For i = 1 To NumMonth

    Month(i) = Cells(4 + i, 1).Value
    Precip(i) = Cells(4 + i, 2).Value
    RefET(i) = Cells(4 + i, 3).Value
    Next i


For j = 1 To 1
      WC(j) = Cells(3 + j, 11).Value

     Next j

     Application.ScreenUpdating = True
  End Sub



Sub WaterBalanceMediterranean()

    Dim fc As Double
    fc = Cells(4, 7).Value
    NumMonth = 12
    i = 1
    j = 2

    Dim pwp,dz As Double

    Do
        If WC(j) >= pwp And (fc - WC(j - 1) + RefET(i)) < Precip(i) Then
            Runoff(i) = (Precip(i) - (fc - WC(j - 1) + RefET(i))) * 0.5
            Percolation(i) = (Precip(i) - (fc - WC(j - 1) + RefET(i))) * 0.5
            WC(j) = fc
            WCinit(j) = WC(j - 1)    
        ElseIf WC(j) >= pwp And (fc - WC(j - 1) + RefET(i)) > Precip(i) Then
            Runoff(i) = 0
            Percolation(i) = 0
            WC(j) = WC(j - 1) + Precip(i) - RefET(i)
            WCinit(j) = WC(j - 1)
        Else
            Runoff(i) = 0
            Percolation(i) = 0
            WC(j) = pwp
            WCinit(j) = WC(j - 1)
        End If
        j = j + 1
        i = i + 1
    Loop While j < 14


End Sub
4

2 に答える 2

2

配列をdoubleの配列として宣言する必要があります。

Dim WC() As Double
Redim WC(1 to NumMonth + 1) As Double 'Type is not necessary here, but no harm AFAIK

それらはバリアントの配列として宣言されているため、そもそも値が割り当てられていません。かなり計算コストの高いことをしている場合、この変更により計算も高速化されます。

本当にdoubleを使用したくない場合は、使用する前に配列をゼロにすることもできます。

戻って編集内容を確認する必要があったため、質問からできるだけ多くのコードを削除するようにお願いしたことをお詫びしますが、そこには多くのコードがあり、その多くを再現する必要はありませんでした問題。言うまでもなく、無差別に削除しました。あごにこの批判をしないでください。うまくいけば、私があなたの質問をフォローして答えたという事実は、私が真剣であることを示しています。とにかく、これがあなたの問題を解決することを願っています:)。

于 2013-02-28T05:55:02.893 に答える
2

pwp手始めに、値を割り当てる前に変数を使用しています。VBAでは、コンマで区切られた複数の変数を定義しても、両方にタイプは与えられません。たとえば、pwpとdzを次のように定義してからDim pwp, dz as Double、次のように表示します。

MsgBox "pwp = " & pwp & " , dz = " & dz

あなたはこれを得るでしょう:pwp = , dz = 0

コードの場合、pwpは、値が割り当てられる前に「If」ブロックで呼び出されます。このブロックに到達すると、その後コードが壊れます。変数定義をに変更すると、Dim pwp as Double, dz as Doubleこの問題が修正されます。


さらに、この質問に対する本当の答えは、あなたがここで多くの間違ったことをしているということです。この特定の問題の原因は、特に参照されている各セルにどのデータが含まれているかがわからないため、特定できないものがいくつもある可能性があります。私の提案は、次のことを行って、私たちに戻ることです。

  1. コードを1つのサブルーチンに統合します。
  2. インクリメンタル変数と組み合わせたDoWhileループの代わりに、For...Nextループを使用します。
  3. 次のような絶対に無意味なコードを削除します

    For j = 1 To 1
          WC(j) = Cells(3 + j, 11).Value
    
         Next j
    

    このスニペットはである必要がありますWC(1) = Cells(14,11).Value。。。はるかに簡単です。

さらに、私が行う他のいくつかの変更は、経験からは言えないかもしれませんが、あなたがそれを自分のやり方で行うと、問題が発生する可能性があります。幸運を。

于 2013-02-28T22:17:44.507 に答える