エクセルマクロ オンライン講座コメント紹介

コメント紹介
   └ エクセルマクロ・VBA発展編2
       └ 配列操作の便利関数、オプション、その他

配列操作の便利関数、オプション、その他

[7883] 2017-03-31 11:15:42 平吹 敦史さんからの投稿です。

お世話様です。

テキスト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

 


[7886] 2017-03-31 14:04:37 小川慶一さんからの投稿です。

平吹 敦史 さん:

何もない状態から再スタートするか、上書きするか、
という違いがありますね。

ReDim Preserve stAry(cAry) '[1]
stAry(cAry) = Range("F" & cFm).Value '[2]


で、最初に実行するとき、[1]の段階で、 cAry = 0 です。
そして、直後の[2]で、stAry(0) に値を格納しています。

ところで、 Erase stAry で配列 stAry を初期化しないと、[1] の直後の段階では、前回投入した値が stAry(0) にまだ残っています。

Erase stAry で配列 stAry を初期化したあとだと、 [1] の直後の段階では、 stAry(0) にまだ何も入っていません。

ここで、「直後に上書きするんだから、値が入っててもいいじゃない」と思うか、「すべてスッキリした状態で再スタートのほうが気持ちいい!」と思うか?の違いがあります。

好みの問題に聞こえるかもしれません。
しかし、後者のほうがより安全なので、僕は、後者の方法を推したいですね。

 


[7887] 2017-03-31 17:09:03 平吹 敦史さんからの投稿です。

小川慶一 さん:

お世話様です。
もう少し突っ込んだ質問です。

前回投入した値の数が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の意味がピンとこないのです。

面倒な質問ですいません。

>平吹 敦史 さん:
>
>何もない状態から再スタートするか、上書きするか、
>という違いがありますね。
>
>
ReDim Preserve stAry(cAry) '[1]
>stAry(cAry) = Range("F" & cFm).Value '[2]

>
>で、最初に実行するとき、[1]の段階で、 cAry = 0 です。
>そして、直後の[2]で、stAry(0) に値を格納しています。
>
>ところで、 Erase stAry で配列 stAry を初期化しないと、[1] の直後の段階では、前回投入した値が stAry(0) にまだ残っています。
>
>Erase stAry で配列 stAry を初期化したあとだと、 [1] の直後の段階では、 stAry(0) にまだ何も入っていません。
>
>ここで、「直後に上書きするんだから、値が入っててもいいじゃない」と思うか、「すべてスッキリした状態で再スタートのほうが気持ちいい!」と思うか?の違いがあります。
>
>好みの問題に聞こえるかもしれません。
>しかし、後者のほうがより安全なので、僕は、後者の方法を推したいですね。
>

 


[7888] 2017-03-31 17:25:28 小川慶一さんからの投稿です。

平吹 敦史 さん:

小川慶一 さん:

これで、どうでしょうか。この図で、理解の整理、進みますかね。
https://www.dropbox.com/s/xtmuutquwb9x4gu/redimpreserveimage.JPG?dl=0

 


[7889] 2017-03-31 18:43:18 平吹 敦史さんからの投稿です。

小川慶一 さん:

なるほどです!
仕組みを勘違いしていました。

丁寧にありがとうございました。


>平吹 敦史 さん:
>
>小川慶一 さん:
>
>これで、どうでしょうか。この図で、理解の整理、進みますかね。
>https://www.dropbox.com/s/xtmuutquwb9x4gu/redimpreserveimage.JPG?dl=0
>

 


[7894] 2017-04-01 10:44:45 小川慶一さんからの投稿です。

平吹 敦史 さん:

よかったです。

行き詰まることがあれば、また、いつでもどうぞ☆

 


まずはここから!スマホでも学べる無料動画講座

今なら先着30名限定で無料!定価4,800円の、初心者のためのエクセルマクロ動画講座。
  1. Excel 97~Excel 2016まですべて対応。動画本数20本、総再生時間2時間44分53秒
  2. PC, Mac, iPhone, iPad, Androidのお好みの環境で、いつでも好きなときに学べます。
2004年から10年間述べ3,000名以上に実施した研修の経験と実績を集約した講座です。
いますぐ無料で試してください。

トップへ