Option Explicit Dim stTgt As String '検索対象の区 Dim stAry() As String '配列 Dim cTo As Long 'データ書き出し先の行 Sub ListUpBukken() Columns("I:J").ClearContents
cTo = 2
stTgt = "渋谷区" ExeKensaku
stTgt = "世田谷区" ExeKensaku
stTgt = "目黒区" ExeKensaku
stTgt = "港区" ExeKensaku
stTgt = "品川区" ExeKensaku
End Sub Sub ExeKensaku() Dim cFm As Long '元データ表でForNext構文が使う変数 Dim cMx As Long '元データ表の最大行 Dim cAry As Long '配列のインデックス用
cMx = Range("A65536").End(xlUp).Row
cAry = 0 Erase stAry・・・・・・これをとっても結果は同じなる? For cFm = 2 To cMx If Range("C" & cFm).Value = stTgt Then ReDim Preserve stAry(cAry) stAry(cAry) = Range("F" & cFm).Value cAry = cAry + 1 End If Next
平吹 敦史さんの投稿
(投稿ID: 2932)
テキストP41、Chap02-61のEraseステートメントの下記例題ですが、
Erase stAryの一文があってもなくても結果は一緒でした。
ステップインで追いかけましたが、いまいちわかりませんでした。
どうも、stAry(cAry)のcAry=0で例えば渋谷区の配列の中身が世田谷区の中身に上書きされた時点で、
それ以降の配列はクリアになるようでした。
なので、あえてErase stAryの一文が必要なのでしょうか?
最初は、前の配列がそのまま残っているので、クリアにしないと不要な配列が書き出されてしまうイメージでした。データ数が一緒なら上書きされて問題ないが、データ数が少ないと不要なデータが書き出されてしまうイメージです。
ですが、結果が違ったので???状態です。
ご教授願います。
Option Explicit
Dim stTgt As String '検索対象の区
Dim stAry() As String '配列
Dim cTo As Long 'データ書き出し先の行
Sub ListUpBukken()
Columns("I:J").ClearContents
cTo = 2
stTgt = "渋谷区"
ExeKensaku
stTgt = "世田谷区"
ExeKensaku
stTgt = "目黒区"
ExeKensaku
stTgt = "港区"
ExeKensaku
stTgt = "品川区"
ExeKensaku
End Sub
Sub ExeKensaku()
Dim cFm As Long '元データ表でForNext構文が使う変数
Dim cMx As Long '元データ表の最大行
Dim cAry As Long '配列のインデックス用
cMx = Range("A65536").End(xlUp).Row
cAry = 0
Erase stAry・・・・・・これをとっても結果は同じなる?
For cFm = 2 To cMx
If Range("C" & cFm).Value = stTgt Then
ReDim Preserve stAry(cAry)
stAry(cAry) = Range("F" & cFm).Value
cAry = cAry + 1
End If
Next
Range("I" & cTo).Value = stTgt & "の物件は " & UBound(stAry) + 1 & "件ヒットしました!"
cTo = cTo + 1
For cFm = LBound(stAry) To UBound(stAry)
Range("J" & cTo).Value = stAry(cFm)
cTo = cTo + 1
Next
cTo = cTo + 1
End Sub
ゲストさんのコメント
(コメントID: 4405)
何もない状態から再スタートするか、上書きするか、
という違いがありますね。
で、最初に実行するとき、[1]の段階で、 cAry = 0 です。
そして、直後の[2]で、stAry(0) に値を格納しています。
ところで、 Erase stAry で配列 stAry を初期化しないと、[1] の直後の段階では、前回投入した値が stAry(0) にまだ残っています。
Erase stAry で配列 stAry を初期化したあとだと、 [1] の直後の段階では、 stAry(0) にまだ何も入っていません。
ここで、「直後に上書きするんだから、値が入っててもいいじゃない」と思うか、「すべてスッキリした状態で再スタートのほうが気持ちいい!」と思うか?の違いがあります。
好みの問題に聞こえるかもしれません。
しかし、後者のほうがより安全なので、僕は、後者の方法を推したいですね。
平吹 敦史さんのコメント
(コメントID: 4406)
お世話様です。
もう少し突っ込んだ質問です。
前回投入した値の数が7つ。(事例でいうと世田谷区)
stAry(0)
stAry(1)
stAry(2)
stAry(3)
stAry(4)
stAry(5)
stAry(6)
次に投入した値が3つ。(目黒区)
stAry(0)・・・上書きされる
stAry(1)・・・上書きされる?
stAry(2)・・・上書きされる?
Erase stAryで初期化しなくとも、世田谷区の下記4つが
残らないのはなぜでしょうか?
stAry(3)
stAry(4)
stAry(5)
stAry(6)
そこの仕組みがどうしても理解できません。
私の頭の理解では、preserveなので、初期化してない限りは、
そのまま残って、書き出されてしまうはずなんですが・・・
なので、ますますEraseの意味がピンとこないのです。
面倒な質問ですいません。
>平吹 敦史 さん:
>
>何もない状態から再スタートするか、上書きするか、
>という違いがありますね。
>
>
>
>で、最初に実行するとき、[1]の段階で、 cAry = 0 です。
>そして、直後の[2]で、stAry(0) に値を格納しています。
>
>ところで、 Erase stAry で配列 stAry を初期化しないと、[1] の直後の段階では、前回投入した値が stAry(0) にまだ残っています。
>
>Erase stAry で配列 stAry を初期化したあとだと、 [1] の直後の段階では、 stAry(0) にまだ何も入っていません。
>
>ここで、「直後に上書きするんだから、値が入っててもいいじゃない」と思うか、「すべてスッキリした状態で再スタートのほうが気持ちいい!」と思うか?の違いがあります。
>
>好みの問題に聞こえるかもしれません。
>しかし、後者のほうがより安全なので、僕は、後者の方法を推したいですね。
>
ゲストさんのコメント
(コメントID: 4407)
小川慶一 さん:
これで、どうでしょうか。この図で、理解の整理、進みますかね。
https://www.dropbox.com/s/xtmuutquwb9x4gu/redimpreserveimage.JPG?dl=0
平吹 敦史さんのコメント
(コメントID: 4408)
なるほどです!
仕組みを勘違いしていました。
丁寧にありがとうございました。
>平吹 敦史 さん:
>
>小川慶一 さん:
>
>これで、どうでしょうか。この図で、理解の整理、進みますかね。
>https://www.dropbox.com/s/xtmuutquwb9x4gu/redimpreserveimage.JPG?dl=0
>
ゲストさんのコメント
(コメントID: 4411)
よかったです。
行き詰まることがあれば、また、いつでもどうぞ☆