2012-01-02 5 views
1

動的配列を使用すると、vbaの各ループが適切な数の要素を返さない理由を理解できません。ループごとに動的配列内の要素の番号が正しくない

exempleについては、私の配列のサイズが4である、と私はループごとに5反復を持っている...

Public Sub test() 

Dim t_direction() As String 
Dim t_nextDirection() As String 
Dim myDirection As Variant 
Dim test As Integer 
Var = 0 

ReDim t_direction(4) 

t_direction(0) = "N" 
t_direction(1) = "S" 
t_direction(2) = "E" 
t_direction(3) = "W" 

t_nextDirection = randomizeArray(t_direction) 

For Each myDirection In t_nextDirection 
    Var = Var + 1 
Next myDirection 

MsgBox (UBound(t_nextDirection)) 
MsgBox (Var) 

End Sub 

Public Function randomizeArray(ByVal t_array As Variant) As String() 
Dim i As Integer 
Dim j As Integer 

Dim tmp As String 
Dim numItems As Integer 

numItems = UBound(t_array) - 1 

    ' Randomize the array. 
    For i = 0 To numItems 
     ' Pick a random entry. 
     j = Rand(0, numItems) 

     ' Swap the numbers. 
     tmp = t_array(i) 
     t_array(i) = t_array(j) 
     t_array(j) = tmp 
    Next i 
    'MsgBox (UBound(t_array)) 
    randomizeArray = t_array 

End Function 

Public Function Rand(ByVal Low As Long, _ 
        ByVal High As Long) As Integer 
    Rand = Int((High - Low + 1) * Rnd) + Low 
End Function 

答えて

4


ReDim t_direction(4)
で5つの要素の配列を作成しています。どちら

  • 4素子アレイReDim t_direction(3)(すなわち0〜3)を作成し、次にそれと一致numItemsを使用するか、
  • 4素子アレイを作成する必要があり

    t_direction(0)ように、第1の要素が発生するようにReDim t_directionを1の基数(すなわち1〜4)で置き換えて、numItems(つまりnumItems = UBound(t_array))を使用してください。 Option Base 1は以下となる第1の要素を強制次いでReDim t_direction(1 To 4)

コードは、以下の後アプローチを使用を使用してanyow確保されている1(。それは4を返し、4よりもむしろ現在4及び5

Option Base 1 
Public Sub test() 

Dim t_direction() As String 
Dim t_nextDirection() As String 
Dim myDirection As Variant 
Dim test As Integer 
Var = 0 

ReDim t_direction(1 To 4) 

t_direction(1) = "N" 
t_direction(2) = "S" 
t_direction(3) = "E" 
t_direction(4) = "W" 

t_nextDirection = randomizeArray(t_direction) 

For Each myDirection In t_nextDirection 
    Var = Var + 1 
Next myDirection 

MsgBox (UBound(t_nextDirection)) 
MsgBox (Var) 

End Sub 

Public Function randomizeArray(ByVal t_array As Variant) As String() 
Dim i As Integer 
Dim j As Integer 

Dim tmp As String 
Dim numItems As Integer 

numItems = UBound(t_array) 

    ' Randomize the array. 
    For i = 1 To numItems 
     ' Pick a random entry. 
     j = Rand(1, numItems) 

     ' Swap the numbers. 
     tmp = t_array(i) 
     t_array(i) = t_array(j) 
     t_array(j) = tmp 
    Next i 
    'MsgBox (UBound(t_array)) 
    randomizeArray = t_array 

End Function 

Public Function Rand(ByVal Low As Long, _ 
        ByVal High As Long) As Integer 
    Rand = Int((High - Low + 1) * Rnd) + Low 
End Function 
+0

素敵なショット、いつものように:)と5000 +のおめでとう、あなたは非常に迅速にそこにいた – JMax

+0

@Jmaxのおめでとう、おめでとう - 非常に感謝:) – brettdj

2

ReDim t_direction(4)は、実際にはより良いt_direction

0 To 4としてのそのは、明示的であることを宣言しています。

ReDim t_direction(0 To 3) 

指定された下限がない場合(To句を使用)、デフォルトのlower束縛が用いられる。
このデフォルト値は、モジュールレベルでOption Base {0|1}を使用すると、0または1に設定できます。 Option Baseが存在しない場合には
は、デフォルトのデフォルトは0

ノートです:

VBAであなたが下限として0または1に限定されるものではなく、あなたが望む任意の値を使用することができます。

は、配列内のアイテムの数が

numItems = UBound(arr) - LBound(arr) + 1 

あなたは下限が

あるものにどのような仮定を行っていません。この方法を使用して計算する

For i = LBound(arr) To UBound(arr) 

を使用し、配列を反復処理するために、

+0

この単一の変更を行っても、問題は解決されません。問題は4/5から3/4に簡単に移動します。 – brettdj

+0

@Brettdj問題の根本は、Redimの操作と下限のアンダーラインに関する悪い仮定です。答えは、単にコードをデバッグするのではなく、根本的な問題に対処しようとしています –

+0

元の答えは、 'numItems'の境界の不一致に対処していないためです。 – brettdj

関連する問題