Excel VBA質問箱 IV

当質問箱は、有志のボランティア精神のおかげで成り立っています。
問題が解決したら、必ずお礼をしましょうね。
本サイトの基本方針をまとめました。こちら をご一読ください。

投稿種別の選択が必要です。ご注意ください。
迷惑投稿防止のため、URLの入力を制限しています。ご了承ください。


3810 / 13646 ツリー ←次へ | 前へ→

【59849】年間月別合計の出し方 ひかる 09/1/13(火) 20:39 質問[未読]
【59850】Re:年間月別合計の出し方 kanabun 09/1/13(火) 21:18 発言[未読]
【59855】Re:年間月別合計の出し方 ひかる 09/1/13(火) 22:47 質問[未読]
【59856】Re:年間月別合計の出し方 kanabun 09/1/14(水) 0:09 発言[未読]
【59857】Re:年間月別合計の出し方 kanabun 09/1/14(水) 0:15 発言[未読]
【59858】Re:年間月別合計の出し方 ひかる 09/1/14(水) 7:07 お礼[未読]
【59859】Re:年間月別合計の出し方 kanabun 09/1/14(水) 9:33 発言[未読]
【59886】Re:年間月別合計の出し方 ひかる 09/1/15(木) 16:07 質問[未読]
【59887】Re:年間月別合計の出し方 ひかる 09/1/15(木) 16:21 お礼[未読]
【59892】Re:年間月別合計の出し方 kanabun 09/1/15(木) 16:51 発言[未読]
【59949】Re:年間月別合計の出し方 ひかる 09/1/20(火) 18:29 質問[未読]
【59950】Re:年間月別合計の出し方 kanabun 09/1/20(火) 20:25 発言[未読]
【59954】Re:年間月別合計の出し方 ひかる 09/1/20(火) 21:35 質問[未読]
【59955】Re:年間月別合計の出し方 kanabun 09/1/20(火) 21:49 発言[未読]
【59956】Re:年間月別合計の出し方 ひかる 09/1/20(火) 22:09 質問[未読]
【59957】Re:年間月別合計の出し方 kanabun 09/1/20(火) 22:50 発言[未読]
【59958】Re:年間月別合計の出し方 kanabun 09/1/20(火) 23:04 発言[未読]
【59959】Re:年間月別合計の出し方 kanabun 09/1/20(火) 23:31 発言[未読]
【59960】Re:年間月別合計の出し方 ひかる 09/1/20(火) 23:42 お礼[未読]
【59981】Re:年間月別合計の出し方 ひかる 09/1/22(木) 12:02 お礼[未読]
【59983】Re:年間月別合計の出し方 ひかる 09/1/22(木) 12:52 質問[未読]
【59988】Re:年間月別合計の出し方 ひかる 09/1/22(木) 18:07 質問[未読]
【60025】Re:年間月別合計の出し方 kanabun 09/1/24(土) 10:35 発言[未読]
【60026】Re:年間月別合計の出し方 kanabun 09/1/24(土) 10:40 発言[未読]
【60036】Re:年間月別合計の出し方 ひかる 09/1/24(土) 19:18 お礼[未読]
【60054】Re:年間月別合計の出し方 ひかる 09/1/26(月) 11:50 質問[未読]
【60061】Re:年間月別合計の出し方 kanabun 09/1/26(月) 14:39 発言[未読]
【60097】Re:年間月別合計の出し方 ひかる 09/1/27(火) 12:42 お礼[未読]
【60105】Re:年間月別合計の出し方 kanabun 09/1/27(火) 15:56 発言[未読]
【60106】Re:年間月別合計の出し方 ひかる 09/1/27(火) 16:27 お礼[未読]
【59889】Re:年間月別合計の出し方 kanabun 09/1/15(木) 16:48 発言[未読]

【59849】年間月別合計の出し方
質問  ひかる  - 09/1/13(火) 20:39 -

引用なし
パスワード
   はじめて投稿させていただきます。ExcelVBA初心者です。よろしくお願いします。
はじめに、データが次のようにあります。
      会議室  研修室  和室  調理室  単位(円)
04月15日   560   800   1000   500
04月19日   1500   600   5200   1500
05月21日   800   2000   800    2100
05月31日   5000   480   2500   600
06月13日   4500   3600   4800   1600
06月18日   100   3600   8400   2650
06月21日   7000   600   8000   7900

このデータを使って、次のように集計月別の年間集計するには、どうしたらよいのかわかる方がいらっしゃいましたらお教えください。よろしくお願いします。
      4月 5月 6月 7月 8月 9月 10月 11月 12月 1月 2月 3月
会議室   2060 5800 11600
研修室   1400 2480 7800
和室    6200 3300 21200
調理室   2000 2700 12150

【59850】Re:年間月別合計の出し方
発言  kanabun  - 09/1/13(火) 21:18 -

引用なし
パスワード
   ▼ひかる さん:

こんにちは。
VBA初心者ということなので、手始めに一般機能の「統合」を
使ってみてはいかがですか?

まず、元表に細工を施します。
B列を挿入して、挿入列に =MONTH(A2) と数式を入れます。↓
 A    B    C    D    E    F
----------------------------------------------
日付    月    会議室    研修室    和室    調理室
4月15日    4月    560    800    1000    500
4月19日    4月    1500    600    5200    1500
5月21日    5月    800    2000    800    2100
5月31日    5月    5000    480    2500    600
6月13日    6月    4500    3600    4800    1600
6月18日    6月    100    3600    8400    2650
6月21日    6月    7000    600    8000    7900

統合後の表を出力したいセルをアクティブにしておいて、
メニュ-[データ]-[統合...]から
統合元範囲に [B1:F8]を指定します(A列は含みません)
統合の基準
  上端行
  左端列  の両方にチェックを入れ、 [OK]ボタンを押すと、
次のような統合表が出来上がります。

----------------------------------------------
    会議室    研修室    和室    調理室
4    2060    1400    6200    2000
5    5800    2480    3300    2700
6    11600    7800    21200    12150

あとは、この範囲をCUT して、別シートに
行列を入れ替えて貼り付けるだけです。
------------------------------------------
    4    5    6
会議室    2060    5800    11600
研修室    1400    2480    7800
和室    6200    3300    21200
調理室    2000    2700    12150

( 月の書式 4 → 4月 などは 適宜設定してください)

VBAでこれを半自動でやらせることもできます。
そのばあい、以上の操作をマクロ記録してみてください。

【59855】Re:年間月別合計の出し方
質問  ひかる  - 09/1/13(火) 22:47 -

引用なし
パスワード
   ▼kanabun さん:
はじめまして。さっそくのご返信ありがとうございます。
試しに統合の機能を使ってやってみました。ありがとうございました。
今度は、もう少し突っ込んでやってみたいのですが、別シートに次の表が用意してあり、先ほど記述したデータから、マクロ実行後、データを記述するには、VBAコードでは、どうすればよいでしょうか。
   A    B    C    D
1      4月      5月      6月
2 会議室    
3 研修室     
4 和室    
5 調理室    
    
さらに、最終行に合計をいれるとするとどうなるでしょうか。お手数ですがお教えいただけないでしょうか。よろしくお願いします。
   A    B    C    D
1      4月      5月      6月
2 会議室    
3 研修室     
4 和室    
5 調理室    
  合計

【59856】Re:年間月別合計の出し方
発言  kanabun  - 09/1/14(水) 0:09 -

引用なし
パスワード
   ▼ひかる さん:

>今度は、もう少し突っ込んでやってみたいのですが、別シートに次の表が用意してあり、先ほど記述したデータから、マクロ実行後、データを記述するには、VBAコードでは、どうすればよいでしょうか。
>   A    B    C    D
>1      4月      5月      6月
>2 会議室    
>3 研修室     
>4 和室    
>5 調理室    

こんなの↓ [F8]でステップ実行して確かめてください。
元の表は Sheet1 にあり、集計表は Sheet2 にあるものと仮定しています。

'--------------------------------- 標準モジュール
Option Explicit

'dictionary編

Sub Try1()
  Dim dic As Object
  Dim r As Range, c As Range
  Dim tbl
  Dim i As Long
  
  '---- 書き出し先のテーブル情報をDictionaryに格納 -----
  Set dic = CreateObject("Scripting.Dictionary")
  With Worksheets("Sheet2")
    Set r = .Range("A1").CurrentRegion '書きこみ先表範囲
  End With
  Set r = Intersect(r, r.Offset(1, 1)) 'そのうち、正味データ部
  r.ClearContents  '行列見出しを除く正味データ部をクリア
  tbl = r.Value   'クリア後の範囲を配列に格納
  
  '行列見出し位置を辞書に格納
  For Each c In r.Resize(, 1).Offset(, -1) 'A列見出し項目(室)
    i = i + 1
    dic(c.Text) = i
  Next
  i = 0
  For Each c In r.Resize(1).Offset(-1) '1行目見出し項目(月)
    i = i + 1
    dic(c.Text) = i
  Next
  
  '---- 元表のA列×1行目の見出しに対応する 書きこみ先の _
    配列tblの 行列番号を Dictionaryから得る  -----
  Dim rr As Range
  Dim MonData, RoomData, dat, ss As String
  Dim j As Long, n As Long, m As Long

  Set rr = Worksheets("Sheet1").Range("A1").CurrentRegion.Resize(, 5)
  Set rr = Intersect(rr, rr.Offset(1, 1))
  MonData = rr.Resize(, 1).Offset(, -1).Value
  RoomData = rr.Resize(1).Offset(-1).Value
  For i = 1 To UBound(MonData, 1)
    dat = MonData(i, 1)
    If IsDate(dat) Then
      ss = Month(dat) & "月"
      If dic.Exists(ss) Then
        m = dic(ss) '何列目か
        For j = 1 To UBound(RoomData, 2)
          ss = RoomData(1, j)
          If dic.Exists(ss) Then
            n = dic(ss) '何行目か
            '------tblのn行,m列目の要素に 数量を累加 -----
            tbl(n, m) = tbl(n, m) + rr(i, j).Value
          End If
        Next
      End If
    End If
  Next
  
  '---- 配列に集計した結果を表に書き出す ------
  r.Value = tbl

End Sub

>さらに、最終行に合計をいれるとするとどうなるでしょうか。
それは ご自分で表の下に =SUM式 を入れる操作をマクロ記録すれば
得られます。

【59857】Re:年間月別合計の出し方
発言  kanabun  - 09/1/14(水) 0:15 -

引用なし
パスワード
   補足です。
マクロ Try1() が使う元データ表は
B列に 「月名」を挿入しない前の 当初のもの↓ です。

>       会議室  研修室  和室  調理室  単位(円)
> 04月15日   560   800   1000   500
> 04月19日   1500   600   5200   1500
> 05月21日   800   2000   800    2100
> 05月31日   5000   480   2500   600
> 06月13日   4500   3600   4800   1600
> 06月18日   100   3600   8400   2650
> 06月21日   7000   600   8000   7900

月名は コードを読めば分かりますが、マクロ内で A列日付を
Month関数で 月名に直して、位置を関連付けています。

【59858】Re:年間月別合計の出し方
お礼  ひかる  - 09/1/14(水) 7:07 -

引用なし
パスワード
   ▼kanabun さん:
早いご回答ありがとうございます。
今から、このコードを解読してやってみます。分からなければ、また質問させていただきますが、何卒よろしくお願いします。
ありがとうございました。

【59859】Re:年間月別合計の出し方
発言  kanabun  - 09/1/14(水) 9:33 -

引用なし
パスワード
   ▼ひかる さん:

>▼kanabun さん:
>早いご回答ありがとうございます。
>今から、このコードを解読してやってみます。

大変良い心がけです。
ただ、漫然と「解読」しようとしても効率が悪いので、
2、3点、こんな風にしてデバッグするとよい方法を紹介します。

(1)ExcelシートとVBAコードの両方をスクリーン(display)に見えるように
  画面を配置してコードを一行づつStep実行しながら、ワークシートの
  変化を確認する(今回は まず 集計表のあるワークシートSheet2を
  対象に処理しますから、Sheet2をExcel画面にして、Sub Try1()コード
  の一部が同じ画面上に見えるようにして検証を始めるとよいでしょう)
(2)コードは[F5]で一気に実行するのではなく、[F8]キーで1行づつステッ
  プ実行する。
  ステップ実行については
  ht tp://hp.vector.co.jp/authors/VA016119/step/step01.html
  あたりをよく読んで、実践してください。
(3)変数の値変化やシートの範囲を確認するために、VBAコードにDebug用の
  コードを一時的に挿入する。
  たとえば...
>  With Worksheets("Sheet2")
>    Set r = .Range("A1").CurrentRegion '書きこみ先表範囲
>  End With
>  Set r = Intersect(r, r.Offset(1, 1)) 'そのうち、正味データ部
>  r.ClearContents  '行列見出しを除く正味データ部をクリア
>  tbl = r.Value   'クリア後の範囲を配列に格納
という出だしのコード部分で、Sheet2 から 表範囲を取得し変数 r に代入
していますが、この範囲を確認するには
 あらかじめ Sheet2 をアクティブにしておいて、
>    Set r = .Range("A1").CurrentRegion '書きこみ先表範囲
 のあとに、
   r.select
   Msgbox r.Address(0,0) & vbCr & "全体表範囲です"
などとして、範囲を確認するといいでしょう。
さらに、変数r はその直後 行と列見出し部分を取り除いた正味データ
範囲だけに絞り込まれます。↓
ここも、
>  Set r = Intersect(r, r.Offset(1, 1)) 'そのうち、正味データ部
   r.select
   Msgbox r.Address(0,0) & vbCr & "正味書き込み範囲です"
としておくと、判りやすいでしょう。(もちろん、処理の内容が分かっ
たら、消去してください。セルをSelectするのは 実際の処理には必要
ないことなので)
そのあと、
>  r.ClearContents  '行列見出しを除く正味データ部をクリア
>  tbl = r.Value   'クリア後の範囲を配列に格納
によって、範囲のデータ(すべてEmptyのはず)が 変数tblに代入され
ます。変数tbl は複数セル範囲の値ですから、配列 です。
この値が現在どうなっているかは
VBAメニュ-[表示]-[ローカルウィンドウ]を覗いて確かめてください。

【59886】Re:年間月別合計の出し方
質問  ひかる  - 09/1/15(木) 16:07 -

引用なし
パスワード
   ▼kanabun さん:
返事が遅くなりすみません。
貴重なご意見をありがとうございました。
さっそくコードを入力してやってみたのですが、
次の矢印を入れているところで、実行時エラー91”オブジェクト変数またはwithブロック変数が設定されていません”と出るのですが、解決方法をお教えください。よろしくお願いします。

Dim rr As Range
  Dim MonData, RoomData, dat, ss As String
  Dim j As Long, n As Long, m As Long

  Set rr = Worksheets("Sheet1").Range("A1").CurrentRegion.Resize(, 5)
  Set rr = Intersect(rr, rr.Offset(1, 1))
⇒ MonData = rr.Resize(, 1).Offset(, -1).Value
  RoomData = rr.Resize(1).Offset(-1).Value
  For i = 1 To UBound(MonData, 1)
    dat = MonData(i, 1)
    If IsDate(dat) Then
      ss = Month(dat) & "月"
      If dic.Exists(ss) Then
        m = dic(ss) '何列目か
        For j = 1 To UBound(RoomData, 2)
          ss = RoomData(1, j)
          If dic.Exists(ss) Then
            n = dic(ss) '何行目か
            '------tblのn行,m列目の要素に 数量を累加 -----
            tbl(n, m) = tbl(n, m) + rr(i, j).Value
          End If
        Next
      End If
    End If
  Next
  
  '---- 配列に集計した結果を表に書き出す ------
  r.Value = tbl

【59887】Re:年間月別合計の出し方
お礼  ひかる  - 09/1/15(木) 16:21 -

引用なし
パスワード
   >▼kanabun さん:
たびたびすみません。私がsheet1のデータを入力する位置がちがっておりました。
申し訳ございませんでした。
なんとか、できました。ありがとうございました。
Excel VBA がこんなにも奥の深い難しい、しかし使えればとても便利なこのVBAをもっとしりたくなりました。kanabunさんのおかげです。これから、もっと勉強して少しでもたくさん使えるようになりたいと思います。また、困ったことで質問させていただきますが、何卒よろしくお願いします。
ありがとうございました。

【59889】Re:年間月別合計の出し方
発言  kanabun  - 09/1/15(木) 16:48 -

引用なし
パスワード
   ▼ひかる さん:
>▼kanabun さん:
>返事が遅くなりすみません。
>貴重なご意見をありがとうございました。
>さっそくコードを入力してやってみたのですが、
>次の矢印を入れているところで、実行時エラー91”オブジェクト変数またはwithブロック変数が設定されていません”と出るのですが、解決方法をお教えください。

そのまえの
>  Set rr = Worksheets("Sheet1").Range("A1").CurrentRegion
が、うまく動いているか確認してみてください。

手動で、
Sheet1 の[A1]をアクティブにして Ctrl+Shift+[*]を実行してみてください。
どの範囲が選択されますか?
想定した元表の範囲が選択されましたか?

あるいは コードにデバッグ行を挿入して 確認してください。
>
>  Dim rr As Range
>  Dim MonData, RoomData, dat, ss As String
>  Dim j As Long, n As Long, m As Long
>

>  Set rr = Worksheets("Sheet1").Range("A1").CurrentRegion.Resize(, 5)
'↑ この行を ↓のように 変更
  With Worksheets("Sheet1")
    .Activate      '◆デバッグ用追加
    Set rr = .Range("A1").CurrentRegion.Resize(, 5)
    rr.Select      '←↓◆◆デバッグ用追加
    If MsgBox("この範囲が元データ範囲ですか? " & _
      rr.Address(0, 0), vbOKCancel) = vbCancel Then Exit Sub
  End With

>  Set rr = Intersect(rr, rr.Offset(1, 1))
  
  'ここに↓ 追加
   If rr is Nothing then
     msgbox "範囲が不正です データ範囲が取得できません"
     exit sub
   End If
   rr.Select      '←↓◆◆デバッグ用追加
   If MsgBox("この範囲が正味データ範囲ですか? " & _
      rr.Address(0, 0), vbOKCancel) = vbCancel Then Exit Sub

>⇒ MonData = rr.Resize(, 1).Offset(, -1).Value
>  RoomData = rr.Resize(1).Offset(-1).Value
>  For i = 1 To UBound(MonData, 1)
>    dat = MonData(i, 1)
>    If IsDate(dat) Then
>      ss = Month(dat) & "月"
>      If dic.Exists(ss) Then
>        m = dic(ss) '何列目か
>        For j = 1 To UBound(RoomData, 2)
>          ss = RoomData(1, j)
>          If dic.Exists(ss) Then
>            n = dic(ss) '何行目か
>            '------tblのn行,m列目の要素に 数量を累加 -----
>            tbl(n, m) = tbl(n, m) + rr(i, j).Value
>          End If
>        Next
>      End If
>    End If
>  Next
>  
>  '---- 配列に集計した結果を表に書き出す ------
>  r.Value = tbl

【59892】Re:年間月別合計の出し方
発言  kanabun  - 09/1/15(木) 16:51 -

引用なし
パスワード
   ▼ひかる さん:
>>▼kanabun さん:
>たびたびすみません。私がsheet1のデータを入力する位置がちがっておりました。
>申し訳ございませんでした。
>なんとか、できました。ありがとうございました。
>Excel VBA がこんなにも奥の深い難しい、しかし使えればとても便利なこのVBAをもっとしりたくなりました。kanabunさんのおかげです。これから、もっと勉強して少しでもたくさん使えるようになりたいと思います。また、困ったことで質問させていただきますが、何卒よろしくお願いします。
>ありがとうございました。

すみません。ぽちぽち書いていたら、原因が分かったようですね
上でレスしたデバッグ法は 他でも使えると思いますので、
参考にしてください。

ではでは(^^

【59949】Re:年間月別合計の出し方
質問  ひかる  - 09/1/20(火) 18:29 -

引用なし
パスワード
   ▼kanabun さん:
お久しぶりです。また、年間月別でお教えください。
以前のデータから、今度は、室の利用者が、大人か小人かの項目が増えた場合、どういったVBAコードで下の表が埋めれますか。お教えください。

以前のデータに利用者がプラス
    A     B     C      D     E      F
-----------------------------------------------------------------------
1  日付    利用者  会議室   研修室   和室   調理室
2  4月15日   大人    560    800    1000    500
3  4月19日   小人    1500    600    5200    1500
4  5月21日   大人    800    2000    800    2100
5  5月31日   小人    5000    480    2500    600
6  6月13日   小人    4500    3600    4800    1600
7  6月18日   大人    100    3600    8400    2650
8  6月21日   大人    7000    600    8000    7900

マクロ実行後

集計表
   A    B      C    D    E
1             4月   5月   6月
2 会議室   大人 
3       小人
4 研修室   大人  
5       小人
6 和室    大人
7       小人 
8 調理室   大人
9       小人

【59950】Re:年間月別合計の出し方
発言  kanabun  - 09/1/20(火) 20:25 -

引用なし
パスワード
   ▼ひかる さん:

>以前のデータから、今度は、室の利用者が、大人か小人かの項目が増えた場合、どういったVBAコードで下の表が埋めれますか。お教えください。
>
>以前のデータに利用者がプラス
>    A     B     C      D     E      F
>-----------------------------------------------------------------------
>1  日付    利用者  会議室   研修室   和室   調理室
>2  4月15日   大人    560    800    1000    500
>3  4月19日   小人    1500    600    5200    1500
>4  5月21日   大人    800    2000    800    2100
>5  5月31日   小人    5000    480    2500    600
>6  6月13日   小人    4500    3600    4800    1600
>7  6月18日   大人    100    3600    8400    2650
>8  6月21日   大人    7000    600    8000    7900

というデータがあるとき、
集計先のA,B列見出しをまとめて「会議室大人」という見出しの【行】
の「4月」の【列】 に。。。と行列をまとめて
集計していけば、

        4月    5月    6月    7月
会議室    大人    560    800    7100    
会議室    小人    1500    5000    4500    
研修室    大人    800    2000    4200    
研修室    小人    600    480    3600    
和室    大人    1000    800    16400    
和室    小人    5200    2500    4800    
調理室    大人    500    2100    10550    
調理室    小人    1500    600    1600    

Sub Try1()と同じ考えでできます。


シート名は 元表のあるシートが"◆Sheet1"
集計先が "◆Sheet2" として記述してますので、そちらの環境に合わせて
ください。
コードは デバッグ用に シートを選択したり、範囲をMsgBoxで確認したり
していますので、デバッグが終わったら、コメントアウト(コメント化)して
ください。

Sub Try2()
  Dim dic As Object
  Dim r As Range, c As Range
  Dim tbl
  Dim i As Long
  Dim strRoom As String '◆追加
  
  '---- 書き出し先のテーブル情報をDictionaryに格納 -----
  Set dic = CreateObject("Scripting.Dictionary")
  With Worksheets("◆Sheet2")
    .Activate
    Set r = .Range("A1").CurrentRegion '書きこみ先表範囲
    r.Select
    MsgBox "この範囲が表全体"
  End With
  Set r = Intersect(r, r.Offset(1, 2)) 'そのうち、正味データ部 ◆変更
    r.Select
    MsgBox "この範囲が正味データ範囲"
  
  r.ClearContents  '行列見出しを除く正味データ部をクリア
  tbl = r.Value   'クリア後の範囲を配列に格納
  
  '行列見出し位置を辞書に格納
  For Each c In r.Resize(, 1).Offset(, -1) 'A+B列見出し項目(室+大小)
    i = i + 1
    If Len(c(1, 0).Text) Then strRoom = c(1, 0).Text
    dic(strRoom & c.Text) = i
  Next
  i = 0
  For Each c In r.Resize(1).Offset(-1) '1行目見出し項目(月)
    i = i + 1
    dic(c.Text) = i
  Next
  
  '---- 元表のA列×1行目の見出しに対応する 書きこみ先の _
    配列tblの 行列番号を Dictionaryから得る  -----
  Dim rr As Range
  Dim MonData, RoomData, dat, ss As String, ACdata '「大人/小人」配列を追加
  Dim j As Long, n As Long, m As Long
  With Worksheets("◆Sheet1")
    .Activate      '◆デバッグ用追加
    Set rr = .Range("A1").CurrentRegion '.Resize(, 5)
    rr.Select      '←↓◆◆デバッグ用追加
    If MsgBox("この範囲が元データ範囲 " & _
      rr.Address(0, 0), vbOKCancel) = vbCancel Then Exit Sub
  End With
  Set rr = Intersect(rr, rr.Offset(1, 2)) '◆列方向 C列から 「室」見出し
  rr.Select        '←↓◆◆デバッグ用追加
  MsgBox "この範囲が正味数値データ範囲 " & rr.Address(0, 0)
  MonData = rr.Offset(, -2).Resize(, 1).Value
  ACdata = rr.Offset(, -1).Resize(, 1).Value
  RoomData = rr.Resize(1).Offset(-1).Value
  For i = 1 To UBound(MonData, 1) '日付のレコード順に
    dat = MonData(i, 1)
    If IsDate(dat) Then
      ss = Month(dat) & "月"
      If dic.Exists(ss) Then
        m = dic(ss) '何列目か
        For j = 1 To UBound(RoomData, 2)
          ss = RoomData(1, j) & ACdata(i, 1)
          If dic.Exists(ss) Then
            n = dic(ss) '何行目か
            '------tblのn行,m列目の要素に 数量を累加 -----
            tbl(n, m) = tbl(n, m) + rr(i, j).Value
          End If
        Next
      End If
    End If
  Next
  
  '---- 配列に集計した結果を表に書き出す ------
  r.Value = tbl
  Worksheets("◆Sheet2").Activate
End Sub

【59954】Re:年間月別合計の出し方
質問  ひかる  - 09/1/20(火) 21:35 -

引用なし
パスワード
   ▼kanabun さん:
お返事ありがとうございます。
ご回答いただきましたが、できれば、A列とB列は分けたいのです。といいますのも、先ほどは、大人、小人としかいいませんでしたが、そのほかに、男か女かの集計もしたいのです。したのようなデータ(sheet1)です。
>>    A   B   C    D      E     F      G
>>-----------------------------------------------------------------------
>>1  日付  利用者 性別  会議室   研修室   和室   調理室
>>2  4月15日 大人   男   560    800    1000    500
>>3  4月19日 小人   女   1500    600    5200    1500
>>4  5月21日 大人   女   800    2000    800    2100
>>5  5月31日 小人   女   5000    480    2500    600
>>6  6月13日 小人   男   4500    3600    4800    1600
>>7  6月18日 大人   女   100    3600    8400    2650
>>8  6月21日 大人   男   7000    600    8000    7900

これを、sheet2

   A    B    C     D     E     F
           4月    5月    6月    7月
1 会議室  大人  
2 会議室  小人      
3 研修室  大人       
4 研修室  小人      
5 和室   大人  
6 和室   小人  
7 調理室  大人  
8 調理室  小人  

sheet3

   A    B    C     D     E     F
           4月    5月    6月    7月
1 会議室  男  
2 会議室  女  
3 研修室  男  
4 研修室  女  
5 和室   男  
6 和室   女       
7 調理室  男  
8 調理室  女

に集計したいのです。いいかえれば、使い回しをしたいのです。
また、これは、これとは、別のことなのですが、日付を今の記述では、4月15日というふうにかいていますが、これを2008年4月15日のように記入していき、集計で2008年の4月、2009年の4月と分けて、集計することもできますか。2008年と2009年のデータは、できればシートを分けて集計したいです。
                           
>sheet4(仮)                       2008年
   A    B    C     D     E     F
           4月    5月    6月    7月
1 会議室  大人  
2 会議室  小人      
3 研修室  大人       
4 研修室  小人      
5 和室   大人  
6 和室   小人  
7 調理室  大人  
8 調理室  小人      

>sheet5(仮)                       2009年
   A    B    C     D     E     F
           4月    5月    6月    7月
1 会議室  大人  
2 会議室  小人      
3 研修室  大人       
4 研修室  小人      
5 和室   大人  
6 和室   小人  
7 調理室  大人  
8 調理室  小人

という具合です。
以上の点、お手数をお掛けしますが、なにとぞよろしくお願いします。

【59955】Re:年間月別合計の出し方
発言  kanabun  - 09/1/20(火) 21:49 -

引用なし
パスワード
   ▼ひかる さん:
>ご回答いただきましたが、できれば、A列とB列は分けたいのです。
といいますのも、先ほどは、大人、小人としかいいませんでしたが、そのほかに、男か女かの集計もしたいのです。したのようなデータ(sheet1)です。
>>>    A   B   C    D      E     F      G
>>>-----------------------------------------------------------------------
>>>1  日付  利用者 性別  会議室   研修室   和室   調理室
>>>2  4月15日 大人   男   560    800    1000    500
>>>3  4月19日 小人   女   1500    600    5200    1500
>>>4  5月21日 大人   女   800    2000    800    2100
>>>5  5月31日 小人   女   5000    480    2500    600
>>>6  6月13日 小人   男   4500    3600    4800    1600
>>>7  6月18日 大人   女   100    3600    8400    2650
>>>8  6月21日 大人   男   7000    600    8000    7900

元表に B列「利用者」 以外に もう1列「性別」があるというわけですね?
でも、同じことですよ

>  Set rr = Intersect(rr, rr.Offset(1, 2)) '◆列方向 C列から 「室」見出し

>  MonData = rr.Offset(, -2).Resize(, 1).Value '日付データ
>  ACdata = rr.Offset(, -1).Resize(, 1).Value  '利用者(大人/小人)データ

あたりを修正してください。

【59956】Re:年間月別合計の出し方
質問  ひかる  - 09/1/20(火) 22:09 -

引用なし
パスワード
   ▼kanabun さん:
失礼しました。大人/小人と男/女を入れ替えればよかっただけですね。すみませんでした。ありがとうございます。
あと1点ご質問させていただいた日付の点のほうもよろしくお願いします。

【59957】Re:年間月別合計の出し方
発言  kanabun  - 09/1/20(火) 22:50 -

引用なし
パスワード
   ▼ひかる さん:
>▼kanabun さん:
>失礼しました。大人/小人と男/女を入れ替えればよかっただけですね。

いいえ、(集計先シートのレイアウトは 同じですが、)
元表が 日付列と 利用者列と 性別列 の合計 3列の種別になるんでしょ?
この元表を使いまわしたいのでしょ?

Sub Try3() '集計先のシートをアクティブにして実行
  Dim WS1 As Worksheet
  Dim WS2 As Worksheet
  Dim dic As Object
  Dim r As Range, c As Range
  Dim tbl
  Dim i As Long
  Dim strRoom As String '◆追加
  Dim strSecond As String '◆追加
  
  '---- 書き出し先のテーブル情報をDictionaryに格納 -----
  Set dic = CreateObject("Scripting.Dictionary")
  Set WS1 = Worksheets("◆Sheet1")
  Set WS2 = ActiveSheet
  With WS2
    Set r = .Range("A1").CurrentRegion '書きこみ先表範囲
    r.Select
    MsgBox "この範囲が表全体"
  End With
  Set r = Intersect(r, r.Offset(1, 2)) 'そのうち、正味データ部 ◆変更
    r.Select
    MsgBox "この範囲が正味データ範囲"
  
  r.ClearContents  '行列見出しを除く正味データ部をクリア
  tbl = r.Value   'クリア後の範囲を配列に格納
  
  '行列見出し位置を辞書に格納
  For Each c In r.Resize(, 1).Offset(, -1) 'A+B列見出し項目(室+大小)
    i = i + 1
    If Len(c(1, 0).Text) Then strRoom = c(1, 0).Text
    dic(strRoom & c.Text) = i
  Next
  i = 0
  For Each c In r.Resize(1).Offset(-1) '1行目見出し項目(月)
    i = i + 1
    dic(c.Text) = i
  Next
  strSecond = WS2.[B2].Value '第2 項目(見出し)のサンプル
  
  '---- 元表のA列×1行目の見出しに対応する 書きこみ先の _
    配列tblの 行列番号を Dictionaryから得る  -----
  Dim rr As Range
  Dim MonData, RoomData, dat, ss As String
  Dim SecondData 'B列またはC列格納用変数
  Dim j As Long, n As Long, m As Long, x As Long
  With WS1
    .Activate      '◆デバッグ用追加
    Set rr = .Range("A1").CurrentRegion '.Resize(, 5)
    rr.Select      '←↓◆◆デバッグ用追加
    If MsgBox("この範囲が元データ範囲 " & _
      rr.Address(0, 0), vbOKCancel) = vbCancel Then Exit Sub
  End With
  
  Set rr = Intersect(rr, rr.Offset(1, 3)) '◆列方向 D列から 「室」見出し
  rr.Select        '←↓◆◆デバッグ用追加
  MsgBox "この範囲が正味数値データ範囲 " & rr.Address(0, 0)
  MonData = rr.Offset(, -3).Resize(, 1).Value
  Set c = rr.Offset(, -2).Resize(, 2)
  Set c = c.Find(strSecond, , xlValues, xlWhole)
  If c Is Nothing Then
    MsgBox "第2項目の列取得に失敗しました" & vbCr _
       & " 元データシートの B,C列に <" & strSecond & _
       "> が見つかりませんでした"
    Exit Sub
  End If
  Select Case c.Column 'どの列(B列/C列)で集計するのか 調べる
   Case 2: x = -2
   Case 3: x = -1
  End Select
  SecondData = rr.Offset(, x).Resize(, 1).Value
  RoomData = rr.Resize(1).Offset(-1).Value
  For i = 1 To UBound(MonData, 1) '日付のレコード順に
    dat = MonData(i, 1)
    If IsDate(dat) Then
      ss = Month(dat) & "月"
      If dic.Exists(ss) Then
        m = dic(ss) '何列目か
        For j = 1 To UBound(RoomData, 2)
          ss = RoomData(1, j) & SecondData(i, 1)
          If dic.Exists(ss) Then
            n = dic(ss) '何行目か
            '------tblのn行,m列目の要素に 数量を累加 -----
            tbl(n, m) = tbl(n, m) + rr(i, j).Value
          End If
        Next
      End If
    End If
  Next
  
  '---- 配列に集計した結果を表に書き出す ------
  r.Value = tbl
  WS2.Activate
End Sub


>あと1点ご質問させていただいた日付の点のほうもよろしくお願いします。

すみません。ちょっと時間がなくなったので、
どなたか 考えてあげてください。
(出張のため、しばらくレスできません)

【59958】Re:年間月別合計の出し方
発言  kanabun  - 09/1/20(火) 23:04 -

引用なし
パスワード
   ▼ひかる さん:
>あと1点ご質問させていただいた日付の点のほうもよろしくお願いします。

集計先の 1行目の「月」の見出しは
1行目見出し範囲の表示形式を 「m"月"」としておいて、
たとえば、2008/5月からなら、
[C1]に 2008/4/1
[D1]に 2008/5/1
として、[C1:D1]を選択して フィルハンドルを右方向までドラッグして
いけば、日付データで表示が「n月」の見出しが作れます。

たぶん、文字列で「4月」とするよりも、年度の情報も含んだ
日付データとして見出しを作っておくと、元表から抽出するときに
便利かと思います。

では、では

【59959】Re:年間月別合計の出し方
発言  kanabun  - 09/1/20(火) 23:31 -

引用なし
パスワード
   ▼ひかる さん:

習慣のため、寝付けないので、ちょっと年号情報を加味してみました。
集計元の A列データは 2008/4/15 のような値が入っていて、
(表示形式 m"月"d"日" )
集計先の 1行目には 2008/4 〜 2009/3 のような日付データが
(表示形式 「m"月"」で 入力されているものとします)

Sub Try4() '集計先のシートをアクティブにして実行
  Dim WS1 As Worksheet
  Dim WS2 As Worksheet
  Dim dic As Object
  Dim r As Range, c As Range
  Dim tbl
  Dim i As Long, ss As String
  Dim strRoom As String
  Dim strSecond As String
  
  Set WS1 = Worksheets("◆Sheet1") '抽出元の表のあるシート
  Set WS2 = ActiveSheet      'アクティブシート(集計表)
  Set r = WS2.Range("A1").CurrentRegion '書きこみ先表範囲
  Set r = Intersect(r, r.Offset(1, 2)) 'そのうち、正味データ部
    r.Select
    MsgBox "この範囲が正味データ範囲"
  
  r.ClearContents  '行列見出しを除く正味データ部をクリア
  tbl = r.Value   'クリア後の範囲を配列に格納
  
  '---- 書き出し先のテーブル情報をDictionaryに格納 -----
  Set dic = CreateObject("Scripting.Dictionary")
  '行列見出し位置を辞書に格納
  For Each c In r.Resize(, 1).Offset(, -1) 'A+B列見出し項目(室+大小)
    i = i + 1
    If Len(c(1, 0).Text) Then strRoom = c(1, 0).Text
    dic(strRoom & c.Text) = i
  Next
  i = 0
  For Each c In r.Resize(1).Offset(-1) '1行目見出し項目(◆年月)
    ss = Format$(c.Value, "yyyy/mm")
    i = i + 1
    dic(ss) = i
  Next
  strSecond = WS2.[B2].Value '第2 項目(見出し)のサンプル
  
  '---- 元表のA列×1行目の見出しに対応する 書きこみ先の _
    配列tblの 行列番号を Dictionaryから得る  -----
  Dim rr As Range
  Dim MonData, RoomData, dat
  Dim SecondData 'B列またはC列格納用変数
  Dim j As Long, n As Long, m As Long, x As Long
  With WS1
    .Activate      '◆デバッグ用追加
    Set rr = .Range("A1").CurrentRegion '.Resize(, 5)
    rr.Select      '←↓◆◆デバッグ用追加
    If MsgBox("この範囲が元データ範囲 " & _
      rr.Address(0, 0), vbOKCancel) = vbCancel Then Exit Sub
  End With
  
  Set rr = Intersect(rr, rr.Offset(1, 3)) '◆列方向 D列から 「室」見出し
  rr.Select        '←↓◆◆デバッグ用追加
  MsgBox "この範囲が正味数値データ範囲 " & rr.Address(0, 0)
  MonData = rr.Offset(, -3).Resize(, 1).Value
  Set c = rr.Offset(, -2).Resize(, 2)
  Set c = c.Find(strSecond, , xlValues, xlWhole)
  If c Is Nothing Then
    MsgBox "第2項目の列取得に失敗しました" & vbCr _
       & " 元データシートの B,C列に <" & strSecond & _
       "> が見つかりませんでした"
    Exit Sub
  End If
  MsgBox WS1.Cells(1, c.Column).Value & " の列を集計に使います"
  Select Case c.Column
   Case 2: x = -2
   Case 3: x = -1
  End Select
  SecondData = rr.Offset(, x).Resize(, 1).Value
  RoomData = rr.Resize(1).Offset(-1).Value
  For i = 1 To UBound(MonData, 1) '日付のレコード順に
    dat = MonData(i, 1)
    If IsDate(dat) Then
      ss = Format$(dat, "yyyy/mm")
      If dic.Exists(ss) Then
        m = dic(ss) '何列目か
        For j = 1 To UBound(RoomData, 2)
          ss = RoomData(1, j) & SecondData(i, 1)
          If dic.Exists(ss) Then
            n = dic(ss) '何行目か
            '------tblのn行,m列目の要素に 数量を累加 -----
            tbl(n, m) = tbl(n, m) + rr(i, j).Value
          End If
        Next
      End If
    End If
  Next
  
  '---- 配列に集計した結果を表に書き出す ------
  r.Value = tbl
  WS2.Activate
  MsgBox "集計が終わりました"
End Sub

【59960】Re:年間月別合計の出し方
お礼  ひかる  - 09/1/20(火) 23:42 -

引用なし
パスワード
   ▼kanabun さん:
ありがとうございます。
たくさん、記入いただきまして。
とりあえず、ご記入いただいた分をじっくり考えさせていただきます。
また、詰まりましたら、ご質問させていただきます。
ありがとうございました。

【59981】Re:年間月別合計の出し方
お礼  ひかる  - 09/1/22(木) 12:02 -

引用なし
パスワード
   ▼kanabun さん:
ひかるです。
ご記入いただいたコードやってみました。
ありがとうございました。
デバッグ用まで書いていただきよくわかりました。
思いどおりにできました。これで仮に、項目が増えても、範囲等を変更して何とか対応できると思います。日付のほうもありがとうございました。これで一段落つけそうです。
ところで、もうひとつ教えていただけますか。
最初、ファイルの容量(もちろんExcel)が、3Mほど(これでも大きいと思うのですが)だったのが、つかっているうちに(最も新たな保存で少しは、増えていくのですが、)18Mや19Mにまでなるのですが、これは、大きすぎませんか。おかしくなければよいのですが、もし、何かで、少なくする方法があれば、お教えください。

【59983】Re:年間月別合計の出し方
質問  ひかる  - 09/1/22(木) 12:52 -

引用なし
パスワード
   ▼kanabun さん:
本当に何度もすみません。
本当に最後にもうひとつお教えください。
前のデータで次のような表は埋めることはできますか。
前のデータ
>>>    A       B  C   D    E     F     G
>>>-----------------------------------------------------------------------
>>>1  日付      利用者 性別 会議室 研修室   和室   調理室
>>>2 2008年4月15日  大人  男  560   800    1000    500
>>>3 2008年4月19日  小人  女  1500  600    5200    1500
>>>4 2008年5月21日  大人  女  800   2000    800    2100
>>>5 2008年5月31日  小人  女  5000  480    2500    600
>>>6 2008年6月13日  小人  男  4500  3600    4800    1600
>>>7 2008年6月18日  大人  女  100   3600    8400    2650
>>>8 2008年6月21日  大人  男  7000  600    8000    7900

集計表
   A     B     C      D     E
1            4月     5月    6月   
2  大人   男
3       女
4  小人   男
5       女

よろしくお願いします。

【59988】Re:年間月別合計の出し方
質問  ひかる  - 09/1/22(木) 18:07 -

引用なし
パスワード
   ▼kanabun さん:
最後最後といいながら、何回も質問してすみません。
前々回にこれで項目が増えても対応できますと書いたのですが、やはりうまくいきませんでした。
大人/小人、男/女以外に、元表に仮に、会員/非会員など項目が増えた場合VBAコードのどこを修正すれば、できますか。
たくさん質問して申し訳ございませんが、ひとつひとつで構いませんのでご回答をお願いします。

【60025】Re:年間月別合計の出し方
発言  kanabun  - 09/1/24(土) 10:35 -

引用なし
パスワード
   ▼ひかる さん:
>▼kanabun さん:
>最後最後といいながら、何回も質問してすみません。
>前々回にこれで項目が増えても対応できますと書いたのですが、やはりうまくいきませんでした。
>大人/小人、男/女以外に、元表に仮に、会員/非会員など項目が増えた場合VBAコードのどこを修正すれば、できますか。

それには、これまでのコードをおさらいしてみるといいです。
まず、最初の Sub Try1()の考え方から。

> はじめに、データが次のようにあります。
>       会議室  研修室  和室  調理室 
> 04月15日   560   800   1000   500
> 04月19日   1500   600   5200   1500
> 05月21日   800   2000   800    2100
> 05月31日   5000   480   2500   600
> 06月13日   4500   3600   4800   1600
> 06月18日   100   3600   8400   2650
> 06月21日   7000   600   8000   7900
>
> このデータを使って、次のように集計月別の年間集計するには、どうしたら

>       4月 5月 6月 7月 8月 9月 10月 ・・・1月 2月 3月
> 会議室   2060 5800 11600
> 研修室   1400 2480 7800
> 和室    6200 3300 21200
> 調理室   2000 2700 12150

というときに、どうしましたか?

集計先の書き込むデータ範囲を変数tblにして、その4行×12列の各要素に
下のように行列番号をつけ、そこに、元データ表より該当する数値を集計
して いきましたよね?

>       4月   5月   6月   7月  ・・・ 3月 
> 会議室   (1, 1)  (1, 2) (1,3)  (1,4) ・・・ (1,12)
> 研修室   (2, 1)  (2, 2) (2,3)  (2,4) ・・・ (2,12)
> 和室    (3, 1)  (3, 2) (3,3)  (3,4) ・・・ (3,12)
> 調理室   (4, 1)  (4, 2) (4,3)  (4,4) ・・・ (4,12)

このtblという配列内の位置が行列番号で分かれば、その位置にデータを
加算していけばいいわけです。
たとえば、元データが
>       会議室  研修室  和室  調理室 
> 04月15日   560   800   1000   500

のようだったとき、
04月15日を →「4月」になおして、
 「会議室」「4月」の位置に 560 を加算し、
 「研修室」「4月」の位置に 800 を加算し、
  ・・・
 「調理室」「4月」の位置に 500 を加算する、
ということをするために、
Q1. 書きこみ先の「会議室」は何行目(n) にありますか?
Q2. 書きこみ先の「4月」は何列目(m) にありますか?
という2つのことが分かれば、tbl(n, m) の位置にデータ(数値)を
足してやればいいのだから、
Sub Try1()では、
 あらかじめ
 「会議室」 = 1
 「研修室」 = 2
 「和室」  = 3
 「調理室」 = 4
という行番号と、
  「4月」 = 1
  「5月」 = 2
  ・・・
  「2月」 = 11
  「3月」 = 12
という列番号を Dictionary オブジェクト (ここで 変数dicとして
いるものがそれ) に、番号を記憶させています。
Sub Try1()で
↓の部分がそれをしているところであることはお分かりですか?

>   '行列見出し位置を辞書に格納
>   For Each c In r.Resize(, 1).Offset(, -1) 'A列見出し項目(室)
>     i = i + 1
>     dic(c.Text) = i
>   Next
>   i = 0
>   For Each c In r.Resize(1).Offset(-1) '1行目見出し項目(月)
>     i = i + 1
>     dic(c.Text) = i
>   Next

Sub Try1()の
そのあとの部分は、
>   '---- 元表のA列×1行目の見出しに対応する 書きこみ先の _
>     配列tblの 行列番号を Dictionaryから得る  -----
>   Dim rr As Range
>   Dim MonData, RoomData, dat, ss As String
>   Dim j As Long, n As Long, m As Long
>
>   Set rr = Worksheets("Sheet1").Range("A1").CurrentRegion.Resize(, 5)
>   Set rr = Intersect(rr, rr.Offset(1, 1))
>   MonData = rr.Resize(, 1).Offset(, -1).Value
>   RoomData = rr.Resize(1).Offset(-1).Value
>   For i = 1 To UBound(MonData, 1)
>     dat = MonData(i, 1)
>     If IsDate(dat) Then
>       ss = Month(dat) & "月"
>       If dic.Exists(ss) Then
>         m = dic(ss) '何列目か
>         For j = 1 To UBound(RoomData, 2)
>           ss = RoomData(1, j)
>           If dic.Exists(ss) Then
>             n = dic(ss) '何行目か
>             '------tblのn行,m列目の要素に 数量を累加-
>             tbl(n, m) = tbl(n, m) + rr(i, j).Value
>           End If
>         Next
>       End If
>     End If
>   Next

元表を 行順、列順で2重ループして↓
>   For i = 1 To UBound(MonData, 1)
>         For j = 1 To UBound(RoomData, 2)
各セルのデータを tbl配列の(n行, m列)目に集計していっている
ところです。
まず、
>   For i = 1 To UBound(MonData, 1)
で行順に読んでいって、その行が何月のデータであるかを取得し、
月の名前に対応する書きこみ先tblの列番号を
>         m = dic(ss) '何列目か
のように、dicから取得しています。これは
dic("4月") = 1
のように「4月」に対応する列番号がdictionaryに記憶されているからです。
何列目に書き込むかは、元表のA列の日付をみれば分かりましたから、
2番目の(内側の)
>         For j = 1 To UBound(RoomData, 2)
で、今度は 列見出し ▼
>       会議室  研修室  和室  調理室 
> 04月15日   560   800   1000   500
が 配列変数 RoomData のなかに格納されていますから
      j▼
RoomData(1, 1) = "会議室" → dic("会議室") = 1 → n = 1
RoomData(1, 2) = "研修室" → dic("研修室") = 2 → n = 2
RoomData(1, 3) = "和室"  → dic("和室") = 3  → n = 3
RoomData(1, 4) = "調理室" → dic("調理室") = 4 → n = 4
のように、書き込み先の n (行番号)を取得して、
tbl配列の(n行,m列)目に 数値データを加えているわけです。

>         '------tblのn行,m列目の要素に 数量を累加-
>         tbl(n, m) = tbl(n, m) + rr(i, j).Value

ですから、Try1()でやっていることが分かれば、
Sub Try2() や Sub Try3()や Sub Try4() も、Try1()の応用で
できることなのです。
集計先の列見出しと行見出し番号を dicに格納して、
元表のほうを順に 指定された行番号の指定された列位置に加算して
いけばいいわけです。
ただし、集計表の行見出しが複数項目になるばあい
> 集計表
>    A    B      C    D    E
> 1             4月   5月   6月
> 2 会議室   大人 
> 3       小人
> 4 研修室   大人  
> 5       小人
> 6 和室    大人
> 7       小人 
> 8 調理室   大人
> 9       小人

は、dicに格納する tbl配列の行番号は A列とB列を結合したものに
して行を特定する、とか、
  dic("会議室大人") = 1
  dic("会議室小人") = 2
  dic("研修室大人") = 3
  dic("研修室小人") = 4
  ・・・        "会議室"だけでは行が特定できない


一つの元表から、
>>>    A   B   C    D      E     F      G
>>>----------------------------------------------------------------------
>>>1  日付  利用者 性別  会議室   研修室   和室   調理室
>>>2  4月15日 大人   男   560    800    1000    500
>>>3  4月19日 小人   女   1500    600    5200    1500
>>>4  5月21日 大人   女   800    2000    800    2100
>>>5  5月31日 小人   女   5000    480    2500    600
>>>6  6月13日 小人   男   4500    3600    4800    1600
>>>7  6月18日 大人   女   100    3600    8400    2650
>>>8  6月21日 大人   男   7000    600    8000    7900

複数形式の集計をしたい
▼Case 1
>            4月    5月    6月    7月
> 1 会議室  大人  
> 2 会議室  小人      
> 3 研修室  大人       
> 4 研修室  小人      
> 5 和室   大人  
> 6 和室   小人  
> 7 調理室  大人  
> 8 調理室  小人  
>
▼Case 2
>            4月    5月    6月    7月
> 1 会議室  男  
> 2 会議室  女  
> 3 研修室  男  
> 4 研修室  女  
> 5 和室   男  
> 6 和室   女       
> 7 調理室  男  
> 8 調理室  女

という場合のように、
集計先のテーブルに合わせて、元表の結合する列を特定する処理が追加される、
とか
そういう応用処理が加わっているだけです。

いちど、ひかるご自身で、ぼくがTry1()に対して行ったような解析
(コードのトレース)を日本語で行ってみて、コードの各行が何をして
いるものなのか、何をするためにこの一行があるのか、コメントをつけて
見てください。

【60026】Re:年間月別合計の出し方
発言  kanabun  - 09/1/24(土) 10:40 -

引用なし
パスワード
   すみません。
敬称をつけるのを忘れました m(__)m

誤 いちど、ひかるご自身で、
正  ひかるさんご自身で

【60036】Re:年間月別合計の出し方
お礼  ひかる  - 09/1/24(土) 19:18 -

引用なし
パスワード
   ▼kanabun さん:
お返事ありがとうございます。
解析(コードのトレース)を日本語で行ってみて、コメントをつけてみます。
また、コメントをつけたものをだしてみますので、添削のほどよろしくお願いします。
また、この質問の前にも、3、4点質問しておりますので、そちらのご回答もよろしくお願いします。

【60054】Re:年間月別合計の出し方
質問  ひかる  - 09/1/26(月) 11:50 -

引用なし
パスワード
   ▼kanabun さん:
ご指摘いただきました解説をじっくりとみさせていただきました。
最初よりだいぶ理解できたと思います。
それで、この関連で最後の質問をさせてください。
前のデータより次の表をうめる便利な方法があればお教えください。


前のデータ
>>>    A       B  C   D    E     F     G
>>>-----------------------------------------------------------------------
>>>1  日付      利用者 性別 会議室 研修室   和室   調理室
>>>2 2008年4月15日  大人  男  560   800    1000    500
>>>3 2008年4月19日  小人  女  1500  600    5200    1500
>>>4 2008年5月21日  大人  女  800   2000    800    2100
>>>5 2008年5月31日  小人  女  5000  480    2500    600
>>>6 2008年6月13日  小人  男  4500  3600    4800    1600
>>>7 2008年6月18日  大人  女  100   3600    8400    2650
>>>8 2008年6月21日  大人  男  7000  600    8000    7900


集計表                           単位:円
   A     B     C      D     E  ........... K
1            4月     5月    6月  ...........12月  
2  大人   男
3       女
4  小人   男
5       女

【60061】Re:年間月別合計の出し方
発言  kanabun  - 09/1/26(月) 14:39 -

引用なし
パスワード
   ▼ひかる さん:
>▼kanabun さん:
>ご指摘いただきました解説をじっくりとみさせていただきました。
>最初よりだいぶ理解できたと思います。
>それで、この関連で最後の質問をさせてください。
>前のデータより次の表をうめる便利な方法があればお教えください。

あの、その方法を習得してもらうために、これまで長々とTry1()の解説
をして来たつもりなのですが?

ぼくは前々回のレスで、
> いちど、ひかるさんご自身で、ぼくがTry1()に対して行ったような解析
> (コードのトレース)を日本語で行ってみて、コードの各行が何をして
> いるものなのか、何をするためにこの一行があるのか、コメントをつけて
> 見てください。
と発言しました。
それに対して、ひかるさんは
> ▼kanabun さん:
> お返事ありがとうございます。
> 解析(コードのトレース)を日本語で行ってみて、コメントをつけてみます。
> また、コメントをつけたものをだしてみますので、添削のほど
> よろしくお願いします。
とおっしゃっていますから、ぼくはどのようなコメント付きコードが
出てくるか、楽しみにしていたのですよ。

◆要望 シート構成に 合わせて Try1() 〜 Try4() と同様のコードが
    空で(サンプルコードを見ないで)書けるようになるまで、
    反復練習してみてください。
もちろん、コードの意味が分からない部分があれば、時間のあるときに
お答えしますよ

>それで、この関連で最後の質問をさせてください。
別に期限があるわけではないので、閉じ急ぐ必要はさらさらないですよ。
Try1()〜 Try4() までの サンプルコードが理解でき、
ご自分で、↓のようなレイアウトのばあいに、それらを応用したコードが
試行錯誤しながらでも、書けるようになったときが、このスレッドを
終了するときです。

> 集計表                           単位:円
>    A     B     C      D     E  ........... K
> 1            4月     5月    6月  ...........12月  
> 2  大人   男
> 3       女
> 4  小人   男
> 5       女

'主に Sub Try4()を参考にして、上の集計表に合うように修正
していきます
'下に、サンプルコードを示します。
 現在の Sub Try5()をコピーしてモジュールに
 貼り付けると、たくさん 赤字になります。
 から、コメントにガイダンスがあるように
 空白部を実際のコードで埋めていってください。
'--------------------------------------------------
Option Explicit 'モジュールの先頭に宣言する(変数は必ず _
         宣言して使うため )

Sub Try5() '集計先のシートをアクティブにして実行
  Dim WS1 As Worksheet
  Dim WS2 As Worksheet
  Dim dic As Object
  Dim r As Range, c As Range
  Dim tbl
  Dim i As Long, ss As String
  Dim strFirst As String  '変数strRoomを変更
               '(集計シートのA列:大人/小人)
  Dim strSecond As String '集計シートのB列:男/女
  
  '抽出元の表のあるシートを変数WS1 にセットしてください
  Set WS1 = Worksheets("    ") 
  Set WS2 = ActiveSheet  'アクティブシート(集計表)
  '集計表シートがアクティブになっているか、確認する
  If WS2.Name = WS1.Name Then
    MsgBox "集計用シートをアクティブにして実行すること"
    Exit Sub '中断
  End If

'◆これより 集計表のレイアウトの取得
  '書きこみ先(集計表)表範囲を変数r にセットしてください
  Set r = WS2.             '書きこみ先表範囲
  Set r = Intersect( ,    ) 'そのうち、正味データ部を _
                  変数r に再代入してください
   '↑◆ヒント 上のような集計表構成では _
        [A1].CurrentRegion により変数rrに表全体範囲が _
        入っていますから、その範囲と、 _
        その範囲を1行下に、2列右にシフトした範囲 _
        とが重なる範囲を Intersectメソッドで取得すれば _
        いいです

  r.clearcontents  '行列見出しを除く正味データ部をクリア
  tbl = r.      'クリア後の範囲を配列に格納してください
        '↑◆ヒント RangeオブジェクトのValueプロパティ

  '---- 集計テーブルの情報を Dictionary に格納 -----
  '↓Dictionaryオブジェクトのインストール
                         ←
  'A列見出しと B列見出しを結合して 行位置(行index)を辞書に格納
  For Each c In r.Resize(, 1).Offset(, -1) 'B列見出し項目でLoop
    i = i + 1
    If Len(c(1, 0).Text) Then strFirst = c(1, 0).Text 'A列文字列
    dic(strFirst & c.Text) = i 
     'この処理で dic("大人男") に(行番号) 1 が、 _
           dic("大人女") に(行番号) 2 が、 _
           dic("小人女") に(行番号) 3 が、 _
           dic("小人女") に(行番号) 4 が格納されます
  Next
  Stop
  '上のLoopが終わったあと 変数strFirstには「小人」が格納されて _
   います。Stopはプログラムの実行を中断するための命令です。 _
   Stopしたら、メニュ−[表示]−[ローカルウィンドウ]で
   ローカルウィンドウをのぞいて 変数の内容を確かめてください。

  '次に ---------------------------------------------------
   '1行目見出し項目(◆年月)情報をdicに記憶しておきます
   'この部分は Try4()がそのまま使えると思います。
                         ←
   '--------------------------------------------------------
  '↓変数strSecond に集計表B列の見出し項目を記憶
  strSecond = WS2.range("B2").Value 'この例では「男」が代入 _
        されます。ステップ実行[F8]してこの行を実行したら _
        マウスを変数strSecond に近づけて 確認してください
  
  '---- 元表のA列×1行目の見出しに対応する 書きこみ先の _
    配列tblの 行列番号を Dictionaryから得る  -----
  Dim rr As Range, cc As Range
  Dim MonData, dat
  Dim FirstData 'B列またはC列格納用変数
  Dim SecondData 'B列またはC列格納用変数
  Dim j As Long, n As Long, m As Long
  Dim x As Long '◆見出し列位置(B列/C列)
  
'◆ここからが データ元表より抽出する部分です
  With WS1
    .Activate               'デバッグ用
    Set rr =        '変数rr に表範囲をセットする
  End With
  '例によって 元表の数値データ部分をとりだし、 _
    変数rr に再セットしてください
  Set rr = Intersect(rr,         )
   '◆ヒント 下のような元表構成では 表全体範囲rr と その範囲を _
        1行下に、3列右にシフトした範囲 とが重なる範囲です

>>>    A   B   C    D      E     F      G
>>>----------------------------------------------------------------------
>>>1  日付  利用者 性別  会議室   研修室   和室   調理室
>>>2  4月15日 大人   男   560    800    1000    500
>>>3  4月19日 小人   女   1500    600    5200    1500
>>>4  5月21日 大人   女   800    2000    800    2100
>>>5  5月31日 小人   女   5000    480    2500    600
>>>6  6月13日 小人   男   4500    3600    4800    1600
>>>7  6月18日 大人   女   100    3600    8400    2650
>>>8  6月21日 大人   男   7000    600    8000    7900

  '配列変数に A列日付データを格納してください
  MonData = rr.                 'A列
  
  '次に 元表のA,B列範囲から strFirst(具体的には「小人」)が _
   元表のどこにあるか調べます
  Set cc = rr.Offset(, -2).Resize(, 2)
  Set c = cc.Find(strFirst, , xlValues, xlWhole)
  If c Is Nothing Then
    MsgBox "第1項目の列取得に失敗しました" & vbCr _
       & " 元データシートの B,C列に <" & strSecond & _
       "> が見つかりませんでした"
    Exit Sub
  Else
    x = c.Column - 1
    MsgBox cc.Item(0, x).Value _
        & " の列を集計に使います"
    '見つかった列のデータを配列変数FirstData に格納します。
    'そのまま2次元配列(行, 列)として格納してもいいのですが、 _
     簡単のためTransposeで縦に並んだデータをよこにすると、 _
     一次元配列になります
    FirstData = Application.Transpose(cc.Columns(x))
  End If
  
  Set c = cc.Find(strSecond, , xlValues, xlWhole)
  If c Is Nothing Then
    MsgBox "第2項目の列取得に失敗しました" & vbCr _
       & " 元データシートの B,C列に <" & strSecond & _
       "> が見つかりませんでした"
    Exit Sub
  Else
    x = c.Column - 1
    MsgBox cc.Item(0, x).Value _
        & " の列を集計に使います"
    SecondData = Application.Transpose(cc.Columns(x))
  End If
  
  For i = 1 To UBound(MonData, 1) '日付のレコード順に
    dat = MonData(i, 1)
    If IsDate(dat) Then
      ss = Format$(dat, "yyyy/mm") '年月日を 年月に直す
      If dic.Exists(ss) Then
        m = dic(ss) '書きこみ先は 何列目か ?
        ss = FirstData(i) & SecondData(i)
        If dic.Exists(ss) Then
          n = dic(ss) '書きこみ先は 何行目か ?
          '↑ここまでは Try4()と同じです
          '↓集計のしかたが変わりました。 _
           これまでは一つのセルデータを集計先に累加 _
           していましたが、今回は i行のデータはすべて _
           SUM して、対象要素位置(n,m) に渡します。
       '------tblのn行,m列目の要素に 数量を累加 -----
          With Application
            tbl(n, m) = tbl(n, m) _
            + .Sum(.Index(rr.Rows(i).Value, 0))
          End With
        End If
      End If
    End If
  Next
  
  '---- 配列に集計した結果を表に書き出す ------
  r.Value = tbl
  WS2.Activate
  MsgBox "集計が終わりました"
End Sub

◆コードの穴埋めがおわりましたら、ここに報告してくださいね

【60097】Re:年間月別合計の出し方
お礼  ひかる  - 09/1/27(火) 12:42 -

引用なし
パスワード
   ▼kanabun さん:
大変申し訳ありませんでした。
自分で考えず、kanabunさんにたよりすぎました。申し訳ございません。
にもかかわらず、穴埋め問題で助け舟まで出していただき言葉もありません。ありがとうございます。
それで、とりあえず穴は埋めさせていただきました。
これで実行して、結果も得られました。ありがとうございました。
それで、コードの中で質問なのですが、
1点目は、集計テーブルのA列とB列見出しの結合のところですが、
If Len(c(1,0).text) then ・・・・のc(1,0)なのですが、私は、この場合男の横が大人だと思ったのでc(0,-1)と思ったのですが、どうしてこうなるのでしょうか。
2点目は、配列変数に A列日付データを格納するところですが、
MonData = rr.rr.Offset(, -3).Resize(, 1).Valueの.Resize(,1)なのですが、Resize(,1)の1は、なぜ1なのですか。ほしいのはMonDataだから、日付の入っている分が重要でこれにはあまり意味がないということでしょうか。
つまらない質問でもうしわけございませんがお教えください。
よろしくお願いします。


>'--------------------------------------------------
>Option Explicit 'モジュールの先頭に宣言する(変数は必ず _
>         宣言して使うため )
>
>Sub Try5() '集計先のシートをアクティブにして実行
>  Dim WS1 As Worksheet
>  Dim WS2 As Worksheet
>  Dim dic As Object
>  Dim r As Range, c As Range
>  Dim tbl
>  Dim i As Long, ss As String
>  Dim strFirst As String  '変数strRoomを変更
>               '(集計シートのA列:大人/小人)
>  Dim strSecond As String '集計シートのB列:男/女
>  
>  '抽出元の表のあるシートを変数WS1 にセットしてください
>  Set WS1 = Worksheets("◆sheet1") 
>  Set WS2 = ActiveSheet  'アクティブシート(集計表)
>  '集計表シートがアクティブになっているか、確認する
>  If WS2.Name = WS1.Name Then
>    MsgBox "集計用シートをアクティブにして実行すること"
>    Exit Sub '中断
>  End If
>
>'◆これより 集計表のレイアウトの取得
>  '書きこみ先(集計表)表範囲を変数r にセットしてください
>  Set r = WS2.             '書きこみ先表範囲
>  Set r = Intersect(r,r.Offset(1, 2)) 'そのうち、正味データ部を _
>                  変数r に再代入してください
>   '↑◆ヒント 上のような集計表構成では _
>        [A1].CurrentRegion により変数rrに表全体範囲が _
>        入っていますから、その範囲と、 _
>        その範囲を1行下に、2列右にシフトした範囲 _
>        とが重なる範囲を Intersectメソッドで取得すれば _
>        いいです
>
>  r.clearcontents  '行列見出しを除く正味データ部をクリア
>  tbl = r.value   'クリア後の範囲を配列に格納してください
>        '↑◆ヒント RangeオブジェクトのValueプロパティ
>
>  '---- 集計テーブルの情報を Dictionary に格納 -----
>  '↓Dictionaryオブジェクトのインストール
>  Set dic = CreateObject("Scripting.Dictionary") ←
>  'A列見出しと B列見出しを結合して 行位置(行index)を辞書に格納
>  For Each c In r.Resize(, 1).Offset(, -1) 'B列見出し項目でLoop
>    i = i + 1
>    If Len(c(1, 0).Text) Then strFirst = c(1, 0).Text 'A列文字列
>    dic(strFirst & c.Text) = i 
>     'この処理で dic("大人男") に(行番号) 1 が、 _
>           dic("大人女") に(行番号) 2 が、 _
>           dic("小人女") に(行番号) 3 が、 _
>           dic("小人女") に(行番号) 4 が格納されます
>  Next
>  Stop
>  '上のLoopが終わったあと 変数strFirstには「小人」が格納されて _
>   います。Stopはプログラムの実行を中断するための命令です。 _
>   Stopしたら、メニュ−[表示]−[ローカルウィンドウ]で
>   ローカルウィンドウをのぞいて 変数の内容を確かめてください。
>
>  '次に ---------------------------------------------------
>   '1行目見出し項目(◆年月)情報をdicに記憶しておきます
>   'この部分は Try4()がそのまま使えると思います。
>  i = 0
  For Each c In r.Resize(1).Offset(-1) '1行目見出し項目(◆年月)
    ss = Format$(c.Value, "yyyy/mm")
    i = i + 1
    dic(ss) = i
  Next                      ←
>   '--------------------------------------------------------
>  '↓変数strSecond に集計表B列の見出し項目を記憶
>  strSecond = WS2.range("B2").Value 'この例では「男」が代入 _
>        されます。ステップ実行[F8]してこの行を実行したら _
>        マウスを変数strSecond に近づけて 確認してください
>  
>  '---- 元表のA列×1行目の見出しに対応する 書きこみ先の _
>    配列tblの 行列番号を Dictionaryから得る  -----
>  Dim rr As Range, cc As Range
>  Dim MonData, dat
>  Dim FirstData 'B列またはC列格納用変数
>  Dim SecondData 'B列またはC列格納用変数
>  Dim j As Long, n As Long, m As Long
>  Dim x As Long '◆見出し列位置(B列/C列)
>  
>'◆ここからが データ元表より抽出する部分です
>  With WS1
>    .Activate               'デバッグ用
>    Set rr = .Range("A1").CurrentRegion '変数rr に表範囲をセットする
>  End With
>  '例によって 元表の数値データ部分をとりだし、 _
>    変数rr に再セットしてください
>  Set rr = Intersect(rr, rr.Offset(1, 3))
>   '◆ヒント 下のような元表構成では 表全体範囲rr と その範囲を _
>        1行下に、3列右にシフトした範囲 とが重なる範囲です
>
>>>>    A   B   C    D      E     F      G
>>>>----------------------------------------------------------------------
>>>>1  日付  利用者 性別  会議室   研修室   和室   調理室
>>>>2  4月15日 大人   男   560    800    1000    500
>>>>3  4月19日 小人   女   1500    600    5200    1500
>>>>4  5月21日 大人   女   800    2000    800    2100
>>>>5  5月31日 小人   女   5000    480    2500    600
>>>>6  6月13日 小人   男   4500    3600    4800    1600
>>>>7  6月18日 大人   女   100    3600    8400    2650
>>>>8  6月21日 大人   男   7000    600    8000    7900
>
>  '配列変数に A列日付データを格納してください
>  MonData = rr.rr.Offset(, -3).Resize(, 1).Value   'A列
>  
>  '次に 元表のA,B列範囲から strFirst(具体的には「小人」)が _
>   元表のどこにあるか調べます
>  Set cc = rr.Offset(, -2).Resize(, 2)
>  Set c = cc.Find(strFirst, , xlValues, xlWhole)
>  If c Is Nothing Then
>    MsgBox "第1項目の列取得に失敗しました" & vbCr _
>       & " 元データシートの B,C列に <" & strSecond & _
>       "> が見つかりませんでした"
>    Exit Sub
>  Else
>    x = c.Column - 1
>    MsgBox cc.Item(0, x).Value _
>        & " の列を集計に使います"
>    '見つかった列のデータを配列変数FirstData に格納します。
>    'そのまま2次元配列(行, 列)として格納してもいいのですが、 _
>     簡単のためTransposeで縦に並んだデータをよこにすると、 _
>     一次元配列になります
>    FirstData = Application.Transpose(cc.Columns(x))
>  End If
>  
>  Set c = cc.Find(strSecond, , xlValues, xlWhole)
>  If c Is Nothing Then
>    MsgBox "第2項目の列取得に失敗しました" & vbCr _
>       & " 元データシートの B,C列に <" & strSecond & _
>       "> が見つかりませんでした"
>    Exit Sub
>  Else
>    x = c.Column - 1
>    MsgBox cc.Item(0, x).Value _
>        & " の列を集計に使います"
>    SecondData = Application.Transpose(cc.Columns(x))
>  End If
>  
>  For i = 1 To UBound(MonData, 1) '日付のレコード順に
>    dat = MonData(i, 1)
>    If IsDate(dat) Then
>      ss = Format$(dat, "yyyy/mm") '年月日を 年月に直す
>      If dic.Exists(ss) Then
>        m = dic(ss) '書きこみ先は 何列目か ?
>        ss = FirstData(i) & SecondData(i)
>        If dic.Exists(ss) Then
>          n = dic(ss) '書きこみ先は 何行目か ?
>          '↑ここまでは Try4()と同じです
>          '↓集計のしかたが変わりました。 _
>           これまでは一つのセルデータを集計先に累加 _
>           していましたが、今回は i行のデータはすべて _
>           SUM して、対象要素位置(n,m) に渡します。
>       '------tblのn行,m列目の要素に 数量を累加 -----
>          With Application
>            tbl(n, m) = tbl(n, m) _
>            + .Sum(.Index(rr.Rows(i).Value, 0))
>          End With
>        End If
>      End If
>    End If
>  Next
>  
>  '---- 配列に集計した結果を表に書き出す ------
>  r.Value = tbl
>  WS2.Activate
>  MsgBox "集計が終わりました"
>End Sub

【60105】Re:年間月別合計の出し方
発言  kanabun  - 09/1/27(火) 15:56 -

引用なし
パスワード
   ▼ひかる さん:
>▼kanabun さん:
>穴埋め問題で助け舟まで出していただき言葉もありません。ありがとうございます。
>それで、とりあえず穴は埋めさせていただきました。
>これで実行して、結果も得られました。ありがとうございました。

>コードの中で質問なのですが、
>1点目は、集計テーブルのA列とB列見出しの結合のところですが、
>If Len(c(1,0).text) then ・・・・のc(1,0)なのですが、
>私は、この場合男の横が大人だと思ったのでc(0,-1)と思ったのですが、
>どうしてこうなるのでしょうか。

c(1, 0) は c.Item(1, 0) の省略記法です。

セルc は、具体的には
>For Each c In r.Resize(, 1).Offset(, -1) 'B列見出し項目でLoop
とありますから、集計表が以下のようなとき、                       
>    A     B     C      D     E  ...........
> 1            4月     5月    6月  ...........
> 2  大人   男
> 3       女
> 4  小人   男
> 5       女

cは、正味集計範囲 r([C2]セルから12列 5行目までの範囲)を
Resize(, 1) で C列だけの1列にリサイズして、
Offset(, -1) で左方向に1列シフトした列、すなわち B列のことに
なります。
>For Each c In r.Resize(, 1).Offset(, -1) 'B列見出し項目でLoop
で、最初のc は 具体的には [B2]セルです。
c が [B2]セルのとき、c.Item(1,1) は [B2]セルそのもので、
c.Item(1, 0) は [B2]のひとつ左のセル すなわち [A2]セル
ということになります。
同様に、cが[B2]のとき、
c.Item(0,1) といえば [B2]のひとつ上の行 すなわち [B1]セル、
c.Item(2,1) といえば [B2]のひとつ下の行 すなわち [B3]セル
を示すことになります。
結局、この一行は↓

> If Len(c(1, 0).Text) Then strFirst = c(1, 0).Text 'A列文字列

cのひとつ左のセルのテキストが書きこまれていたら、
変数strFirst に そのテキスト(たとえば「大人」)を代入し、
何も書きこまれていなければ strFirstの内容は変更しない、
という処理をしているわけです。


>2点目は、配列変数に A列日付データを格納するところですが、
>MonData = rr.rr.Offset(, -3).Resize(, 1).Valueの.Resize(,1)
>なのですが、Resize(,1)の1は、なぜ1なのですか。
>ほしいのはMonDataだから、日付の入っている分が重要で
>これにはあまり意味がないということでしょうか。

rr がひとつ多いですね?
 MonData = rr.Offset(, -3).Resize(, 1).Value
ということでは?
これも、質問1 でお答えしたとおりです。
範囲を 左に3列オフセットして、1列だけにResize する
ということをしているから、A列だけが取り出されるわけです。


>>'◆これより 集計表のレイアウトの取得
>>  '書きこみ先(集計表)表範囲を変数r にセットしてください
       ◆ここは↓?
>>  Set r = WS2.             '書きこみ先表範囲
>>  Set r = Intersect(r,r.Offset(1, 2))
            ↑OK です
>>  tbl = r.value   'クリア後の範囲を配列に格納してください
      '↑◆OK です

>>  i = 0
>  For Each c In r.Resize(1).Offset(-1) '1行目見出し項目(◆年月)
>    ss = Format$(c.Value, "yyyy/mm")
>    i = i + 1
>    dic(ss) = i
>  Next        '↑◆OK です
>>   '--------------------------------------------------------

>>  Set rr = Intersect(rr, rr.Offset(1, 3))
      '↑◆OK です

>>
>>  '配列変数に A列日付データを格納してください
>>  MonData = rr.rr.Offset(, -3).Resize(, 1).Value   'A列
       '↑◆rr がひとつ多い です

ざっとしかチェックしてませんが、
短時間のうちによく理解されましたね(^^


あと、
ファイルサイズがどんどん大きくなる問題ですが、

> 最初、ファイルの容量(もちろんExcel)が、3Mほど(これでも大きいと
> 思うのですが)だったのが、つかっているうちに(最も新たな保存で
> 少しは、増えてい> くのですが、)18Mや19Mにまでなるのですが、
> これは、大きすぎませんか。

この問題は マクロ付きのExcelファイルによくある現象です。
ht tp://peiyorin.cocolog-nifty.com/blog/2007/09/excel_1635.html
などに、原因と解決方法が書いてありますので、いちど読んでみて
ください。
Bookにマクロがついていて、そのマクロを修正して保存するということ
を繰り返すから、肥大化するわけですから、根本的な解決法としては
データBookとマクロBookを分離することです。
そうすれば、他の人に使ってもらうときでも、いつも最新バージョンの
マクロBookを配布すればいいわけですから。
具体的な方法が分からないときは、これは一つのトピックですので、
スレッドを改めてご質問なさるといいかもしれませんね。

【60106】Re:年間月別合計の出し方
お礼  ひかる  - 09/1/27(火) 16:27 -

引用なし
パスワード
   ▼kanabun さん:
お答ありがとうございました。
どれもよくわかる解説で、とてもたくさんの知識が得ることができました。
世の中には、こんなにも物知りで、親切な方もいるのですね。
このレベルになるまでには、相当かかると思いますが、解説にありましたみないでかけるよう反復練習したり、またどんどん新しいことをおぼえていきたいと思います。
この話題で長々とひっぱりまして申し訳ございませんでした。
また、どうしてもわからず、詰まった時、ひかるで投稿させていただきますので何とぞよろしくお願いします。

3810 / 13646 ツリー ←次へ | 前へ→
ページ:  ┃  記事番号:
2610219
(SS)C-BOARD v3.8 is Free