私はあなたが提供したコード(以下に注釈を付けて提示)でいくつかの作業を行いましたが、これには主にプログラムのロジックの注意深いデバッグが必要でした。コードで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