プロが教える店舗&オフィスのセキュリティ対策術

動的配列と固定長配列の違いについて分からなくなってしまいました。

http://msdn.microsoft.com/ja-jp/library/cc343797 …
上のURLにあるmsdnの解説で

Dim astr1() As String
Dim astr2(0 To 9) As String
astr1 = astr2

を引用した説明があり、重要事項として
「両方の配列が動的配列であり、いずれも同じデータ型として宣言されている必要があります。」
とありました。
astr1は動的配列なのは分かりますが、astr2は固定長配列だと思います。
「両方の配列が動的配列」とはどのように理解すべきなのでしょうか。

A 回答 (3件)

#2の回答者です。



注意:最初に書くべきだったのですが、#2も今回のコードも、VBEditor のオプションの全般は、
「順次コンパイル」モードにしていなければなりません。それ以外の設定では試せません。

補足:
ご質問者さんはご存知のことで、これは初歩的なことですから、あまり殊更書くこともないと思いますが、最初のプロシージャは、両方とも、固定長配列(正確には、固定サイズ配列=Fixed Size)です。だから、どちらもIndex を拡張することは出来ません。余計ですが、おまけに、固定長文字列配列のプロシージャを作ってみました。

#2も以下のコードも、ローカルウィンドウで確認してください。

'//
'エラーが発生する(配列は既に宣言されている)
Sub Fixed-SizedArrayTest1()
 Dim astr1(9) As String '固定長配列
 Dim astr2(0 To 9) As String '固定長配列
 ReDim Preserve astr1(UBound(astr1) + 1)
 ReDim Preserve astr2(UBound(astr2) + 1)
End Sub

Sub DynamicArrayTest1()
'省略
'Dim astr1() As String '可変長配列
'Dim astr2() As String '可変長配列
'Dim astr3() As String '可変長配列
ReDim astr1(9) '動的配列
ReDim astr2(0 To 9) ''動的配列 (0 to 9) でも同じこと
ReDim astr3(5 To 9) ''動的配列 旧VB系のみ

ReDim Preserve astr1(UBound(astr1) + 1)
ReDim Preserve astr2(UBound(astr2) + 1)
ReDim Preserve astr3(LBound(astr3) To UBound(astr3) + 1)
End Sub

Sub FixedLengthStringArrayTest1()
 Dim astr1(9) As String * 20 '固定長文字列配列
 MsgBox Len(astr1(1))
End Sub

なお、私自身は、
Option Base 1
を使いません。理由のひとつは、Collection(コレクション) の時は、初期Index が、概ね、「1」からであり、配列の場合は、「0」からが多いので、その原則が違うと、返って分からなくなりそうな気がします。時々、初期値を合わせようとする人がいますが、返ってややこしいです。もうひとつの理由は、VB,Net では使われないからです。
    • good
    • 0
この回答へのお礼

貴重な例示、どうも有難う御座いました。
お蔭様で、たいへんよく理解することができました。
実際に、VBAで色々と試してみましたが十分納得の行く説明でした。
いままで、msdnをバイブル的に使って日本語で理解しずらい内容は
英文を探して理解に勤めてきましたが、今回も該当する英文を見つけました。
http://msdn.microsoft.com/en-us/library/aa163631 …
機械的ではなく逐語的に忠実な日本語訳で誤訳ではありませんでした。

仰せの通り、msdnの説明内容は配慮に欠ける記述なので気にする必要はないと思っています。
ただ、msdnの説明は必ずしも例示に基づいて説明しているのではなく、より安全サイドでの
説明をしていると理解すれば良いと思いました。逆に例示がなく説明だけに終始していれば
疑問も出て来なかったわけですから。例示があるのは、例示をも理解することで
msdnの説明文以上のことを汲み取れということとわきまえることに致します。

お礼日時:2010/09/22 01:01

>astr1は……astr2は固定長配列だと思います。



私も、astr2は、固定長配列だと思います。(参照:Test3r)
元の『プログラマーズガイド』を読んでみないと分かりませんか゜Webの上は、ダイジェストですから、正確ではありません。これは結果ですから、使いこなせれば文章が合っているか、そうでないかは必要ないでしょう。

>「両方の配列が動的配列」とは……
その文面に合うコードは、Test3() に該当するはずです。

サンプルを作ってきました。

'データ型が違うと失敗する
Sub Test1()
Dim astr1() As Variant '可変長配列
Dim astr2(0 To 9) As String '固定長配列
'astr1 は。配列には当てられません。
'-略-

'固定長配列から可変長配列(動的配列)に入れる
Sub Test2()
 Dim astr1() As String '可変長配列(動的配列)
 Dim astr2(0 To 9) As String '固定長配列
 Call MakingArray(astr2)
 ReDim astr1(UBound(astr2))
 astr1 = astr2
 '動的配列なら入るはず(Compile Err:配列はすでに宣言されています。)
'  ReDim Preserve astr2(10)
'  astr2(10) = "XX"
  '動的配列-こちらは入ります。
  ReDim Preserve astr1(10)
  astr1(10) = "XX"
 Stop
End Sub

'動的配列から可変長配列に入れる
Sub Test3()
Dim astr1() As String '可変長配列
Dim astr2() As String '動的配列
Call MakingArray(astr2, 9) 'MakingArray(動的配列, 添字)
 astr1 = astr2
 Stop
End Sub

'固定長配列を処理する失敗例
'Err:この配列は、固定されているか、または一時的にロックされています。
Sub Test3r()
Dim astr1() As String '可変長配列
Dim astr2(0 to 9) As String '固定長配列
Call MakingArray(astr2, 9) 'MakingArray(動的配列, 添字)
 astr1 = astr2
 Stop
End Sub

'可変長配列配列どうしの成功
Sub Test3r2()
Dim astr1() As String '可変長
Dim astr2() As String '可変長-動的配列
Call MakingArray(astr2, 9) '(動的配列, 添字)
 astr1 = astr2
 ReDim Preserve astr2(UBound(astr2) + 1)
 astr2(UBound(astr2)) = "XX" 'ここで入ります
 Stop
End Sub

'固定長配列から固定長に入れる
Sub Test4()
Dim astr1(0 To 9) As String
Dim astr2(0 To 9) As String
Call MakingArray(astr2)
For i = LBound(astr2) To UBound(astr2)
 If i <= UBound(astr2) Then
  astr1(i) = astr2(i)
 End If
Next
Stop
End Sub

'固定長から、Variant 型へ入れる
'String 型では失敗する。
Sub Test5()
Dim astr1 As Variant  'Variant型のみ、String 型では不可
Dim astr2(0 to 9) As String '固定長
Call MakingArray(astr2) '
 astr1 = astr2 'String型ですとErr
 Stop
End Sub

'//
'配列に代入する
Private Sub MakingArray(ar() As String, Optional num As Long = -1)
Dim i As Long
If num = -1 Then
For i = LBound(ar) To UBound(ar)
  ar(i) = Chr(65 + i)
Next
Else
ReDim ar(num)
For i = LBound(ar) To UBound(ar)
  ar(i) = Chr(65 + i)
Next
End If
End Sub
    • good
    • 0

固定長配列って、要素数が決定していて、必要な領域も事前に準備されているということですよね。



astr2は、「1~10個まで要素を持つことができる」という数が未決定の宣言なので、動的です。
使ってみるまで要素数がわからないが、ある程度要素数を明示的にしておくための宣言ですね。

ただこの場合、要素数の上限を設けているだけで、領域はセット時に拡張されます。

 astr1()    セット時、拡張 |・・・・・・・n  (入れ物なし)拡張可能
 astr2(0 To 9) セット時、拡張 |1|・・・・・10  最大10個まで拡張可能
 astr3(9)   固定入れ物10個 |1|2|~|9|10| 宣言時に確定。拡張不可
                  ・・・拡張の意味
で、どうでしょう。
    • good
    • 0
この回答へのお礼

確かに言われることは理解できました。
しかし、Microsoft Visual Basicのヘルプでは、
「動的配列を宣言するには、かっこの中のインデックス番号は、省略します。」
とあります。
動的配列の宣言をこれだけに限るとはありませんので、仰せの通りastr2(0 To 9)も動的だとすれば、
msdnの文は疑問の余地はなくなるわけですね。
どうも有難うございました。

お礼日時:2010/09/22 01:37

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