Excel VBA質問箱 IV

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

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


7847 / 13645 ツリー ←次へ | 前へ→

【36485】コードによる集計をVBAで行う方法 mero 06/4/1(土) 17:03 質問[未読]
【36488】Re:コードによる集計をVBAで行う方法 inoue 06/4/1(土) 17:52 発言[未読]
【36491】Re:コードによる集計をVBAで行う方法 mero 06/4/1(土) 20:30 お礼[未読]
【36489】Re:コードによる集計をVBAで行う方法 Kein 06/4/1(土) 18:02 発言[未読]
【36490】Re:コードによる集計をVBAで行う方法 mero 06/4/1(土) 20:29 お礼[未読]
【36492】Re:コードによる集計をVBAで行う方法 Hirofumi 06/4/1(土) 21:17 回答[未読]
【36494】Re:コードによる集計をVBAで行う方法 mero 06/4/1(土) 21:55 お礼[未読]

【36485】コードによる集計をVBAで行う方法
質問  mero  - 06/4/1(土) 17:03 -

引用なし
パスワード
   はじめましてmeroともうします。
毎月集計作業をしなければ成りません。
その内容は、商品にコード番号がつけられ値段もあります。
それをコード1番から10番までを集計して別のシートにコード1〜10と表示したセルの右横に集計結果を自動的に計算できないでしょうか?
ただし、コードが1番から1000番まであります。
    それを1〜10、11〜20、・・・・・990〜1000というふうに10づつくぎって
    集計したものをそれぞれの該当するセルの右横にあるセルに計算結果を
    表示したいのです。
ここでは、コードの区切りを単純にしていますが実務では10づつではなくもっと
複雑な区切りになります。
わたしが理解しやすいように、単純に10づつの区切りで教えていただきたいと
おもいます。
説明不足と思いますがよろしくお願いいたします

【36488】Re:コードによる集計をVBAで行う方法
発言  inoue E-MAILWEB  - 06/4/1(土) 17:52 -

引用なし
パスワード
   SUMIF、SUMPRODUCT、配列数式など計算式レベルでできそうですが、
VBAでないといけないのでしょうか。

VBAでやりたいなら、こんなところを参考にしてください。
[「集計」機能を自分で作るサンプル。]
http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_160_11.html

【36489】Re:コードによる集計をVBAで行う方法
発言  Kein  - 06/4/1(土) 18:02 -

引用なし
パスワード
   >実務では10づつではなくもっと複雑な区切り
であれば、SUMIF関数を拡張して複数の条件を指定できる↓のようなコードを利用したら
良いでしょう。
http://homepage2.nifty.com/kmado/ke_m1.htm#E95M004

【36490】Re:コードによる集計をVBAで行う方法
お礼  mero  - 06/4/1(土) 20:29 -

引用なし
パスワード
   ▼Kein さん:
>>実務では10づつではなくもっと複雑な区切り
>であれば、SUMIF関数を拡張して複数の条件を指定できる↓のようなコードを利用したら
>良いでしょう。
>http://homepage2.nifty.com/kmado/ke_m1.htm#E95M004
早速、ご回答有難うございました。
少し難しそうですが、参考にさせていただきます。

【36491】Re:コードによる集計をVBAで行う方法
お礼  mero  - 06/4/1(土) 20:30 -

引用なし
パスワード
   ▼inoue さん:
>SUMIF、SUMPRODUCT、配列数式など計算式レベルでできそうですが、
>VBAでないといけないのでしょうか。
>
>VBAでやりたいなら、こんなところを参考にしてください。
>[「集計」機能を自分で作るサンプル。]
>http://www.asahi-net.or.jp/~ef2o-inue/vba_k/sub04_160_11.html
早速、ご回答有難うございました。
大変参考になりました。

【36492】Re:コードによる集計をVBAで行う方法
回答  Hirofumi  - 06/4/1(土) 21:17 -

引用なし
パスワード
   もう見て居ないかな?

Sheet1に以下の様なデータが有るとします

    A    B
1   コード 値段
2   20   710
3   37   785
4   36   527
5   29   521
6   83   394
7   79   561
8   30   493
9    ・   ・
10   ・   ・

Sheet2に以下の様な集計表が有るとします

   A    B
1   以上  合計
2   1    
3   11    
4   21    
5   31    
6   41    
7   51    
8   61    
9   71    
10   81    
11   91    

以下のコードを実行すると、
集計表のB2には、1以上11未満のコードに対する、値段の合計が入ります
同様に、B3には、11以上21未満のコードに対する、値段の合計が入ります

Option Explicit

Public Sub Sample()

  Dim i As Long
  Dim lngRows As Long
  Dim rngList As Range
  Dim vntData As Variant
  Dim vntMark As Variant
  Dim lngFound As Long
  Dim lngUnder As Long
  Dim rngResult As Range
  Dim strProm As String
  
  '結果出力基準位置を設定
  Set rngResult = Worksheets("Sheet2").Cells(1, "B")
  '集計コードの階級表に位置を配列に取得
  With rngResult.Offset(, -1)
    'データ行数を取得
    lngRows = .Offset(65536 - .Row).End(xlUp).Row - .Row
    'データが無い場合
    If lngRows <= 0 Then
      strProm = "階級表が有りません"
      GoTo Wayout
    End If
    '階級を配列に取得
    vntMark = .Offset(1).Resize(lngRows).Value
    '結果出力用配列を確保
    ReDim vntResult(1 To lngRows, 1 To 1)
  End With
  
  'データListの左上隅セル位置を基準として設定(列見出し「コード」のセル位置)
  Set rngList = Worksheets("Sheet1").Cells(1, "A")
  With rngList
    'データ行数を取得
    lngRows = .Offset(65536 - .Row).End(xlUp).Row - .Row
    'データが無い場合
    If lngRows <= 0 Then
      strProm = "データが有りません"
      GoTo Wayout
    End If
  End With
  
  '集計表を作成
  'データListの最終行まで繰り返し
  For i = 1 To lngRows
    '1行分データを配列に取得
    vntData = rngList.Offset(i).Resize(, 2).Value
    'コードがどの階級に属するか探索
    lngFound = BinarySearch(vntData(1, 1), vntMark, lngUnder)
    'そのコード其の物の値が無い場合
    If lngFound < 0 Then
      'そのコードの値を、超えない最大値の行を指定
      lngFound = lngUnder
    End If
    '指定行に値段を加算
    vntResult(lngFound, 1) = vntResult(lngFound, 1) + vntData(1, 2)
  Next i
  
  '画面更新を停止
'  Application.ScreenUpdating = False
  
  With rngResult
    '集計結果を出力
    .Offset(1).Resize(UBound(vntResult, 1)).Value = vntResult
  End With
  
  strProm = "処理が完了しました"
  
Wayout:
  
  '画面更新を再開
  Application.ScreenUpdating = True
  
  Set rngList = Nothing
  Set rngResult = Nothing
  
  MsgBox strProm, vbInformation
  
End Sub

Private Function BinarySearch(ByVal vntKey As Variant, _
              ByVal vntScope As Variant, _
              Optional lngUnder As Long = -1, _
              Optional lngOver As Long = -1) As Long

'  二進探索

  Dim lngLow As Long
  Dim lngHigh As Long
  Dim lngMiddle As Long
  
  lngLow = LBound(vntScope, 1)
  lngHigh = UBound(vntScope, 1)
  
  Do Until lngLow > lngHigh
    lngMiddle = (lngLow + lngHigh) \ 2
    Select Case vntScope(lngMiddle, 1)
      Case Is < vntKey
        lngLow = lngMiddle + 1
      Case Is > vntKey
        lngHigh = lngMiddle - 1
      Case Is = vntKey
        lngLow = lngMiddle + 1
        lngHigh = lngMiddle - 1
    End Select
  Loop
  
  If lngLow = lngHigh + 2 Then
    BinarySearch = lngMiddle
  Else
    BinarySearch = -1
  End If
  
  lngUnder = lngHigh
  lngOver = lngLow

End Function

【36494】Re:コードによる集計をVBAで行う方法
お礼  mero  - 06/4/1(土) 21:55 -

引用なし
パスワード
   ▼Hirofumi さん:
>もう見て居ないかな?
>
>Sheet1に以下の様なデータが有るとします
>
>    A    B
>1   コード 値段
>2   20   710
>3   37   785
>4   36   527
>5   29   521
>6   83   394
>7   79   561
>8   30   493
>9    ・   ・
>10   ・   ・
>
>Sheet2に以下の様な集計表が有るとします
>
>   A    B
>1   以上  合計
>2   1    
>3   11    
>4   21    
>5   31    
>6   41    
>7   51    
>8   61    
>9   71    
>10   81    
>11   91    
>
>以下のコードを実行すると、
>集計表のB2には、1以上11未満のコードに対する、値段の合計が入ります
>同様に、B3には、11以上21未満のコードに対する、値段の合計が入ります
>
>Option Explicit
>
>Public Sub Sample()
>
>  Dim i As Long
>  Dim lngRows As Long
>  Dim rngList As Range
>  Dim vntData As Variant
>  Dim vntMark As Variant
>  Dim lngFound As Long
>  Dim lngUnder As Long
>  Dim rngResult As Range
>  Dim strProm As String
>  
>  '結果出力基準位置を設定
>  Set rngResult = Worksheets("Sheet2").Cells(1, "B")
>  '集計コードの階級表に位置を配列に取得
>  With rngResult.Offset(, -1)
>    'データ行数を取得
>    lngRows = .Offset(65536 - .Row).End(xlUp).Row - .Row
>    'データが無い場合
>    If lngRows <= 0 Then
>      strProm = "階級表が有りません"
>      GoTo Wayout
>    End If
>    '階級を配列に取得
>    vntMark = .Offset(1).Resize(lngRows).Value
>    '結果出力用配列を確保
>    ReDim vntResult(1 To lngRows, 1 To 1)
>  End With
>  
>  'データListの左上隅セル位置を基準として設定(列見出し「コード」のセル位置)
>  Set rngList = Worksheets("Sheet1").Cells(1, "A")
>  With rngList
>    'データ行数を取得
>    lngRows = .Offset(65536 - .Row).End(xlUp).Row - .Row
>    'データが無い場合
>    If lngRows <= 0 Then
>      strProm = "データが有りません"
>      GoTo Wayout
>    End If
>  End With
>  
>  '集計表を作成
>  'データListの最終行まで繰り返し
>  For i = 1 To lngRows
>    '1行分データを配列に取得
>    vntData = rngList.Offset(i).Resize(, 2).Value
>    'コードがどの階級に属するか探索
>    lngFound = BinarySearch(vntData(1, 1), vntMark, lngUnder)
>    'そのコード其の物の値が無い場合
>    If lngFound < 0 Then
>      'そのコードの値を、超えない最大値の行を指定
>      lngFound = lngUnder
>    End If
>    '指定行に値段を加算
>    vntResult(lngFound, 1) = vntResult(lngFound, 1) + vntData(1, 2)
>  Next i
>  
>  '画面更新を停止
>'  Application.ScreenUpdating = False
>  
>  With rngResult
>    '集計結果を出力
>    .Offset(1).Resize(UBound(vntResult, 1)).Value = vntResult
>  End With
>  
>  strProm = "処理が完了しました"
>  
>Wayout:
>  
>  '画面更新を再開
>  Application.ScreenUpdating = True
>  
>  Set rngList = Nothing
>  Set rngResult = Nothing
>  
>  MsgBox strProm, vbInformation
>  
>End Sub
>
>Private Function BinarySearch(ByVal vntKey As Variant, _
>              ByVal vntScope As Variant, _
>              Optional lngUnder As Long = -1, _
>              Optional lngOver As Long = -1) As Long
>
>'  二進探索
>
>  Dim lngLow As Long
>  Dim lngHigh As Long
>  Dim lngMiddle As Long
>  
>  lngLow = LBound(vntScope, 1)
>  lngHigh = UBound(vntScope, 1)
>  
>  Do Until lngLow > lngHigh
>    lngMiddle = (lngLow + lngHigh) \ 2
>    Select Case vntScope(lngMiddle, 1)
>      Case Is < vntKey
>        lngLow = lngMiddle + 1
>      Case Is > vntKey
>        lngHigh = lngMiddle - 1
>      Case Is = vntKey
>        lngLow = lngMiddle + 1
>        lngHigh = lngMiddle - 1
>    End Select
>  Loop
>  
>  If lngLow = lngHigh + 2 Then
>    BinarySearch = lngMiddle
>  Else
>    BinarySearch = -1
>  End If
>  
>  lngUnder = lngHigh
>  lngOver = lngLow
>
>End Function
もう一度みてすごく良かったです。
こんなに、詳しくまたご親切にご教示いただき感謝いたします。
ExcelVBAの初心者ですので実際に要求されるものをどのように組み立ててよいか
理解できない点がありました。
大変参考になります。
貴重なお時間を割いてくださり誠に感謝にたえません。

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