動的配列と固定長配列の違いについて分からなくなってしまいました。
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は固定長配列だと思います。
「両方の配列が動的配列」とはどのように理解すべきなのでしょうか。
No.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 では使われないからです。
貴重な例示、どうも有難う御座いました。
お蔭様で、たいへんよく理解することができました。
実際に、VBAで色々と試してみましたが十分納得の行く説明でした。
いままで、msdnをバイブル的に使って日本語で理解しずらい内容は
英文を探して理解に勤めてきましたが、今回も該当する英文を見つけました。
http://msdn.microsoft.com/en-us/library/aa163631 …
機械的ではなく逐語的に忠実な日本語訳で誤訳ではありませんでした。
仰せの通り、msdnの説明内容は配慮に欠ける記述なので気にする必要はないと思っています。
ただ、msdnの説明は必ずしも例示に基づいて説明しているのではなく、より安全サイドでの
説明をしていると理解すれば良いと思いました。逆に例示がなく説明だけに終始していれば
疑問も出て来なかったわけですから。例示があるのは、例示をも理解することで
msdnの説明文以上のことを汲み取れということとわきまえることに致します。
No.2
- 回答日時:
>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
No.1
- 回答日時:
固定長配列って、要素数が決定していて、必要な領域も事前に準備されているということですよね。
astr2は、「1~10個まで要素を持つことができる」という数が未決定の宣言なので、動的です。
使ってみるまで要素数がわからないが、ある程度要素数を明示的にしておくための宣言ですね。
ただこの場合、要素数の上限を設けているだけで、領域はセット時に拡張されます。
astr1() セット時、拡張 |・・・・・・・n (入れ物なし)拡張可能
astr2(0 To 9) セット時、拡張 |1|・・・・・10 最大10個まで拡張可能
astr3(9) 固定入れ物10個 |1|2|~|9|10| 宣言時に確定。拡張不可
・・・拡張の意味
で、どうでしょう。
確かに言われることは理解できました。
しかし、Microsoft Visual Basicのヘルプでは、
「動的配列を宣言するには、かっこの中のインデックス番号は、省略します。」
とあります。
動的配列の宣言をこれだけに限るとはありませんので、仰せの通りastr2(0 To 9)も動的だとすれば、
msdnの文は疑問の余地はなくなるわけですね。
どうも有難うございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
IF関数でEmpty値を設定する方法。
-
変数を動的に作るには?
-
VBで作った乱数を一度も重複さ...
-
VBAで配列の計算
-
動的配列が存在(要素が有る)か...
-
パソコンキーボードで時分秒を...
-
EXCEL VBA で、0から?1から?
-
VB.net 引数で配列変数を渡す際...
-
格闘ゲームのコマンド判定について
-
複数のテキストボックスに同じ...
-
C#でのコントロール配列について
-
遅延バインディングを使用でき...
-
重複なしでランダムに画像を表...
-
VBA 配列数式的に一括してR...
-
For文と配列
-
VBA 配列で重複した単語が格納...
-
エクセルで小数の中の最大値を...
-
【MFC】GetCount()とGetSize()...
-
配列の要素数を超えた参照のコ...
-
EXCELVBA 配列値集計方法
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
IF関数でEmpty値を設定する方法。
-
パソコンキーボードで時分秒を...
-
VBAで配列の計算
-
EXCEL VBA で、0から?1から?
-
変数を動的に作るには?
-
動的配列が存在(要素が有る)か...
-
VB.net 引数で配列変数を渡す際...
-
VBで作った乱数を一度も重複さ...
-
複数のテキストボックスに同じ...
-
VBでbyte配列型のインスタンス...
-
遅延バインディングを使用でき...
-
配列の要素数を超えた参照のコ...
-
【MFC】GetCount()とGetSize()...
-
C言語 重複しない4ケタの乱数...
-
C# での文字列パディング
-
五目並べのプログラムを配列と...
-
For文と配列
-
Excel VBAで配列の途中から(X)M...
-
ジャグ配列とは
-
10進数を4桁のバイト配列に格納...
おすすめ情報