アプリ版:「スタンプのみでお礼する」機能のリリースについて

Dim i As Long
Dim A() As String

'何かの処理で配列全部に文字列を入れる。
i=1
Do while Len(A(i))>0
'何かの処理
i=i+1
Loop
配列の全部の要素に文字列が入ってると、最後のiでエラーになります。静的配列を使う場合は、要素数に余裕を持たせて宣言するので問題無かったのですが、動的配列を使うようになりエラーが出ました。

動的配列では条件判断に配列を使わない方がいいのでしょうか?というよりDowhile自体使わない方がいいのでしょうか。
勿論やりようで使える筈です。例えば要素数を1個追加して空""にするとか。常識的な方法はあるのでしょうか。例えばFor nextとか。

A 回答 (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の中で動的配列の上限を操作する可能性があってそういう事をしているのかもしれませんが、そこはご相談の範疇じゃないので割愛します。
    • good
    • 0
この回答へのお礼

ありがとうございます。
Uboundが
一番良さそうですね。

お礼日時:2014/05/12 07:25

こんばんは。



>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を使いました。
    • good
    • 0
この回答へのお礼

ありがとうございます。
Dowhileは数値では用いない、了解です。その様にします。

〉サンプルコードとは違うとかいうレスはしないでください
前回質問のやり取りを意識しての事と思いますが、それを言われてしまうと私としても「質問外の事を書かないでくれ」としか返事出来ません。ソースコードもありませんし、あったとしてもおそらく開示出来ません。ここに質問する時は、変えるとか必要部分のみ書いてます。

Trim これは知りませんでした。調べてみます。

お礼日時:2014/05/12 18:37

Do While i <= UBound(A)


'何かの処理
i = i + 1
Loop

でいけそうですがどうでしょう。
    • good
    • 0
この回答へのお礼

ありがとうございます。
この方法でも出来ますね。ここまで来るとForNextに近いですね。

お礼日時:2014/05/12 07:37

参考に


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
    • good
    • 0
この回答へのお礼

ありがとうございます。
i=i+1の後で判定すればDowhileも使えますね。

お礼日時:2014/05/12 07:33

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
---


といった感じではないでしょうか。
    • good
    • 0
この回答へのお礼

ありがとうございます。
Uboundが一番良さそうですね。

お礼日時:2014/05/12 07:27

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!