質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Q&A

解決済

3回答

3482閲覧

VBA 連想配列がどういうものかわかりません

dacchi2000

総合スコア27

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

0グッド

0クリップ

投稿2016/06/02 08:32

###前提
VBAにて工数管理を作成しています。 前回、連想配列の書き出し方法について質問したのですが、参照先がうまく指定されていなかったのと配列にデータがうまく格納されていなかったので、ソースを書き直しました。
前回質問URL:https://teratail.com/questions/36518
今回の質問内容はそもそも私自身、連想配列を概ね理解できておらず、コードの一部が何を実行しているのかわかりません。
なので、未熟者の私に連想配列と実際に記載しているコードの意味を教えてください。

###内容説明・実現したいこと
一枚目にある画像で記入した項目を登録ボタン押下することで該当する大分類のシート(2枚目画像)に移動して1枚目の画像に表示してある日付(D3)、中分類、領域全てが一致した場所に、掛かった工数入力されるようにしたいと思っています。 (J列は基本表示されないようにしていて、0.5時間刻みにしています)
連想配列を使用して日付以外の項目は配列への読み出しして大分類、中分類、領域が同じものがあれば、工数を加算し、違う項目があれば新規に項目を作成するようにしたいと思っています。
もし大分類、中分類、領域いずれかに空白があれば次の行の検索に飛ぶようしたいです。
大分類は4種類あり、2枚目画像のA4部分(青く塗りつぶされ部分)が大分類になり、中分類はA7〜A24(大分類によって項目数は異なる)、領域はG7〜G24(3項目固定)になります。

###画像
イメージ説明
イメージ説明

###ソースコード

VBA

1Sub record() 2 3 Dim Sheet1, Sheet2, Sheet3, Sheet4, Sheet5 As Worksheet 4 Const COL大分類 = 4 '大分類の列 5 Const COL中分類 = 6 '中分類の列 6 Const COL領域 = 9 '領域の列 7 Const COL工数 = 10 '工数の列 8 Dim MAXRow As Long '最終行 9 Dim Key As String '検索キー 10 Dim c, r, i As Long 11 Dim Today As Date '日付 12 Dim dic As Class1 'Dictionaryオブジェクト呼び出し 13 Dim myVal, myVal2, myVal3 14 15 Set dic = New Class1 '連想配列の定義 16 17 Set Sheet1 = Worksheets("工数入力") 18 Set Sheet5 = Worksheets("月次表(その他)") 19 20 Today = Worksheets("工数入力").Range("D3").Value '登録する日を格納 21 22 MAXRow = Sheet1.Cells(Rows.Count, 4).End(xlUp).Row '最終行を求める 23 24 myVal = Sheet1.Range("D9", Sheet1.Range("D" & Rows.Count).End(xlUp)).Resize(, 4).Value '元データを配列に格納 25 26 27 '各工数の時間を連想配列へ読み込む 28 With Sheet1 29 For r = 9 To MAXRow '最終時間まで 30 Key = .Cells(r, COL大分類).Value & "," & .Cells(r, COL中分類).Value & "," & .Cells(r, COL領域).Value & "," & .Cells(r, COL工数).Value '大分類&中分類&領域&工数 31 Debug.Print (Key) 32 If Not Key = "," Then 33 If Not dic.exists(Key) Then 34 dic.add Key, myVal(r, COL工数) 'ここでエラー発生中 35 Else 36 dic(Key) = dic(Key) + myVal(r, COL工数) 'すでに存在しているkeyの時は工数加算 37 End If 38 End If 39 'dic(Key) = dic(Key) + .Cells(r, COL工数).Value '工数計算 40 Next 41 End With 42 43 44'-----------------各月次表への書き出し----------------- 45 c = Day(Today) + 9 46 47 With Sheet5 'とりあえずその他シートで実験 48 For i = 4 To 19 Step 3 '中項目(項目追加されたら編集) 49 For r = 7 To 24 '領域 50 Key = .Cells(4, 1).Value & .Cells(i, 1).Value & .Cells(r, 7).Value & .Cells(2, c).Value '大分類&中分類&領域&日付 51 If dic.exists(Key) Then 52 .Cells(r, c) = dic(Key) 53 End If 54 Next 55 Next 56 End With 57 58 MsgBox "登録完了しました。" 59 60End Sub 61

###発生している問題・エラーメッセージ

実行時エラー'9' インデックスが有効範囲にありません。 エラー箇所 dic.add Key, myVal(r, COL工数) 'ここでエラー発生中

###デバッグ結果
その他,メール対応,オペレーション,0.5

###補足情報
Mac版オフィスを使用しているので連想配列の定義は以下URLを参考にしています
http://fccreator.blogspot.jp/2014/03/macmacexcelvbadictionary.html

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

質問内容を丁寧に記載されているのは良いのですが、
もう少しデバッグ方法を学んでから質問されてはいかがでしょうか?

ブレークポイント、ローカルウィンドウや、イミディエイトウィンドウ、
ウォッチウィンドウ等を使えるようになることが、
本質的な問題解決への近道かと思われます。

投稿2016/06/05 03:07

ExcelVBAer

総合スコア1175

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dacchi2000

2016/06/06 07:31

連絡が遅くなってしまいすいません。 わかりました。少し勉強してみます。
guest

0

このエラーは、

VB

1myVal = Sheet1.Range("D9", Sheet1.Range("D" & Rows.Count).End(xlUp)).Resize(, 4).Value

で配列サイズを4にリサイズしているのに myVal(r, COL工数)でCOL工数=10でアクセスしているために出ているエラーだと思います。
連想配列でエラーが出ているわけではないです。

VBAの連想配列はここに分かりやすく書いてあります。

投稿2016/06/02 09:31

編集2016/06/02 09:32
PineMatsu

総合スコア3579

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dacchi2000

2016/06/03 02:09

回答ありがとうございます。 申し訳ありませんが、この場合Resizeの値、もしくはCOL工数をどのように変更すればよろしいのでしょうか? Resizeを変更しても、 dic(Key) = dic(Key) + myVal(r, COL工数) 'すでに存在しているkeyの時は工数加算 の部分でエラーが出てしまいます。
PineMatsu

2016/06/03 09:36

Resizeをやめてみてはどうでしょうか?
guest

0

ベストアンサー

わざわざ難しいのを使わず
簡単に作ったほうが初心者には良いかもしれません

デバックは必須ですが

VBA

1列=format("dd",日付の入ってるセル)*1+8 2 for i=9 to 34 3 select case cells(i,"F").value 4 case is="名刺データ作成" 5 行=7 6 case is="企画書作成" 7 行=10 8 ... 9 end select 10 select case cells(i,"I").value 11 case is = "リーダー" 12 行=行+1 13 case is = "オペレーション" 14 行=行+2 15 end select 16 with sheets(2) 17 .cells(行,列).value = .cells(行,列).value + 0.5 18 end with 19 next i

投稿2016/06/06 13:15

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dacchi2000

2016/06/07 01:08

ありがとうございます。 確かにちょっとコード書くのに時間はかかりますがその方がより確実ですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問