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

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

ただいまの
回答率

90.22%

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

解決済

回答 3

投稿

  • 評価
  • クリップ 0
  • VIEW 1,319

dacchi2000

score 25

前提

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

内容説明・実現したいこと

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

画像

イメージ説明
イメージ説明

ソースコード

Sub record()

    Dim Sheet1, Sheet2, Sheet3, Sheet4, Sheet5    As Worksheet
    Const COL大分類 = 4            '大分類の列
    Const COL中分類 = 6            '中分類の列
    Const COL領域 = 9              '領域の列
    Const COL工数 = 10              '工数の列
    Dim MAXRow    As Long         '最終行
    Dim Key       As String       '検索キー
    Dim c, r, i      As Long
    Dim Today     As Date         '日付
    Dim dic    As Class1         'Dictionaryオブジェクト呼び出し
    Dim myVal, myVal2, myVal3

    Set dic = New Class1    '連想配列の定義

    Set Sheet1 = Worksheets("工数入力")
    Set Sheet5 = Worksheets("月次表(その他)")

    Today = Worksheets("工数入力").Range("D3").Value    '登録する日を格納

    MAXRow = Sheet1.Cells(Rows.Count, 4).End(xlUp).Row    '最終行を求める

    myVal = Sheet1.Range("D9", Sheet1.Range("D" & Rows.Count).End(xlUp)).Resize(, 4).Value   '元データを配列に格納


    '各工数の時間を連想配列へ読み込む
    With Sheet1
        For r = 9 To MAXRow    '最終時間まで
            Key = .Cells(r, COL大分類).Value & "," & .Cells(r, COL中分類).Value & "," & .Cells(r, COL領域).Value & "," & .Cells(r, COL工数).Value   '大分類&中分類&領域&工数
            Debug.Print (Key)
                If Not Key = "," Then
                    If Not dic.exists(Key) Then
                        dic.add Key, myVal(r, COL工数)    'ここでエラー発生中
                    Else
                        dic(Key) = dic(Key) + myVal(r, COL工数)    'すでに存在しているkeyの時は工数加算
                    End If
                End If
            'dic(Key) = dic(Key) + .Cells(r, COL工数).Value   '工数計算
        Next
    End With


'-----------------各月次表への書き出し-----------------
    c = Day(Today) + 9

    With Sheet5                'とりあえずその他シートで実験
        For i = 4 To 19 Step 3    '中項目(項目追加されたら編集)
        For r = 7 To 24        '領域
            Key = .Cells(4, 1).Value & .Cells(i, 1).Value & .Cells(r, 7).Value & .Cells(2, c).Value        '大分類&中分類&領域&日付
            If dic.exists(Key) Then
                .Cells(r, c) = dic(Key)
            End If
        Next
        Next
    End With

    MsgBox "登録完了しました。"

End Sub

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

実行時エラー'9'
インデックスが有効範囲にありません。

エラー箇所
dic.add Key, myVal(r, COL工数)    'ここでエラー発生中

デバッグ結果

その他,メール対応,オペレーション,0.5

補足情報

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

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

+2

このエラーは、

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


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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/03 11:09

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

    キャンセル

  • 2016/06/03 18:36

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

    キャンセル

+2

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/06 16:31

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

    キャンセル

checkベストアンサー

+1

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

デバックは必須ですが

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/06/07 10:08

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

    キャンセル

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

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る