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

  • このエントリーをはてなブックマークに追加
コメント紹介

エクセルマクロオンライン講座への質問とその回答から

[7905] 2017-04-07 05:52:55 平吹 敦史さんからの投稿です。

お世話になっております。

連想配列について質問です。

Chap02-71のSheet2の演習で、取引金額をH列にも追加して、
KeyはB列ひとつなんですが、ItemがG列とH列です。

書き出し先は、KeyがI列、ItemがG列→J列、H列→K列です。

とりあえず正しく反映しますが、以下コードで問題ないか、
アドバイスをお願いします。

なんとなくですが、removeallでいったんクリアにするので、
それが悪さしないのか心配です。

Sub GetCount()
Dim dic As Scripting.Dictionary
Set dic = CreateObject("Scripting.Dictionary")

Dim c As Long
Dim r As Long
Dim st As String

For r = 0 To 1
For c = 0 To Range("A" & Rows.Count).End(xlUp).Row - 2
st = Range("B2").Offset(c).Value
If dic.Exists(st) Then
dic.Item(st) = dic.Item(st) + Range("G2").Offset(c, r).Value
Else
dic.Add (st), Range("G2").Offset(c, r).Value
End If
Next

Dim vKeys As Variant
Dim vItems As Variant
vKeys = dic.Keys
vItems = dic.Items
For c = LBound(vKeys) To UBound(vKeys)
Range("I2").Offset(c).Value = vKeys(c)
Range("J2").Offset(c, r).Value = vItems(c)
Next
dic.RemoveAll
Next

End Sub

 


[7908] 2017-04-07 09:29:46 小川慶一さんからの投稿です。

平吹 敦史 さん:

おはようございます。

初期化のタイミングをどこにするか?ということですね。

基礎編フォローアップでその基本を解説している問題があります。

○出現回数を数える。CountIf関数がやっていることをマクロで書くと?
https://padstudy.jp/detail?movie_id=150&package_id=27

以下、この動画内での解説をさらにシンプルに表現してみます。
上記動画での解説は複数のものについて調査→出力するときのパターンのあくまで一例ですが、要は、こういうこと↓です。

for ループ外
初期化
調査
出力
next



この調査の部分で forループを使っています。以下のとおり。

for ループ外
初期化
for ループ内1 '調査
...
next
出力
next



もちろん、出力にforループを使うことが必要になる場合もあります。すると、以下。

for ループ外
初期化
for ループ内1 '調査
...
next
for ループ内2 '出力
...
next
next



↑これは、今回の連想配列の課題のパターンですね。

さて。
平吹さんが今回書かれたコードは、こう↓なっていますね。

for ループ外
for ループ内1 '調査
...
next
for ループ内2 '出力
...
next
初期化
next



これを、改めて、最初に示したものレベルまで簡略化して表現すると、以下のとおり。

for ループ外
調査
出力
初期化
next



今回いただいたご質問は、要は、「さて、↑これでどうか?」ということです。

では、どうでしょうか。
ご自身で考えて、またコメントいただければと思います。いっしょに考えましょう。

なお、今回一点だけ指摘しておくと、以下の2つの変数宣言は、僕なら、「for ループ外」より前に持っていきます。

Dim vKeys As Variant
Dim vItems As Variant

では、どうしてか?
これについても、ご自身で考えみてて、またコメントいただければと思います。

まずは、以上のとおりです。


>お世話になっております。
>
>連想配列について質問です。
>
>Chap02-71のSheet2の演習で、取引金額をH列にも追加して、
>KeyはB列ひとつなんですが、ItemがG列とH列です。
>
>書き出し先は、KeyがI列、ItemがG列→J列、H列→K列です。
>
>とりあえず正しく反映しますが、以下コードで問題ないか、
>アドバイスをお願いします。
>
>なんとなくですが、removeallでいったんクリアにするので、
>それが悪さしないのか心配です。
>
>Sub GetCount()
> Dim dic As Scripting.Dictionary
> Set dic = CreateObject("Scripting.Dictionary")
>
> Dim c As Long
> Dim r As Long
> Dim st As String
>
> For r = 0 To 1
> For c = 0 To Range("A" & Rows.Count).End(xlUp).Row - 2
> st = Range("B2").Offset(c).Value
> If dic.Exists(st) Then
> dic.Item(st) = dic.Item(st) + Range("G2").Offset(c, r).Value
> Else
> dic.Add (st), Range("G2").Offset(c, r).Value
> End If
> Next
>
> Dim vKeys As Variant
> Dim vItems As Variant
> vKeys = dic.Keys
> vItems = dic.Items
> For c = LBound(vKeys) To UBound(vKeys)
> Range("I2").Offset(c).Value = vKeys(c)
> Range("J2").Offset(c, r).Value = vItems(c)
> Next
> dic.RemoveAll
> Next
>
>End Sub
>

 


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

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

トップへ