0

条件付きループで作業しようとしています。すべてが機能しているように見えますが、次の i と次の j に進んでループを続けていません。ループを一周したら終了のようです。私はかなり長い間これに取り組んできましたが、VBA には非常に慣れていません。

Sub Read()
     NumMonth = 12
     Worksheets("Sheet1").Activate
     ReDim Month(1 To NumMonth)
     ReDim WCinit(1 To NumMonth)
     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
     WCinit(i) = Cells(4 + i, 10).Value

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

 Next i

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

     Application.ScreenUpdating = True
  End Sub


Sub Test()
    Dim fc As Double
    fc = 0.3
    NumMonth = 12
    i = 1
    j = 2

    Dim pwp As Double
    pwp=0.1
    Dim dz As Double
    dz = 0.5 'm

Do

If WC(j - 1) + WCinit(i) > pwp And fc - (WC(j - 1) + WCinit(i)) + RefET(i) < Precip(i)        Then
   Runoff(i) = (Precip(i) - (fc - (WC(j - 1) + WCinit(i)) + RefET(i))) * 0.5
   Percolation(i) = (Precip(i) - (fc - (WC(j - 1) + WCinit(i)) + RefET(i))) * 0.5
   WC(j) = fc

ElseIf WC(j - 1) + WCinit(i) > pwp And fc - (WC(j - 1) + WCinit(i)) + RefET(i) <    Precip(i) Then
   Runoff(i) = 0
   Percolation(i) = 0
   WC(j) = WC(j - 1) + WCinit(i) + Precip(i) - RefET(i)

Else
   WC(j) = pwp

End If
    j = j + 1
    i = i + 1

Loop While j<13
4

1 に答える 1

2

私はあなたが提供したコード(以下に注釈を付けて提示)でいくつかの作業を行いましたが、これには主にプログラムのロジックの注意深いデバッグが必要でした。コードで2つの配列が割り当てられていないため、コンパイラエラーが発生します。これを適切に行うための十分な情報がありません。

扱いにくいコードを使いこなすためにVBAで利用できる最高のリソースは、組み込みのデバッガーです。これを使用すると、各ステップで各変数がどのように変化しているかを確認しながら、コードを1行ずつステップ実行できます。

デバッガーに慣れていない場合は、Chip Pearsonによる基本の説明など、多くの優れた説明がオンラインで入手できます。

ループとインデックスの処理を容易にする可能性のある変更の1つは、「13か月目」の値を配列とは別の変数に入れることです。これにより、データの12か月のアンサンブルが簡単になります。

これは、他の方法で必要とされる紛らわしい簿記を減らす方法になります(「プログラムのこの時点でのインデックスはj、またはj -1、またはj + 1である必要がありますか?」)。そのアプローチがあなたのデータと計算に本当に適合するかどうかはわかりません。

Option Explicit                         ' Require declaration of all variables 

Private Const NumMonth As Long = 12     ' Make these variable available to all subroutines   
Private month As Variant                ' and functions in the module. Needed because they 
Private WCinit As Variant               ' would otherwise be out of scope in the Test() 
Private WC As Variant                   ' subroutine.

Private Precip As Variant               ' The arrays need to be declared as type Variant,
Private RefET As Variant                ' so we can make the assignment
Private Percolation As Variant          
Private Runoff As Variant              

Sub Read()

    Dim firstMoDataRow As Long
    Dim lastMoDataRow As Long

    firstMoDataRow = 5
    lastMoDataRow = 16

    ' if you want to avoid using the transpose function in the following
    ' array assignments, you will need to reference the arrays as  
    ' two-dimensional, e.g., WC(i,1) or WC(3,1), etc., with the 
    ' second index always 1 (that's what many often do).

    month = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow, 1), Cells(lastMoDataRow, 1)).Value)    ' Direct assignment of values

    WCinit = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow, 10), Cells(lastMoDataRow, 10)).Value)  ' in the worksheet ranges

    WC = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow - 1, 11), Cells(lastMoDataRow, 11)).Value)  ' to the arrays.

    Precip = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow, 2), Cells(lastMoDataRow, 2)).Value)

    RefET = WorksheetFunction.Transpose(Range(Cells(firstMoDataRow, 3), Cells(lastMoDataRow, 3)).Value)

  ' ?! Percolation and runoff are not assigned in your code, so I don't know
  '    the correct row and column references in the worksheet.

End Sub


Sub Test()

    Dim fc As Double           
    Dim pwp As Double
    Dim dz As Double
    Dim i as Long, j as Long


    fc = 0.3
    pwp = 0.1
    dz = 0.5 'm

    i = 1
    j = 2

    Do While i <= NumMonth And j <= NumMonth + 1  ' I am assuming here that you will sort out
                                                  ' the correct initializing and incrementing 
                                                  ' of the loop indexes, which I have not
                                                  ' puzzled out


        If WC(j - 1) + WCinit(i) > pwp And fc - (WC(j - 1) + WCinit(i)) + RefET(i) < Precip(i) Then

            Runoff(i) = (Precip(i) - (fc - (WC(j - 1) + WCinit(i)) + RefET(i))) * 0.5
            Percolation(i) = (Precip(i) - (fc - (WC(j - 1) + WCinit(i)) + RefET(i))) * 0.5
            WC(j) = fc

        ElseIf WC(j - 1) + WCinit(i) > pwp And fc - (WC(j - 1) + WCinit(i)) + RefET(i) < Precip(i) Then

            ' You are getting a "Subscript out of range" error here because Runoff() and 
            ' Percolation<> did not get assigned in the Read sub

            Runoff(i) = 0                                         
            Percolation(i) = 0                                    
            WC(j) = WC(j - 1) + WCinit(i) + Precip(i) - RefET(i)  

        Else

            WC(j) = pwp

        End If

        j = j + 1
        i = i + 1

    Loop

End Sub 
于 2013-02-24T01:51:12.977 に答える