- ベストアンサー
VBA Dowhileで動的配列を判断条件に使う時の注意点
- VBAのDowhileループを使用する場合、動的配列を判断条件に使用する場合には注意が必要です。
- 動的配列を使用すると、配列の要素が全て空の場合に無限ループが発生する可能性があります。
- この問題を回避するためには、動的配列を使用する前に配列の要素数を十分に初期化するか、別のループ構造を使用することが推奨されます。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
ご相談のマクロでは、脱出条件としてA(i)が「存在する」ことが前提になってるのですから、つまりはロジックの組み方が間違ってます。 >常識的な方法 一般には option base 1 for i = 1 to ubound(a) ’if len(a(i)) = 0 then exit for ’必要なら 何かの処理 a(i) next i のようにしとくのが、ご相談の状況では一番簡単確実に見えます。 #もちろん例えばdo loopの中で動的配列の上限を操作する可能性があってそういう事をしているのかもしれませんが、そこはご相談の範疇じゃないので割愛します。
その他の回答 (4)
- WindFaller
- ベストアンサー率57% (465/803)
こんばんは。 >Dowhile自体使わない方がいいのでしょうか。 Do While というのは、一般的に、数的な終了条件を求められない時に使うものです。 だから、VBAの実務では、外部ファイルのテキストファイルのEOF などの制御コードの時に用います。 数的に捉えられるものは、For 初期値 To 最終値 のほうが便利で早いです。 今回は、あくまでも、初級の練習だと解釈するしかありません。 また、ふつう、動的配列というものは、配列の添字の最大値が予め分からない場合に用いることであって、元はどういう構造になっているのか見せられていませんから、なんとも言えません。 以下のサンプルコードの場合は、本来は、動的配列は不要です。 (サンプルコードとは違うとかいうレスはしないでください。違うのだったら、元のコードを見せてください。) 常識的に、動的に配列に入れたなら、動的配列に使った、カウンター数か、UBoundで、Loopから抜ければよいだけではないでしょうか? >最後のiでエラーになります。 Loopで戻った後に、配列の添字の上限以上の数を入れるわけですから、配列にない添字を入れたわけですから、エラーになります。 Do a = a & Ar(i) '一例 i = i + 1 Loop While i <= UBound(Ar) Or Trim(Ar(i - 1)) = "" あえて、2つの条件をあわせるなら、こうなります。 '// Sub TestArray() Dim i As Long Dim j As Long Dim k As Long Dim Ar() As String Dim a As String Const sABC As String = "abcdefghijklmnopqrstuvwxyz" For i = 1 To Len(sABC) ReDim Preserve Ar(j) Ar(j) = Mid(sABC, i, 1) j = j + 1 'ここで、カウンター数を取得 Next i Do 'If Trim(Ar(k)) = "" Then Exit Do 'もし空白条件を入れるなら。 a = a & Ar(k) k = k + 1 Loop While k < j 'While k <= UBound(Ar) '下に入れる Stop End Sub '// こういうスタイルの場合は、最初に、予め配列の添字の上限を決めてしまうのが通例です。 空白で、Len(Ar(i))=0 というのは、Ar()が文字型ですから、「""」で十分ですが、あえて、Trimを使いました。
お礼
ありがとうございます。 Dowhileは数値では用いない、了解です。その様にします。 〉サンプルコードとは違うとかいうレスはしないでください 前回質問のやり取りを意識しての事と思いますが、それを言われてしまうと私としても「質問外の事を書かないでくれ」としか返事出来ません。ソースコードもありませんし、あったとしてもおそらく開示出来ません。ここに質問する時は、変えるとか必要部分のみ書いてます。 Trim これは知りませんでした。調べてみます。
- kkkkkm
- ベストアンサー率66% (1734/2604)
Do While i <= UBound(A) '何かの処理 i = i + 1 Loop でいけそうですがどうでしょう。
お礼
ありがとうございます。 この方法でも出来ますね。ここまで来るとForNextに近いですね。
- watabe007
- ベストアンサー率62% (476/760)
参考に Do while Len(A(i))>0 '何かの処理 i = i + 1 If i > UBound(A) Then Exit Do Loop >例えばFor nextとか。 For i = LBound(A) To UBound(A) '何かの処理 Next
お礼
ありがとうございます。 i=i+1の後で判定すればDowhileも使えますね。
- t-aka
- ベストアンサー率36% (114/314)
UBoundで配列の数を取得しておいて、For~Nextを使用すれば対応できると思います。 --- Dim A() As String '何かの処理で配列全部に文字列を入れる。 Dim i As Long i = 1 Dim arrayMax As Long arrayMax = UBound(A) For i = 0 To arrayMax '何かの処理 If Len(A(i)) = 0 Then Exit For Next i --- といった感じではないでしょうか。
お礼
ありがとうございます。 Uboundが一番良さそうですね。
お礼
ありがとうございます。 Uboundが 一番良さそうですね。