条件4項目 日付&単位&単価&区分(A列、C列、D列、F列)の一致するもののB列及びE列を集計して別シートに書き出したいのです。 

sheet1
A   B   C   D   E   F
日付 数  単位 単価 計  区分
3/12  2    人  10000 20000  通常
3/12  1    人  10000 10000  通常
3/12  1    時間  2000 10000  残業
3/14  4    時間  2000  8000  残業
3/15  4    人  10000 40000  通常

このような表を
sheet2
A   B   C   D   E   F
日付数単位単価計区分
3/12  3    人  10000 30000  通常
3/12  1    時間  2000 10000  残業
3/14  4    時間  2000  8000  残業
3/15  4    人  10000 40000  通常

のようにまとめたいのです。
Dictionaryを用い、A列、C列、D列、F列を一旦結合しkeyとし、同じものが登録されていたら、itemとしてB列及びE列の値を加算させて、登録件数分を書き出しという流れでやりたいのですが、出来ません。
助けて下さい。お願いします。

このQ&Aに関連する最新のQ&A

A 回答 (5件)

/qa4512348.html の続きですか?


その情報をリンク貼っておけば回答側の参考にもなったと思いますよ。

>DictionaryのItemには追加時に連番をふりながら(その連番を)Indexとしてセットし、
>『集計&転記用の配列を別に用意』し、
>Indexでその配列への加算位置を指定してあげるほうが簡単かもしれません。
と書いてたでしょう。

Sub try_3()
  Dim dic As Object 'Dictionary用
  Dim s  As String 'キー文字列結合用
  Dim key As Variant 'key列用
  Dim ary As Variant '集計列用
  Dim c  As Variant '配列Loop用
  Dim v  As Variant '元データ格納用配列
  Dim w  As Variant 'データ集計・書き出し用配列
  Dim n  As Long  '配列の要素index用
  Dim i  As Long
  Dim j  As Long

  key = Array(1, 3, 4, 6) 'key列
  ary = Array(2, 5)    '集計列

  With ThisWorkbook
    v = .Sheets("sheet1").Range("A1").CurrentRegion '.Resize(, 6)
    ReDim w(1 To UBound(v, 1), 1 To UBound(v, 2))

    Set dic = CreateObject("Scripting.Dictionary")
    n = 0
    For i = 1 To UBound(v)
      'キー文字列 s として結合
      s = ""
      For Each c In key
        s = s & v(i, c) & vbTab
      Next
      If dic.Exists(s) Then
        '既登録ならindexを取得
        j = dic(s)
      Else
        '未登録ならindexを追加
        n = n + 1
        dic(s) = n
        j = n
        '未登録なら書き出し用配列 w にkey列をセット
        For Each c In key
          w(j, c) = v(i, c)
        Next
      End If
      '書き出し用配列 w に集計列を加算
      For Each c In ary
        w(j, c) = w(j, c) + v(i, c)
      Next
    Next

    With .Sheets("sheet2")
      .UsedRange.ClearContents
      .Range("A1").Resize(n, UBound(w, 2)).Value = w
    End With
  End With

  Set dic = Nothing
End Sub

前回のコードでも、keyを増やして
key1 key2 key3 key4 集計1 集計2
日付 単位 単価 区分 数   計
の順で書き出した後に、列を入れ替えればよかったんじゃないですか?

#以下、既に実施済みでしたら読み飛ばしてください。
コードを理解するには、ただ眺めるだけじゃなく、VBE[F8]キーで1ステップずつ実行するのが効果的です。
その時[ローカルウィンドウ]を表示させて、変数や配列への格納のされ方も確認してくださいね。

この回答への補足

 end-uさん最近はお世話になりっぱなしです。
全てend-uさんのおっしゃる通りです。じつは前回のコードで、keyを増やして
key1 key2 key3 key4 集計1 集計2
日付 単位 単価 区分 数   計
の順で書き出した後に、列を入れ替えて書き出して動かしてました。(下記のコードで入れ替え。)

 vntData_2 = Columns("B").Value
vntData_3 = Columns("C").Value
vntData_4 = Columns("D").Value
vntData_5 = Columns("E").Value
vntData_6 = Columns("F").Value

Columns("B").Value = vntData_5
Columns("C").Value = vntData_2
Columns("D").Value = vntData_3
Columns("E").Value = vntData_6
Columns("F").Value = vntData_4
しかし、少し時間(列入れ替え時)かかるのと、今回は入れ替えの無いパターンなので、前は作れたのに、時間が経って忘れてしまったのか、今回は単純なパターンなのにつまづいてしまったのは、基礎が、身に付いてなかったせいと思い、そこでまた皆様のお力をお借りしたのでした。本当に忘れないようにします。私は、出張が多いので、本当にお世話になりまくりのend-uさんには、何かお土産でも渡したいと思ってます(心から)なにかよい方法(メールアドレス等)でも教えてもらえれば幸いです。今また出かけなければならないので、ここのお礼は、後ほど必ずいたします。YOKOKAMA46

補足日時:2009/05/13 16:36
    • good
    • 0
この回答へのお礼

end-uさん。今戻りました。バッチリです。
しかしまだまだ
ReDim w(1 To UBound(v, 1), 1 To UBound(v, 2))の部分が私にとって鬼門です。配列の要素数の再定義 この部分をしっかり理解しないと、一気に出来ず、Dictionaryを2回使ったりしなければならなくなりそうです。この部分を勉強させてもらいます。

お礼日時:2009/05/13 22:08

#4補足に対するレスを入れておきます。


(もしかしたら削除対象回答に該当するかもしれませんが、事務局のご判断におまかせします。)

お礼についてはお気持ちだけで充分です。お気になさらず。
回答側の立場で投稿してますが、私も勉強になる事が多いです。
回答者というより利用者という感覚で、Q&Aをケーススタディとして勉強させてもらってます。
それに
http://help.okwave.jp/okwave/beginner/beginner.h …
『OKWaveは利用者の方々からの「質問」と「回答」を通し、世の中のあらゆる問題の解決と、人と人の相互協力のリレーション作りを目指すQ&Aサイトです。』
とあるように、『相互協力』ですから、利用者各個人の得意分野を補完し合っていけば良いのだと思います。
直接私に対してではなくとも、貴方も誰かのお役に立たれているはずです。
そういった連鎖関係の中でお互いが得していると考えておけば良いんじゃないでしょうか。
それはこれから先の事でも構わないし、このコミュニティ内に限った事でもないと思います。


他、今後気をつけたほうがいい事として1点、アドバイスです。
今一度、『■禁止事項ガイドライン』に眼を通されておかれたほうが良いでしょう。
http://help.okwave.jp/okwave/beginner/prohibitio …
会員間の直接のやり取りを促すような記述は削除・編集の対象となっています。
私もメールアドレスなどを公開するつもりはありませんし、前述したように、何か物的なものをお受けするつもりはさらさらありません。
(かといって、補足にお書きになった事で気分を害しているわけでもありません。本当に、お気持ちだけ嬉しくお受け致します^ ^)



本来は、このレスも『指摘回答』だと判断されて削除対象になるかもしれませんが、私からもお礼の気持ちが伝わればと思って書きました。
では、今後ともよろしくお願いします。お互いにこのコミュニティを通して、問題解決やスキルアップができれば良いですネ。
    • good
    • 1
この回答へのお礼

end-uさん。有難うございます。
おっしゃるとおり今まで KenKen-SPさん、n-junさん、onlyromさん、redfox63さん,そしてend-uさん、そのほかの方々 色々な方にお世話になっております。OKWAVEには感謝しております。
end-uさんには特にお世話になっている回数が多いのと私のプロフィールに書いてある通り、以前の私の質問に(締切済み)追加でメール頂いた件は、内容もその後の私の悩みにドンピシャだったので非常に助かった思いがありました。そこで今回のような発言だったのですが、禁止事項ガイドラインにふれるのですね。無念です。それではせめて、end-uさんのご多幸を祈らせて頂くことにとどめます。
またお手数かけることも多いとは思いますが今後もよろしくお願いいたします。yokokama46

お礼日時:2009/05/13 22:29

Excel(エクセル) VBA入門:Dictionaryオブジェクトを利用する


http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/v …
【Dictionaryオブジェクトを作成する】
”・ところが、A列の品名が重複していると、~”
と言う所が参考になるのでは?

この回答への補足

n-junさん 以前も助けて頂きました。今回もまたお手数かけます。
以前もDictionaryを用い似たような集計(条件列と集計列が書き出し時に一部入れ替えがあるので、集計列をaryで示すという方法でした)
今回は書き出し時にレイアウト変更がないのですが、基本を押さえてなかったようで、自分でうまくいきません。
ご提示のページも参考にさせていただきましたが、4条件を結合は下記でよいと思いますが、その先の2つのアイテム追加のしかたと、出来たとしても書き出し時がいまいち解りません。これを機に今一度Dictionaryの勉強をしますので、なにとぞご教示のほどよろしくお願いします。

myVal = sh1.Range("F1", sh1.Range("A" & sh1.Rows.Count).End(xlUp)).Value

Set myDic = CreateObject("Scripting.Dictionary")

For i = 2 To UBound(myVal, 1)

End If
myVal2 = myVal(i, 1) & "_" & myVal(i, 3) & "_" & myVal(i, 4) & "_" & myVal(i, 6)
If Not myVal2 = "_" & "_" & "_" Then
If myDic.exists(myVal2) Then

補足日時:2009/05/13 15:31
    • good
    • 0
この回答へのお礼

n-junさん返事遅れてすみません。以前n-junさんから頂いたコードのシンプル版なので、end-uさんへの補足に述べさせて頂いたとおり、n-junさんから頂いたコードを最後に列の入れ替えをして、対応は出来たのですが、入れ替え無いパターンは(ただし集計列1列)自分でも出来ていたので、集計列2列にも挑戦したのですが、撃沈でした。そこでn-junさんから頂いたコードを最後に列の入れ替えをする対応で済ます予定でしたが、せっかくだから基本を覚えようと思ったしだいです。n-junさんは色々なかたに幅広く答えていらっしゃいますし私も何度かお世話になっております。重ねてお礼申し上げます。
またよろしくお願いします。yokokama46

お礼日時:2009/05/13 22:02

エクセルVBAを、どれほどこなせるレベルか知ら無いが、Dictionaryなどの凝った仕組みを使わずとも、普通のVBA(ソート法などで)簡単に出来るよ。

Dictionaryの練習問題ならいざ知らず、ベテランはなるべく単純な使い慣れた仕組みを使うと思う。
Dictionaryを使いこなせるレベルなら、デバッグなど自力で出来る力が有るはずだ。
Googleででも「VBScript dictionary」で照会でもして、たくさん出る記事の適当なものを読みましたか。
ーーー
文字列を結合したKeyを作るとき、定桁結合式にしないと、おかしくなることが有ることを注意してますか。
ーーー
私の言うやり方でやってみる。
IFと代入しか使ってない。質問者は、他シート参照がなれているかな。
ただしロジックは易しいと思うが、先人のロジックで、長く使い続けて慣れた面はある。
例データ ソート後
日付数単位単価計区分
3月12日1時間200010000残業
3月12日2人1000020000通常
3月12日1人1000010000通常
3月12日4人1000010000通常
3月12日2人1000020000通常
3月14日4時間20008000残業
3月14日2人1000020000通常
3月15日4人1000040000通常
3月15日1人2000020000通常
3月15日2人2000020000通常
ーー
コード
Sub test01()
Dim sh1, sh2 As Worksheet
Set sh1 = Worksheets("Sheet2")
Set sh2 = Worksheets("Sheet3")
d = sh1.Range("A65536").End(xlUp).Row
MsgBox d
k = 2: t1 = 0: t2 = 0
m1 = sh1.Cells(2, "A"): m2 = sh1.Cells(2, "C"): m3 = sh1.Cells(2, "D"): m4 = sh1.Cells(2, "F")
'---
For i = 2 To d
If sh1.Cells(i, "A") = m1 And sh1.Cells(i, "C") = m2 And sh1.Cells(i, "D") = m3 And sh1.Cells(i, "F") = m4 Then
t1 = t1 + sh1.Cells(i, "B")
t2 = t2 + sh1.Cells(i, "E")
Else
sh2.Cells(k, "A") = m1
sh2.Cells(k, "B") = t1
sh2.Cells(k, "C") = m2
sh2.Cells(k, "D") = m3
sh2.Cells(k, "E") = t2
sh2.Cells(k, "F") = m4
k = k + 1
m1 = sh1.Cells(i, "A"): m2 = sh1.Cells(i, "C"): m3 = sh1.Cells(i, "D"): m4 = sh1.Cells(i, "F")
t1 = sh1.Cells(i, "B")
t2 = sh1.Cells(i, "E")
End If
Next i
sh2.Cells(k, "A") = m1
sh2.Cells(k, "B") = t1
sh2.Cells(k, "C") = m2
sh2.Cells(k, "D") = m3
sh2.Cells(k, "E") = t2
sh2.Cells(k, "F") = m4
End Sub
ーーー
結果
日付数単位単価計区分
2009/3/121時間200010000残業
2009/3/129人1000060000通常
2009/3/144時間20008000残業
2009/3/142人1000020000通常
2009/3/154人1000040000通常
2009/3/153人2000040000通常
第1行見出しは、元のシートの見出し行をコピー貼り付けする。

この回答への補足

imogasiさん。急用で出かけてまして今戻りました。返事遅れてすいません。出かける直前に、最後のend-uさんのコードを試させて頂き動きました。imogasiさんのは今試させていただいたのですが、imogasiさんの例示とその結果のようになればよいのですが、なぜか、同項目同士の累計がなされませんでした。(累計なくまったく同じものが転記される)。もしかしたら私のミスかもしれませんのでお気を悪くせずに今後もよろしくお願いします。

補足日時:2009/05/13 21:37
    • good
    • 0

まずはできているものを提示なさっては?


また、どのようにうまくいかないのでしょうか?

この回答への補足

fujillinさん初めまして。最初に返事頂いたのに諸事情により、返事遅れてすみませんでした。やりたかったことと途中までのコードは、n-junさんへの解答のとうりでした。色んな方のお力をお借りしてばかりの私なので今後ともよろしくお願いします。

補足日時:2009/05/13 21:45
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qツイッターに登録したいのですが、ツイッターjpをクリックしても、.co

ツイッターに登録したいのですが、ツイッターjpをクリックしても、.comになり、英語のツイッターのサイトに飛んでしまいます。これは、なぜでしょうか・・・・詳しい方、宜しくお願いします・・・

Aベストアンサー

画面右下に言語が選択できるところがあります。
はっきり言ってすごくわかりづらく、自分もずっと
英語版しかないのかと思っていました・・・

Q重複列があり、その他の列を同じ列にかえす

こういったselect文ってつくれるんでしょうか?
ネットで調べてもこういった答えが見つけられなかったので…
おわかりの方いましたら、よろしくお願いします。

列1  | 列2  | 列3

1    |りんご  |きゅうり
1    |みかん  |なす
2    |かき   |はくさい
2    |なし    |キャベツ
3    |もも    |ごぼう
3    |キウイ  |きのこ



1   |りんご/みかん|きゅうり/なす
2   |かき/なし   |はくさい/キャベツ
3   |もも/キウイ  |ごぼう/きのこ

っていうことがしたいんですが…
列1の重複ごとにまとめて、2、3をまとめて1つの列にいれるような
selectで表示されるような文です。
2、3は一応文字列なので、集計とか考えていないです。

Aベストアンサー

ムリです。

列2の内容を他のレコードの列2とバインドするようなSQLはかけません。用意されていません。
どうしてしたのら、VBとかフォロントエンドで処理をしてください。

QAmazon.co.jp VS @TOWER.JP VS HMV.co,jp

だいたいCD(ほぼ洋楽)を月10枚以上買います。通勤の関係上最近店舗に行って買うことが難しくなりこれからはネットで買うしかないな、ということでタイトルにあげた3つのどれを使おうか迷ってます。

お勧めなどありましたら教えて下さい。他のお勧めのサイトがありましたらそれでも結構です。

<今までCDの購入は会社帰りにタワーレコードの店舗に行って、とくに目当てのもの以外は店内をぶらぶらして視聴したりジャケ買いしたりしてました。>

Aベストアンサー

私は上記の3店で利用したことがあるのはTOWERだけなのでお役に立てないかもしれませんが・・・

1.送料無料になる購入額が一番安いのがアマゾン。
2.HP上の新譜情報が早いと思うのがHMV。
3.商品検索がしやすいのは新星堂(原則国内盤のみ)。

輸入盤は店によって価格がかなり異なることがあるので、
店独自のポイントシステムにこだわらないのであればそのつど価格を比較するのが賢明です。

QVB データテーブルA列とB列があった時、B列の1行目から1stepずつデータを入力していきたい

AddDataTableRowメソッドにて
1月として、A列は日付で先に31日分の行が作成されます。その際にB行はNothingで生成しました。
私は、A列はそのままでB列の1行目から1つずつ書き込んでいくコーディングが知りたいです。
現在はAddDataTableRowのためA列の最後の行の次の行が追加され入力されてしまいます。

Aベストアンサー

whereで列BがNothingだけにして、列AのMinの値を取得
列A指定して、狙い打ちでUpdate

Qinfoseekのカウンターはどうやってつけるの?

infoseekでホームページを作ったのですがカウンターがうまく付けられません。infoseekに聞いたら、
「カウンターってどうやってつけるの?
http://count.web.infoseek.co.jp/[iswebベーシックID]/Count.cgi」
を紹介されたのですが、このアドレスに移動してもカウンターがぽつんとあるだけです。これをどうすればいいのでしょうか。

Aベストアンサー

#2のnana_koです。
ソースを見させてもらったところ、貼り付けられたタグの記述に問題はありませんでした。
指定されたダグを貼り付けてもカウンタが表示されないということでもう一度、infoseekに問い合わせてみてはいかがでしょうか?
もしくは、フリーのカウンタを借りてきて貼り付けるとか。
早めにカウンタを設置したいなら、どこか違うところで借りてきたほうが早いと思われます。
(無料カウンタのリンク集を紹介しておきます。)

参考URL:http://tadamono.to/counter.html

Qマクロ 最終列をコピーして最終列の次の列に挿入する

マクロ 最終列をコピーして最終列の次の列に挿入する方法
マクロで最終列をコピーして、最終列の次の列に挿入する方法に苦戦しております。
(1)のところでエラーが出てしまいます。

列をコピーして次の列に挿入した時に挿入した列のセルの値をクリアしたいと思っております。

アドバイスの程、よろしくお願い致します

Sub ADD_Column()
Dim lastColumn As Integer

lastColumn = Cells(3, Columns.Count).End(xlToLeft).Column
Range(lastColumn).Copy Range(lastColumn + 1) '(1)

End Sub

Aベストアンサー

こんばんは!

lastColumn を「整数型」で宣言していますので、
列番号での操作方法にしてみてはどうでしょうか?

Sub ADD_Column()
Dim lastColumn As Integer
lastColumn = Cells(3, Columns.Count).End(xlToLeft).Column
Columns(lastColumn).Copy Destination:=Columns(lastColumn + 1)
Columns(lastColumn).ClearContents
End Sub

こんな感じではどうでしょうか?m(_ _)m

Q新 Infoseek メール

新 Infoseek メール(Windows Live)に登録ログインしてるのですが
楽天会員ログインとInfoseek メールのご利用開始手続きへの画面
https://mail.infoseek.co.jp/introduce1/index
の繰り返しになります。
どなたか登録できた方はいるのでしょうか?
お願いします。

Aベストアンサー

NO2で回答した者です。9月2日午前0時現在、
IEでは新メールへの手続きがしにくくなっており、cookieの設定を変更しても、先の症状が続いていますが、
Google chromeで、新メールへの手続きと旧メールからの移行などができました。

Google chromeなら、比較的簡単にインフォシークのTOP画面から、メール手続き画面に入れるようです(^^)

Q1列おき2列選択

 指定範囲(I9:CW40)の中で1列おきに2列選択したいのですが 、当然ですがマクロで記録はできても実行できませんし2行1列には関数式が入っているのでこれを除いて他の範囲(I71:CW99)に同じように1列おきに2列に「形式として貼り付け」ー「値」としたいのですが、お教え願えませんでしようか?



Sheets("メイン").Select
Range( _
"J9:K40,M9:N40,P9:Q40,S9:T40,V9:W40,Y9:Z40,AB9:AC40,AE9:AF40,AH9:AI40,AK9:AL40,AN9:AO40,AQ9:AR40,AT9:AU40,AW9:AX40,AZ9:BA40,BF9:BG40,BI9:BJ40,BL9:BM40,BO9:BP40,BR9:BS40,BU9:BV40,BX9:BY40,CA9:CB40,CD9:CE40,CG9:CH40,CJ9:CK40,CM9:CN40,CP9:CQ40,CS9:CT40,CV9:CW40" _
).Select
Range("CV9").Activate
Selection.Copy
End Sub

 指定範囲(I9:CW40)の中で1列おきに2列選択したいのですが 、当然ですがマクロで記録はできても実行できませんし2行1列には関数式が入っているのでこれを除いて他の範囲(I71:CW99)に同じように1列おきに2列に「形式として貼り付け」ー「値」としたいのですが、お教え願えませんでしようか?



Sheets("メイン").Select
Range( _
"J9:K40,M9:N40,P9:Q40,S9:T40,V9:W40,Y9:Z40,AB9:AC40,AE9:AF40,AH9:AI40,AK9:AL40,AN9:AO40,AQ9:AR40,AT9:AU40,AW9:AX40,AZ9:BA40,BF9:BG40,BI9:BJ40,BL9:BM40,BO9:BP40,BR9:BS40...続きを読む

Aベストアンサー

1列おきに2列に「形式として貼り付け」ー「値」としたいのですが
マクロの記録にばかり頼っていると、どうしてもコピーと貼り付けをイメージしてしまいますが
簡単な式で、値をほかのセルへ入れることが出来ます。

例えば
Sheets("コピー先").Range("J9:K40").Value=Sheets("メイン").Range("J9:K40").Value

とかでできます。

今回の質問の場合、列(JとかK)を順に変えたいので Cellsプロパティを使って
Sheets("コピー先").Range(Sheets("コピー先").Cells(9, 10), Sheets("コピー先").Cells(40, 11)).Value =・・・
と記述することになります。

Sub Macro1()
Dim j As Integer
Dim k As Integer
j = 10
k = 10
For i = 1 To 3
Sheets("コピー先").Range(Sheets("コピー先").Cells(9, k), Sheets("コピー先").Cells(40, k + 1)).Value = _
Sheets("コピー元").Range(Sheets("コピー元").Cells(9, j), Sheets("コピー元").Cells(40, j + 1)).Value
j = j + 3
k = k + 2
Next
End Sub

j = 10
k = 10
For i = 1 To 3
・・・
はそちらの都合に合わせて変更してください。
http://excelvba.pc-users.net/index.html
などのサイトを参考にして勉強してみてください。

1列おきに2列に「形式として貼り付け」ー「値」としたいのですが
マクロの記録にばかり頼っていると、どうしてもコピーと貼り付けをイメージしてしまいますが
簡単な式で、値をほかのセルへ入れることが出来ます。

例えば
Sheets("コピー先").Range("J9:K40").Value=Sheets("メイン").Range("J9:K40").Value

とかでできます。

今回の質問の場合、列(JとかK)を順に変えたいので Cellsプロパティを使って
Sheets("コピー先").Range(Sheets("コピー先").Cells(9, 10), Sheets("コピー先").Cells(40, 1...続きを読む

QEXCEL「Dictionaryオブジェクト」宣言

EXCEL VBAにて
Dictionaryオブジェクトを利用しようと思い
ネット検索して調べていると・・・

1)Dim MyDic As Object
Set MyDic=CreateObject("Scripting.Dictionary")

2) Dim MyDic As Scripting.Dictionary
Set MyDic = New Scripting.Dictionary

3) Dim MyDic
Set MyDic=CreateObject("Scripting.Dictionary")

4) Dim myDic As New Scripting.Dictionary

上記の4パターンが出てきました。
いずれも「連想配列」を使うものなのですが、

オブジェクト型、バリアント型、Newキーワードで宣言・・・

4つの違いがイマイチ理解できません。
違いを教えてください。

Aベストアンサー

1)Dim MyDic As Object
Set MyDic=CreateObject("Scripting.Dictionary")
参照設定無しで扱う場合

2) Dim MyDic As Scripting.Dictionary
Set MyDic = New Scripting.Dictionary
有りで・・

3) Dim MyDic
Set MyDic=CreateObject("Scripting.Dictionary")
無しで

4) Dim myDic As New Scripting.Dictionary
有りで

だけでは分からないので、用途・環境の面で考えてみました。
今回の場合は、Scripting.Dictionary なのでWindows2000の頃からバージョンは変わっていないので
説明しやすくするために、AccessからExcelをオートメーションで扱う例で説明します。
Scripting.Dictionary → Excel.Applicationです。
Excelに参照設定を行う場合はバージョンによって、Microsoft Excel xx.x Object Libraryの
xx.x が変わってくるのはご存知かと思います。

参照設定を行ってコーディングすれば、Excelのプロパティなどが自動表示されるので非常に楽ちんです。
Excelの定数もそのまま使えます。
ただ、2003に参照設定して作成したものを2010がインストールされている環境で使おうとした時など
参照設定不可になりますので、改めて設定しなおす必要があります。
一方無しでコーディングするのは上記お助け機能が使えないので手間ですが
バージョンが異なってもある程度は差異を吸収してくれます。
なので不特定のPCで使う場合は、有りで作成し、最終的に無しで動くように変更しています。
自身で使われるだけでしたら、2)で良いかとも思います。
(Scripting.Dictionary自体Windows2000?の頃から変わっていないし)

3)については、VBScript がこのパターンです。
(元々変数の型宣言ができないので。)
VBAではVariant型で宣言したものを再度Setでやり直しているので二度手間です。

4)は2)を1行にまとめたものですが
2)の場合は、Set・・した時点でインスタンスが作成されますが
4)は参照しに行って初めて作成されます。
また、Set ・・ Nothing で 2)は解放され以後は使えなくなりますが
4)はNothingした後でも参照しに行けばゾンビのごとく新たに立ち上がります。

以下のをローカルウィンドウかウォッチウィンドウで確認しつつ実行してみてください。
1行目と2・3行目のコメントアウトを入れ替えてみた場合も。

Sub DicTest()
Dim myDic As New Scripting.Dictionary
'Dim myDic As Scripting.Dictionary
'Set myDic = New Scripting.Dictionary
Stop

myDic.Add 0, "zero"
myDic.Add 1, "one"
Debug.Print "count1=" & myDic.Count
Debug.Print myDic(1)

Set myDic = Nothing
Stop
Debug.Print "count2=" & myDic.Count 'ゾンビ?復活
Stop
End Sub

余計わけわかんなくなったらゴメン。

1)Dim MyDic As Object
Set MyDic=CreateObject("Scripting.Dictionary")
参照設定無しで扱う場合

2) Dim MyDic As Scripting.Dictionary
Set MyDic = New Scripting.Dictionary
有りで・・

3) Dim MyDic
Set MyDic=CreateObject("Scripting.Dictionary")
無しで

4) Dim myDic As New Scripting.Dictionary
有りで

だけでは分からないので、用途・環境の面で考えてみました。
今回の場合は、Scripting.Dictionary なのでWindows2000の頃からバージョンは変わっていないので
説明しやすくするために、Access...続きを読む

Q現在2017/4/1から2018/3/31までの日月の入った表があります。ボタンを押すと1年足されて

現在2017/4/1から2018/3/31までの日月の入った表があります。ボタンを押すと1年足されて2018/4/1から2019/3/31になる VBAを教えてください。
よろしくお願いします。

Aベストアンサー

ANo3です。

>この様場合どうすれば自動で2/29が入りますか。
データをシリアル値(=Date型)で持つようにしているなら、うるう年は自動的に2/29日が表示できます。
(前回回答の式の表示調整の仕組みをご覧ください)

それよりも、
>表は一月ごとに区切ってあります。
・・という条件は、ご質問文には記載されていませんでしたので、ANo3で提示した式はA列に一年分がズラ~っと並ぶ前提で作成した式になっています。
(うるう年はきちんと反映されますし、翌年度に当たるセルは空白になる関数式になっています)

ひと月ごとに区切って記載するのであれば話が全然違うので、各月用に式を作成し、その月の分だけ表示できる式にしておく必要がありますね。
(添付写真では部分的にしか見えませんが、小計の行やそれ以外にも異なる種類の行が間に入っているようですので…)

>2/28から3/1の間が4行空いてます
添付の写真では2/28から3/1の間は11行空いているように見えますが…???


>表は一月ごとに区切ってあります。
2月を例に考えれば、通常は28日までで以下は空白、うるう年は29日まで表示して以下は空白になれば良いものと解釈しました。(上記の「4行」云々は意味不明なので無視しています)
そのようにするには「その月の範囲」を条件にして、あとは空白になるようにしておけば良いです。
(ANo3は年度外は空白になるようにしてありますが、それを月単位にすれば良い)

例えば2月の場合の例を挙げるとして、
前回同様に、A1セルに平成年度が数値であるものと仮定すれば・・・
その先頭(2/1)のセルには
 =DATEVALUE("h"&$A$1&"/2/1")
次のセルには
 =IF(前のセル<DATEVALUE("h"&($A$1)&"/3/1")-1,前のセル+1,"")
として31日分フィルコピーすれば、ひと月分が表示されるはずです。
(「前のセル」とあるのは2/1を表示しているセル番地のことです)

上記の式だと12か月分に対して、月の部分を少しずつ変えた式を作成する必要がありますが、セル範囲に規則性があったり、月を示すタイトルがどこかにあるような場合は、それを利用することで全部の月で同じ関数式にすることも可能です。
などと言っているよりも、事前設定の1回こっきりの作業だと思いますので、個別に設定してしまった方が早いですし、2月以外は日数が固定なのでもっと簡単な式にでき、他の月に関しては、
 = 前のセル+1
という式で、必要な範囲にフィルコピーすれば十分なはずです。

ANo3です。

>この様場合どうすれば自動で2/29が入りますか。
データをシリアル値(=Date型)で持つようにしているなら、うるう年は自動的に2/29日が表示できます。
(前回回答の式の表示調整の仕組みをご覧ください)

それよりも、
>表は一月ごとに区切ってあります。
・・という条件は、ご質問文には記載されていませんでしたので、ANo3で提示した式はA列に一年分がズラ~っと並ぶ前提で作成した式になっています。
(うるう年はきちんと反映されますし、翌年度に当たるセルは空白になる関数式になっていま...続きを読む


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング