Excel VBA質問箱 IV

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

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


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

【49539】月間集計 hiro 07/6/9(土) 17:35 質問[未読]
【49541】Re:月間集計 Hirofumi 07/6/10(日) 0:39 回答[未読]
【49543】コード修正して下さい Hirofumi 07/6/10(日) 8:17 回答[未読]
【49545】Re:コード修正して下さい Hirofumi 07/6/10(日) 13:20 回答[未読]
【49552】Re:コード修正して下さい hiro 07/6/10(日) 21:32 質問[未読]
【49554】Re:コード修正して下さい Hirofumi 07/6/10(日) 23:43 回答[未読]
【49555】Re:コード修正して下さい hiro 07/6/11(月) 0:52 発言[未読]
【49556】Re:コード修正して下さい Hirofumi 07/6/11(月) 1:24 回答[未読]
【49557】2表出力 Hirofumi 07/6/11(月) 2:49 回答[未読]
【49558】Re:2表出力 Hirofumi 07/6/11(月) 2:51 回答[未読]
【49581】Re:2表出力 hiro 07/6/11(月) 23:32 質問[未読]
【49601】Re:2表出力 Hirofumi 07/6/12(火) 14:49 回答[未読]
【49653】Re:2表出力 hiro 07/6/14(木) 19:10 発言[未読]
【49654】Re:2表出力 Hirofumi 07/6/14(木) 20:57 回答[未読]
【49667】Re:2表出力 hiro 07/6/15(金) 1:29 発言[未読]
【49680】Re:2表出力 Hirofumi 07/6/15(金) 19:57 回答[未読]
【49704】Re:2表出力 hiro 07/6/17(日) 23:27 発言[未読]
【49713】Re:2表出力 Hirofumi 07/6/18(月) 12:13 回答[未読]
【49714】Re:2表出力 Hirofumi 07/6/18(月) 12:16 回答[未読]

【49539】月間集計
質問  hiro  - 07/6/9(土) 17:35 -

引用なし
パスワード
   いつも教えて頂きありがとうございます
以前オートフィルタの件で hirohumi様よりサンプルを頂き日々使わしております
この度少し変更したく思いあつかましくまた質問させてください

シート1(List1)

日付    店舗    項目    1係    2係    3係
20070401    本店    売上    1    1    1
20070401    本店    差益    2    2    2
20070401    本店    在庫    3    3    3
20070401    支店A    売上    4    4    4
20070401    支店A    差益    5    5    5
20070401    支店A    在庫    6    6    6
20070401    支店B    売上    7    7    7
20070401    支店B    差益    8    8    8
20070401    支店B    在庫    9    9    9
20070402    本店    売上    1    1    1
20070402    本店    差益    2    2    2
20070402    本店    在庫    3    3    3
20070402    支店A    売上    4    4    4
20070402    支店A    差益    5    5    5
20070402    支店A    在庫    6    6    6
20070402    支店B    売上    7    7    7
20070402    支店B    差益    8    8    8
20070402    支店B    在庫    9    9    9

日々のデータをユーザーフォームから上記のように転記しております
これにオートフィルターで別シートに日にちと店舗を指定して抽出しております
これに売上と差益の累計値も同時に表示させたいと思っております

4月2日の本店を抽出するとシート2(List2)

20070402                
本店                

店舗    本店    本店        
項目    売上    差益    売上累計    差益累計
1係    1    2    2     4
2係    1    2     2    4
3係    1    2    2     4


無理でしょうか?よろしくおねがいいたします
シート1のデータは3店舗×3項目で1日9行が1年分あります
係りは30係あります
現在上の様に使用しておりますがデータを2年分2006年4月〜2008年3月31日迄入力いたしますと当然ですが前年分も累計されてしまいます、条件設定で入力した日の当年、当月だけの累計を表示させたいのです(20070420を入力 2007年4月1日〜2007年4月20日の累計値)が、頂いたサンプルの修正で私でも可能でしたらお教えくださいよろしくお願いいたします
現在使わしていただいているコードは下記です
Public Sub Sample5()

  '◆Listのデータ列数(A列〜AG列)
  Const clngColumns As Long = 33
  '◆「1係」の列位置を指定(基準セル位置からの列Offset:基準がA1で「1係」がD列なら3)
  Const clngBegin As Long = 3
  '◆「日付」の列位置を指定(基準セル位置からの列Offset:基準がA1で「日付」がA列なら0)
  Const clngDate As Long = 0
  '◆「店舗」の列位置を指定(基準セル位置からの列Offset:基準がA1で「店舗」がB列なら1)
  Const clngKey As Long = 1
  '◆「項目」の列位置を指定(基準セル位置からの列Offset:基準がA1で「項目」がC列なら2)
  Const clngItem As Long = 2
 
  Dim i As Long
  Dim lngRows As Long
  Dim rngList As Range
  Dim rngResult As Range
  Dim rngWork As Range
  Dim vntResult As Variant
  Dim vntKeyA1 As Variant
  Dim vntKeyB1 As Variant
  Dim vntItem As Variant
  Dim strProm As String

  '◆Listの先頭セル位置を基準とする(列見出し「日付」のセル位置)
  Set rngList = Worksheets("List1").Cells(1, "A")

  '◆List2の先頭セル位置を基準とする(列見出し「日付」のセル位置)
  Set rngResult = Worksheets("List2").Cells(5, "A")
  Set rngResult = Worksheets("List2").Cells(5, "B")
 
  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益")
 
  With rngList
    '行数の取得
    lngRows = .CurrentRegion.Rows.Count - 1
    If lngRows <= 0 Then
      strProm = "データが有りません"
      GoTo Wayout
    End If
  End With
 
  '画面更新を停止
  Application.ScreenUpdating = False
 
  With rngResult
    '「日付」の抽出条件を取得
    vntKeyA1 = .Parent.Cells(2, 2).Value
    '「店舗」の抽出条件を取得
    vntKeyB1 = .Parent.Cells(3, 2).Value
    '先回の結果をクリア (結果表示先List2のA:AF)
    .CurrentRegion.ClearContents
  End With
 
  '作業用シートを追加
  With Worksheets
    Set rngWork = .Add(After:=.Item(.Count)).Cells(1, "A")
  End With

  With rngWork
    '列見出しを貼り付け
    rngList.Resize(, clngColumns).Copy Destination:=.Item(1)
    'AdvancedFilter条件範囲の列見出しの出力
    With .Offset(, clngColumns)
      .Offset(, 1).Value = rngList.Offset(, clngDate).Value
      .Offset(, 2).Value = rngList.Offset(, clngKey).Value
      .Offset(, 3).Value = rngList.Offset(, clngItem).Value
    End With
    '集計結果の格納用配列を確保
    ReDim vntResult(UBound(vntItem))
    '☆KeyA1の値以下の日付で、KeyB1の店舗で
    '日付条件を出力
    .Offset(1, clngColumns + 1).Value = "<=" & vntKeyA1
    '店舗条件を出力
    .Offset(1, clngColumns + 2).Value = vntKeyB1
    '売上、差益を抽出し、集計
    For i = 0 To UBound(vntItem)
      '項目条件を出力
      .Offset(1, clngColumns + 3).Value = vntItem(i)
      'AdvancedFilterを実行
      DoFilter rngList.CurrentRegion, .Offset(, clngColumns + 1) _
                  .Resize(2, 3), .Resize(, clngColumns)
      'データ行数を取得
      lngRows = .CurrentRegion.Rows.Count
      '売上データを集計
      With .Offset(lngRows, clngBegin).Resize(, clngColumns - clngBegin)
        '範囲に関数を設定
        .FormulaR1C1 = "=Sum(R[-" & lngRows & "]C:R[-1]C)"
      End With
      '範囲を配列に取得
      vntResult(i) = .Offset(lngRows).Resize(, clngColumns).Value
      vntResult(i)(1, clngItem + 1) = vntItem(i) & "累計"
    Next i
    '☆KeyA1の値の日付で、KeyB1の店舗のデータを抽出
    '日付条件を出力
    .Offset(1, clngColumns + 1).Value = vntKeyA1
    'AdvancedFilterを実行
    DoFilter rngList.CurrentRegion, .Offset(, clngColumns + 1) _
                .Resize(2, 2), .Resize(, clngColumns)
    'データ行数を取得
    lngRows = .CurrentRegion.Rows.Count
    '抽出データがない場合
    If lngRows = 1 Then
      strProm = "抽出条件に一致するレコードが有りません"
      rngResult.Parent.Activate
      GoTo Wayout
    End If
    '売上、差益データを出力
    For i = 0 To UBound(vntItem)
      .Offset(lngRows + i).Resize(, clngColumns).Value = vntResult(i)
    Next i
    '結果範囲をCopy
    Application.Intersect(.CurrentRegion, .CurrentRegion.Offset(, 1)).Copy
  End With
 
  With rngResult
    '出力結果の下に行列を入れ替え値のみPaste
    .PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=True
    Application.CutCopyMode = False
    .Parent.Activate
    .Select
  End With
 
  strProm = "処理が完了しました"
 
Wayout:

  '作業シートを削除
  If Not rngWork Is Nothing Then
    Application.DisplayAlerts = False
    rngWork.Parent.Delete
    Application.DisplayAlerts = True
  End If
 
  '画面更新を再開
  Application.ScreenUpdating = True
 
  Set rngWork = Nothing
  Set rngList = Nothing
  Set rngResult = Nothing
 
  MsgBox strProm, vbInformation
  
End Sub

Private Sub DoFilter(rngScope As Range, _
          rngCriteria As Range, _
          rngCopyTo As Range)
 
'  AdvancedFilterの実行

  rngScope.AdvancedFilter _
      Action:=xlFilterCopy, _
      CriteriaRange:=rngCriteria, _
      CopyToRange:=rngCopyTo, _
      Unique:=False
  
End Sub

【49541】Re:月間集計
回答  Hirofumi  - 07/6/10(日) 0:39 -

引用なし
パスワード
   集計が正しく行われているか善く験算して見て下さい

Option Explicit

Public Sub Sample6()

  '◆Listのデータ列数(A列〜AG列)
  Const clngColumns As Long = 33
  '◆「1係」の列位置を指定(基準セル位置からの列Offset:基準がA1で「1係」がD列なら3)
  Const clngBegin As Long = 3
  '◆「日付」の列位置を指定(基準セル位置からの列Offset:基準がA1で「日付」がA列なら0)
  Const clngDate As Long = 0
  '◆「店舗」の列位置を指定(基準セル位置からの列Offset:基準がA1で「店舗」がB列なら1)
  Const clngKey As Long = 1
  '◆「項目」の列位置を指定(基準セル位置からの列Offset:基準がA1で「項目」がC列なら2)
  Const clngItem As Long = 2
  
  Dim i As Long
  Dim lngRows As Long
  Dim rngList As Range
  Dim rngResult As Range
  Dim rngWork As Range
  Dim vntResult As Variant
  Dim vntKeyA1 As Variant
  Dim vntKeyB1 As Variant
  Dim vntTop As Variant
  Dim vntItem As Variant
  Dim strProm As String

  '◆Listの先頭セル位置を基準とする(列見出し「日付」のセル位置)
  Set rngList = Worksheets("List").Cells(1, "A")

  '◆List2の先頭セル位置を基準とする(列見出し「日付」のセル位置)
  Set rngResult = Worksheets("List2").Cells(5, "B")
  
  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益")
  
  With rngList
    '行数の取得
    lngRows = .CurrentRegion.Rows.Count - 1
    If lngRows <= 0 Then
      strProm = "データが有りません"
      GoTo Wayout
    End If
  End With
  
  '画面更新を停止
  Application.ScreenUpdating = False
  
  With rngResult
    '「日付」の抽出条件を取得
    vntKeyA1 = .Parent.Cells(2, 2).Value
    '年度先頭の日付を取得
    vntTop = DateValue(Left(vntKeyA1, 4) _
          & "/" & Mid(vntKeyA1, 5, 2) _
          & "/" & Right(vntKeyA1, 2))
    If Month(vntTop) <= 3 Then
      vntTop = Year(vntTop) - 1
    Else
      vntTop = Year(vntTop)
    End If
    vntTop = ">=" & vntTop & "0401"
    '「店舗」の抽出条件を取得
    vntKeyB1 = .Parent.Cells(3, 2).Value
    '先回の結果をクリア (結果表示先List2のA:AF)
    .CurrentRegion.ClearContents
  End With
  
  '作業用シートを追加
  With Worksheets
    Set rngWork = .Add(After:=.Item(.Count)).Cells(1, "A")
  End With

  With rngWork
    '列見出しを貼り付け
    rngList.Resize(, clngColumns).Copy Destination:=.Item(1)
    'AdvancedFilter条件範囲の列見出しの出力
    With .Offset(, clngColumns)
      .Offset(, 1).Resize(, 2).Value _
          = rngList.Offset(, clngDate).Value
      .Offset(, 3).Value = rngList.Offset(, clngKey).Value
      .Offset(, 4).Value = rngList.Offset(, clngItem).Value
    End With
    '集計結果の格納用配列を確保
    ReDim vntResult(UBound(vntItem))
    '☆KeyA1の値以下の日付で、KeyB1の店舗で
    '日付条件を出力
    .Offset(1, clngColumns + 1).Value = vntTop
    .Offset(1, clngColumns + 2).Value = "<=" & vntKeyA1
    '店舗条件を出力
    .Offset(1, clngColumns + 3).Resize(UBound(vntItem) + 1).Value _
        = "=" & """=" & vntKeyB1 & """"
    '売上、差益を抽出し、集計
    For i = 0 To UBound(vntItem)
      '項目条件を出力
      .Offset(1, clngColumns + 4).Value _
          = "=" & """=" & vntItem(i) & """"
      'AdvancedFilterを実行
      DoFilter rngList.CurrentRegion, .Offset(, clngColumns + 1) _
                  .Resize(2, 4), .Resize(, clngColumns)
      'データ行数を取得
      lngRows = .CurrentRegion.Rows.Count
      '売上データを集計
      With .Offset(lngRows, clngBegin).Resize(, clngColumns - clngBegin)
        '範囲に関数を設定
        .FormulaR1C1 = "=Sum(R[-" & (lngRows - 1) & "]C:R[-1]C)"
      End With
      '範囲を配列に取得
      vntResult(i) = .Offset(lngRows).Resize(, clngColumns).Value
      vntResult(i)(1, clngItem + 1) = vntItem(i) & "累計"
    Next i
    '☆KeyA1の値の日付で、KeyB1の店舗のデータを抽出
    '日付条件を出力
    .Offset(1, clngColumns + 2).Resize( _
          UBound(vntItem) + 1).Value = vntKeyA1
    For i = 0 To UBound(vntItem)
      .Offset(1 + i, clngColumns + 4).Value _
          = "=" & """=" & vntItem(i) & """"
    Next i
    'AdvancedFilterを実行
    DoFilter rngList.CurrentRegion, .Offset(, clngColumns + 2) _
        .Resize(UBound(vntItem) + 1 + 1, 3), .Resize(, clngColumns)
    'データ行数を取得
    lngRows = .CurrentRegion.Rows.Count
    '抽出データがない場合
    If lngRows = 1 Then
      strProm = "抽出条件に一致するレコードが有りません"
      rngResult.Parent.Activate
      GoTo Wayout
    End If
    '売上、差益データを出力
    For i = 0 To UBound(vntItem)
      .Offset(lngRows + i).Resize(, _
          clngColumns).Value = vntResult(i)
    Next i
    '結果範囲をCopy
    Application.Intersect(.CurrentRegion, _
        .CurrentRegion.Offset(, 1)).Copy
  End With
  
  With rngResult
    '出力結果の下に行列を入れ替え値のみPaste
    .PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=True
    Application.CutCopyMode = False
    .Parent.Activate
    .Select
  End With
  
  strProm = "処理が完了しました"
  
Wayout:

  '作業シートを削除
  If Not rngWork Is Nothing Then
    Application.DisplayAlerts = False
    rngWork.Parent.Delete
    Application.DisplayAlerts = True
  End If
  
  '画面更新を再開
  Application.ScreenUpdating = True
  
  Set rngWork = Nothing
  Set rngList = Nothing
  Set rngResult = Nothing
   
  MsgBox strProm, vbInformation
     
End Sub

Private Sub DoFilter(rngScope As Range, _
          rngCriteria As Range, _
          rngCopyTo As Range)
  
'  AdvancedFilterの実行

  rngScope.AdvancedFilter _
      Action:=xlFilterCopy, _
      CriteriaRange:=rngCriteria, _
      CopyToRange:=rngCopyTo, _
      Unique:=False
    
End Sub

【49543】コード修正して下さい
回答  Hirofumi  - 07/6/10(日) 8:17 -

引用なし
パスワード
   現状では、B2に有る抽出日付が日付と認められない文字列の場合
エラーでブレイクするのが解りました
因って、以下の部分を修正して下さい

以下の行、全てを

  With rngResult
    '「日付」の抽出条件を取得
    vntKeyA1 = .Parent.Cells(2, 2).Value
    '年度先頭の日付を取得
    vntTop = DateValue(Left(vntKeyA1, 4) _
          & "/" & Mid(vntKeyA1, 5, 2) _
          & "/" & Right(vntKeyA1, 2))
    If Month(vntTop) <= 3 Then
      vntTop = Year(vntTop) - 1
    Else
      vntTop = Year(vntTop)
    End If
    vntTop = ">=" & vntTop & "0401"
    '「店舗」の抽出条件を取得
    vntKeyB1 = .Parent.Cells(3, 2).Value
    '先回の結果をクリア (結果表示先List2のA:AF)
    .CurrentRegion.ClearContents
  End With

以下の行、全てに差し替えて下さい
  
  With rngResult
    '「日付」の抽出条件を取得
    vntKeyA1 = .Parent.Cells(2, 2).Value
    '「店舗」の抽出条件を取得
    vntKeyB1 = .Parent.Cells(3, 2).Value
    '先回の結果をクリア (結果表示先List2のA:AF)
    .CurrentRegion.ClearContents
  End With
  '年度先頭の日付を取得
  vntTop = Left(vntKeyA1, 4) & "/" & Mid(vntKeyA1, 5, 2) _
          & "/" & Right(vntKeyA1, 2)
  '日付の確認
  If Not IsDate(vntTop) Then
    strProm = "抽出日付が、日付と認められません"
    GoTo Wayout
  End If
  'シリアル値に変換
  vntTop = DateValue(vntTop)
  '年を調整
  If Month(vntTop) <= 3 Then
    vntTop = Year(vntTop) - 1
  Else
    vntTop = Year(vntTop)
  End If
  vntTop = ">=" & vntTop & "0401"

以上

【49545】Re:コード修正して下さい
回答  Hirofumi  - 07/6/10(日) 13:20 -

引用なし
パスワード
   >当然ですが前年分も累計されてしまいます、条件設定で入力した日の
>当年、当月だけの累計を表示させたいのです(20070420を入力 2007年4月1日〜2007年4月20日の累計値)が、
>頂いたサンプルの修正で私でも可能でしたらお教えくださいよろしくお願いいたします

あれ?、勘違いしたかな?
当年、当月と言うなら

20070520なら、累計は、5月1日〜5月20日
20070620なら、累計は、6月1日〜6月20日

と言う事ですか?

それなら、以下の部分を


  '年度を調整
  vntTop = DateValue(vntTop)
  If Month(vntTop) <= 3 Then
    vntTop = Year(vntTop) - 1
  Else
    vntTop = Year(vntTop)
  End If
  vntTop = ">=" & vntTop & "0401"

を、以下の様に変更して下さい

  '年度を調整
  vntTop = DateValue(vntTop)
  vntTop = ">=" & Format(DateSerial(Year(vntTop), _
            Month(vntTop), 1), "yyyymmdd")

以上

【49552】Re:コード修正して下さい
質問  hiro  - 07/6/10(日) 21:32 -

引用なし
パスワード
   ▼Hirofumi さん
修正頂きありがとうございます その節は大変御世話になりました
頂いたサンプルは快適に動作して毎日使わして頂いております
さてこの度はまたまたご無理を言ってすいません

>20070520なら、累計は、5月1日〜5月20日
>20070620なら、累計は、6月1日〜6月20日
>
>と言う事ですか?
はい そのとおりです
>  '年度を調整
>  vntTop = DateValue(vntTop)
>  vntTop = ">=" & Format(DateSerial(Year(vntTop), _
>            Month(vntTop), 1), "yyyymmdd")で再度験算してみます
もう一つお聞きしたいのですが、もし抽出項目を増やしたいときの修正なのですが
? 売上、差益の他にあと仕入、と在庫の2項目を同じように累計値も抽出する方法を、お時間のあるときに教えていただきたくお願いできますでしょうか

験算結果、のちほどご報告致します。

【49554】Re:コード修正して下さい
回答  Hirofumi  - 07/6/10(日) 23:43 -

引用なし
パスワード
   >もう一つお聞きしたいのですが、もし抽出項目を増やしたいときの修正なのですが
>? 売上、差益の他にあと仕入、と在庫の2項目を同じように累計値も抽出する方法を、
>お時間のあるときに教えていただきたくお願いできますでしょうか

此れは、多分そう言う事が有るだろうと思って、
今回の修正で簡単に出来るように直して有ります
ただし、項目の並ぶ順番は、元のListの順番に依存していますのでそこが問題です?

日付   店舗   項目   1係
20060401 本店   売上    1
20060401 本店   差益    1
20060401 本店   仕入    1
20060401 本店   在庫    1

と元のレコードが並んでいる場合

  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益")

上記を

  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益", "仕入", "在庫")

とすれば

項目 売上 差益 仕入 在庫 売上累計 差益累計 仕入累計 在庫累計

と並びますが?

  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益", "在庫", "仕入")

とすると

項目 売上 差益 仕入 在庫 売上累計 差益累計 在庫累計 仕入累計

と成りますので気をつけて下さい

【49555】Re:コード修正して下さい
発言  hiro  - 07/6/11(月) 0:52 -

引用なし
パスワード
   ▼Hirofumi さん
早速のご回答ありがとうございます
さすがにHirofumi さんご指示どおり文字列設定すると成功いたしました
先ほどの件も験算の結果問題ありませんでした。ありがとうございます
>ただし、項目の並ぶ順番は、元のListの順番に依存していますのでそこが問題です?
>
>日付   店舗   項目   1係
>20060401 本店   売上    1
>20060401 本店   差益    1
>20060401 本店   仕入    1
>20060401 本店   在庫    1
入力は、この順番で行いますので大丈夫です ご配慮ありがとうございます。

それと聞き忘れたのですが、前年の同日を(C2)に(店舗は同じ)入力してlist2の(L5)から前年のデータを、連続してと、言いますか、同時に抽出するとしたら

'◆List2の先頭セル位置を基準とする(列見出し「日付」のセル位置)
  Set rngResult = Worksheets("List2").Cells(5, "B")を (5,"L")に変更

'「日付」の抽出条件を取得
    vntKeyA1 = .Parent.Cells(2, 2).Valueを (2,3).Valueに変更で
With rngResult
    '出力結果の下に行列を入れ替え値のみPaste
    .PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=True
    Application.CutCopyMode = False
    .Parent.Activate
    .Select
  End With
以下にコピーではだめでしょうか?
Wayout:以下でエラーになるよにも思いまして
「日付」の抽出条件を取得と出力設定を上記のように変更してもう一つマクロ登録するほうが無難でしょうか?
素人の質問ですいません教えて頂けますでしょうか

【49556】Re:コード修正して下さい
回答  Hirofumi  - 07/6/11(月) 1:24 -

引用なし
パスワード
   >それと聞き忘れたのですが、前年の同日を(C2)に(店舗は同じ)入力してlist2の(L5)から前年のデータを、連続してと、言いますか、同時に抽出するとしたら
>
>'◆List2の先頭セル位置を基準とする(列見出し「日付」のセル位置)
>  Set rngResult = Worksheets("List2").Cells(5, "B")を (5,"L")に変更
>
> '「日付」の抽出条件を取得
>    vntKeyA1 = .Parent.Cells(2, 2).Valueを (2,3).Valueに変更で
>With rngResult
>    '出力結果の下に行列を入れ替え値のみPaste
>    .PasteSpecial Paste:=xlPasteValues, _
>        Operation:=xlNone, _
>        SkipBlanks:=False, Transpose:=True
>    Application.CutCopyMode = False
>    .Parent.Activate
>    .Select
>  End With
>以下にコピーではだめでしょうか?
>Wayout:以下でエラーになるよにも思いまして

小手先で修正しようとしても、多分無理だと思います

>「日付」の抽出条件を取得と出力設定を上記のように変更してもう一つマクロ登録するほうが無難でしょうか?

これは、全く同じコードが2つに成るので無駄なのと、
例えば今回の様に、仕様の一部変更、詰まりメンテナンスの上で得策では無いと思います

もし、同様の表を当年分と前年分とを並べるだけなら、
必要な、日付、店名、その他を引数にして、別のコードで外から与えて2度回す方法を取った方がいいですね
それで良ければ、多分、それほど大変では無いと思いますよ?

【49557】2表出力
回答  Hirofumi  - 07/6/11(月) 2:49 -

引用なし
パスワード
   こんなかな?

Option Explicit

Public Sub Main()
  
  '◆Listのデータ列数(A列〜AG列)
  Const clngColumns As Long = 33
  '◆「日付」の列位置を指定(基準セル位置からの列Offset:基準がA1で「日付」がA列なら0)
  Const clngDate As Long = 0
  '◆「店舗」の列位置を指定(基準セル位置からの列Offset:基準がA1で「店舗」がB列なら1)
  Const clngKey As Long = 1
  '◆「項目」の列位置を指定(基準セル位置からの列Offset:基準がA1で「項目」がC列なら2)
  Const clngItem As Long = 2
  
  Dim lngRows As Long
  Dim rngList As Range
  Dim rngResult As Range
  Dim rngWork As Range
  Dim vntKeyA1 As Variant
  Dim vntKeyA2 As Variant
  Dim vntKeyB1 As Variant
  Dim strProm As String

  '◆Listの先頭セル位置を基準とする(列見出し「日付」のセル位置)
  Set rngList = Worksheets("List").Cells(1, "A")

  '◆List2の先頭セル位置を基準とする(列見出し「店舗」のセル位置)
  Set rngResult = Worksheets("List2").Cells(5, "B")

  With rngList
    '行数の取得
    lngRows = .CurrentRegion.Rows.Count - 1
    If lngRows <= 0 Then
      strProm = "データが有りません"
      GoTo Wayout
    End If
  End With
  
  With rngResult
    '「日付」の抽出条件を取得
    vntKeyA1 = .Parent.Cells(2, 2).Value
    vntKeyA2 = .Parent.Cells(2, 3).Value
    '「店舗」の抽出条件を取得
    vntKeyB1 = .Parent.Cells(3, 2).Value
    '先回の結果をクリア (結果表示先List2のA:AF)
    .CurrentRegion.ClearContents
  End With
  '日付の確認
  strProm = "抽出日付が、日付と認められません"
  If Not IsDate(Left(vntKeyA1, 4) _
      & "/" & Mid(vntKeyA1, 5, 2) _
          & "/" & Right(vntKeyA1, 2)) Then
    GoTo Wayout
  End If
  If Not IsDate(Left(vntKeyA2, 4) _
      & "/" & Mid(vntKeyA2, 5, 2) _
          & "/" & Right(vntKeyA2, 2)) Then
    GoTo Wayout
  End If
  
  '画面更新を停止
'  Application.ScreenUpdating = False
  
  '作業用シートを追加
  With Worksheets
    Set rngWork = .Add(After:=.Item(.Count)).Cells(1, "A")
  End With
  With rngWork
    '列見出しを貼り付け
    rngList.Resize(, clngColumns).Copy Destination:=.Item(1)
    'AdvancedFilter条件範囲の列見出しの出力
    With .Offset(, clngColumns)
      .Offset(, 1).Resize(, 2).Value _
          = rngList.Offset(, clngDate).Value
      .Offset(, 3).Value = rngList.Offset(, clngKey).Value
      .Offset(, 4).Value = rngList.Offset(, clngItem).Value
    End With
  End With
  
  strProm = "抽出条件に一致するレコードが有りません"
  If Not AddUp(rngList, rngResult, _
      rngWork, vntKeyA1, vntKeyB1, clngColumns, clngItem) Then
    GoTo Wayout
  End If
  If Not AddUp(rngList, rngResult.Offset(, 10), _
      rngWork, vntKeyA2, vntKeyB1, clngColumns, clngItem) Then
    GoTo Wayout
  End If

  strProm = "処理が完了しました"
  
Wayout:

  '作業シートを削除
  If Not rngWork Is Nothing Then
    Application.DisplayAlerts = False
    rngWork.Parent.Delete
    Application.DisplayAlerts = True
  End If
  
  '画面更新を再開
  Application.ScreenUpdating = True
  
  Set rngWork = Nothing
  Set rngList = Nothing
  Set rngResult = Nothing
   
  MsgBox strProm, vbInformation
     
End Sub

Private Function AddUp(rngList As Range, rngResult As Range, _
            rngWork As Range, vntKeyA1 As Variant, _
            vntKeyB1 As Variant, lngColumns As Long, _
            lngItem As Long) As Boolean

  '◆「1係」の列位置を指定(基準セル位置からの列Offset:基準がA1で「1係」がD列なら3)
  Const clngBegin As Long = 3
  
  Dim i As Long
  Dim j As Long
  Dim lngRows As Long
  Dim vntResult As Variant
  Dim vntTop As Variant
  Dim vntItem As Variant

  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益", "仕入", "在庫")
  
  '年度先頭の日付を取得
  vntTop = Left(vntKeyA1, 4) & "/" & Mid(vntKeyA1, 5, 2) _
          & "/" & Right(vntKeyA1, 2)
  '年度を調整
  vntTop = DateValue(vntTop)
  vntTop = ">=" & Format(DateSerial(Year(vntTop), _
            Month(vntTop), 1), "yyyymmdd")
  AddUp = True
  With rngWork
    '集計結果の格納用配列を確保
    ReDim vntResult(UBound(vntItem))
    '☆KeyA1の値以下の日付で、KeyB1の店舗で
    '日付条件を出力
    .Offset(1, lngColumns + 1).Value = vntTop
    .Offset(1, lngColumns + 2).Value = "<=" & vntKeyA1
    '店舗条件を出力
    .Offset(1, lngColumns + 3).Resize(UBound(vntItem) + 1).Value _
        = "=" & """=" & vntKeyB1 & """"
    '売上、差益を抽出し、集計
    For i = 0 To UBound(vntItem)
      '項目条件を出力
      .Offset(1, lngColumns + 4).Value _
          = "=" & """=" & vntItem(i) & """"
      'AdvancedFilterを実行
      DoFilter rngList.CurrentRegion, .Offset(, lngColumns + 1) _
                  .Resize(2, 4), .Resize(, lngColumns)
      'データ行数を取得
      lngRows = .CurrentRegion.Rows.Count
      '売上データを集計
      With .Offset(lngRows, clngBegin).Resize(, lngColumns - clngBegin)
        '範囲に関数を設定
        .FormulaR1C1 = "=Sum(R[-" & (lngRows - 1) & "]C:R[-1]C)"
      End With
      '範囲を配列に取得
      vntResult(i) = .Offset(lngRows).Resize(, lngColumns).Value
      vntResult(i)(1, lngItem + 1) = vntItem(i) & "累計"
    Next i
    '☆KeyA1の値の日付で、KeyB1の店舗のデータを抽出
    '日付条件を出力
    .Offset(1, lngColumns + 2).Resize( _
          UBound(vntItem) + 1).Value = vntKeyA1
    For i = 0 To UBound(vntItem)
      .Offset(1 + i, lngColumns + 4).Value _
          = "=" & """=" & vntItem(i) & """"
    Next i
    'AdvancedFilterを実行
    DoFilter rngList.CurrentRegion, .Offset(, lngColumns + 2) _
        .Resize(UBound(vntItem) + 1 + 1, 3), .Resize(, lngColumns)
    'データ行数を取得
    lngRows = .CurrentRegion.Rows.Count
    '抽出データがない場合
    If lngRows = 1 Then
      AddUp = False
      rngResult.Parent.Activate
      Exit Function
    End If
    '抽出項目の整列
    vntTop = .Offset(1, lngItem).Resize(lngRows).Value
    For i = 1 To lngRows - 1
      For j = 0 To UBound(vntItem)
        If vntTop(i, 1) = vntItem(j) Then
          vntTop(i, 1) = j
          Exit For
        End If
      Next j
    Next i
    .Offset(1, lngColumns).Resize(lngRows - 1).Value = vntKeyB1
    .Offset(1).Resize(lngRows - 1, lngColumns + 1).Sort _
        Key1:=.Offset(1, lngColumns), Order1:=xlAscending, _
        Header:=xlNo, OrderCustom:=1, _
        MatchCase:=False, Orientation:=xlTopToBottom, _
        SortMethod:=xlStroke
    .Offset(1, lngColumns).EntireColumn.ClearContents
    '売上、差益データを出力
    For i = 0 To UBound(vntItem)
      .Offset(lngRows + i).Resize(, _
          lngColumns).Value = vntResult(i)
    Next i
    '結果範囲をCopy
    Application.Intersect(.CurrentRegion, _
        .CurrentRegion.Offset(, 1)).Copy
  End With
  
  With rngResult
    '出力結果の下に行列を入れ替え値のみPaste
    .PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=True
    Application.CutCopyMode = False
    .Parent.Activate
    .Select
  End With
     
End Function

Private Sub DoFilter(rngScope As Range, _
          rngCriteria As Range, _
          rngCopyTo As Range)
  
'  AdvancedFilterの実行

  rngScope.AdvancedFilter _
      Action:=xlFilterCopy, _
      CriteriaRange:=rngCriteria, _
      CopyToRange:=rngCopyTo, _
      Unique:=False
    
End Sub

【49558】Re:2表出力
回答  Hirofumi  - 07/6/11(月) 2:51 -

引用なし
パスワード
   尚、表の売上、差益等の出力順は、整列を入れましたので

  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益", "仕入", "在庫")

の並び順に成ります

【49581】Re:2表出力
質問  hiro  - 07/6/11(月) 23:32 -

引用なし
パスワード
   ▼Hirofumi さん
昨日は遅くまでありがとうございます 今朝拝見し早速会社で実行させて頂きました。希望のとおり2007年の横に前年の表を出力できました。ありがとうございます
最後に後一お聞きしたいのですが
List2に出力した累計値と同じ値を別の表にも入力しているのですがせっかく出力して頂いたのでファイル一つにして "部門"と言うsheetを挿入してcopyしょうと思っています。
店舗 本店で出力した時の値のcopy先はsheet部門の 売上がE列 差益H列 仕入L列 在庫O列 で行が下記のように不規則なのですが
1係    60
2係    63
3係    66
4係    81
5係    69
6係    93
7係    72
8係    75
9係    38
10係    
11係    5
12係    41
13係    
14係    20
15係    23
16係    8
17係    26
18係    29
19係    44
20係    47
21係    90
22係    50
23係    11
24係    14
25係    32
26係    
27係    
28係    84
29係    
30係    96

With rngResult
    '出力結果の下に行列を入れ替え値のみPaste
    .PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=True
    Application.CutCopyMode = False
    .Parent.Activate
    .Select
  End With
   With Worksheets("部門")
     .Range("E60").Value = Worksheets("List2").Range("E7").Value
     .Range("E63").Value = Worksheets("List2").Range("E8").Value

 End With
 
  strProm = "処理が完了しました"

こんなかんじで続けていけばいいでしょうか?素人のコードすいません
(10,13,26,27,29係)は本店にデーターなしです

【49601】Re:2表出力
回答  Hirofumi  - 07/6/12(火) 14:49 -

引用なし
パスワード
   >  End With
>   With Worksheets("部門")
>     .Range("E60").Value = Worksheets("List2").Range("E7").Value
>     .Range("E63").Value = Worksheets("List2").Range("E8").Value
>
> End With
> 
>  strProm = "処理が完了しました"
>
>こんなかんじで続けていけばいいでしょうか?素人のコードすいません
>(10,13,26,27,29係)は本店にデーターなしです

物は試し、データのCopyを取って、試して下さい
どんな不都合が出るか?、もしかしたら上手くいくかも?
私も考えて見ますが?
コードいじって、試して見て、エラーを出して、どうしたら上手くいくか考える
これを繰り返さないと、なかなか理解しないと思いますので
hiroさんの試した結果が出てから、私のコードはUpします

【49653】Re:2表出力
発言  hiro  - 07/6/14(木) 19:10 -

引用なし
パスワード
   ▼Hirofumi さん:

遅くなってすいません とりあえずupします
Private Function AddUp(rngList As Range, rngResult As Range, _
            rngWork As Range, vntKeyA1 As Variant, _
            vntKeyB1 As Variant, lngColumns As Long, _
            lngItem As Long) As Boolean

  '◆「1係」の列位置を指定(基準セル位置からの列Offset:基準がA1で「1係」がD列なら3)
  Const clngBegin As Long = 3
 
  Dim i As Long
  Dim j As Long
  Dim 行, 列
  Dim lngRows As Long
  Dim vntResult As Variant
  Dim vntTop As Variant
  Dim vntItem As Variant

  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益", "仕入", "在庫")
 
  '年度先頭の日付を取得
  vntTop = Left(vntKeyA1, 4) & "/" & Mid(vntKeyA1, 5, 2) _
          & "/" & Right(vntKeyA1, 2)
  '年度を調整
  vntTop = DateValue(vntTop)
  vntTop = ">=" & Format(DateSerial(Year(vntTop), _
            Month(vntTop), 1), "yyyymmdd")
  AddUp = True
  With rngWork
    '集計結果の格納用配列を確保
    ReDim vntResult(UBound(vntItem))
    '☆KeyA1の値以下の日付で、KeyB1の店舗で
    '日付条件を出力
    .Offset(1, lngColumns + 1).Value = vntTop
    .Offset(1, lngColumns + 2).Value = "<=" & vntKeyA1
    '店舗条件を出力
    .Offset(1, lngColumns + 3).Resize(UBound(vntItem) + 1).Value _
        = "=" & """=" & vntKeyB1 & """"
    '売上、差益を抽出し、集計
    For i = 0 To UBound(vntItem)
      '項目条件を出力
      .Offset(1, lngColumns + 4).Value _
          = "=" & """=" & vntItem(i) & """"
      'AdvancedFilterを実行
      DoFilter rngList.CurrentRegion, .Offset(, lngColumns + 1) _
                  .Resize(2, 4), .Resize(, lngColumns)
      'データ行数を取得
      lngRows = .CurrentRegion.Rows.Count
      '売上データを集計
      With .Offset(lngRows, clngBegin).Resize(, lngColumns - clngBegin)
        '範囲に関数を設定
        .FormulaR1C1 = "=Sum(R[-" & (lngRows - 1) & "]C:R[-1]C)"
      End With
      '範囲を配列に取得
      vntResult(i) = .Offset(lngRows).Resize(, lngColumns).Value
      vntResult(i)(1, lngItem + 1) = vntItem(i) & "累計"
    Next i
    '☆KeyA1の値の日付で、KeyB1の店舗のデータを抽出
    '日付条件を出力
    .Offset(1, lngColumns + 2).Resize( _
          UBound(vntItem) + 1).Value = vntKeyA1
    For i = 0 To UBound(vntItem)
      .Offset(1 + i, lngColumns + 4).Value _
          = "=" & """=" & vntItem(i) & """"
    Next i
    'AdvancedFilterを実行
    DoFilter rngList.CurrentRegion, .Offset(, lngColumns + 2) _
        .Resize(UBound(vntItem) + 1 + 1, 3), .Resize(, lngColumns)
    'データ行数を取得
    lngRows = .CurrentRegion.Rows.Count
    '抽出データがない場合
    If lngRows = 1 Then
      AddUp = False
      rngResult.Parent.Activate
      Exit Function
    End If
    '抽出項目の整列
    vntTop = .Offset(1, lngItem).Resize(lngRows).Value
    For i = 1 To lngRows - 1
      For j = 0 To UBound(vntItem)
        If vntTop(i, 1) = vntItem(j) Then
          vntTop(i, 1) = j
          Exit For
        End If
      Next j
    Next i
    .Offset(1, lngColumns).Resize(lngRows - 1).Value = vntKeyB1
    .Offset(1).Resize(lngRows - 1, lngColumns + 1).Sort _
        Key1:=.Offset(1, lngColumns), Order1:=xlAscending, _
        Header:=xlNo, OrderCustom:=1, _
        MatchCase:=False, Orientation:=xlTopToBottom, _
        SortMethod:=xlStroke
    .Offset(1, lngColumns).EntireColumn.ClearContents
    '売上、差益データを出力
    For i = 0 To UBound(vntItem)
      .Offset(lngRows + i).Resize(, _
          lngColumns).Value = vntResult(i)
    Next i
    '結果範囲をCopy
    Application.Intersect(.CurrentRegion, _
        .CurrentRegion.Offset(, 1)).Copy
  End With
 
  With rngResult
    '出力結果の下に行列を入れ替え値のみPaste
    .PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=True
    Application.CutCopyMode = False
    .Parent.Activate
    .Select
  End With
  With Worksheets("部門")
    

行 = Array(60, 63, 66, 81, 69, 93, 72, 75, 38, 214, 5, 41, 207, 20, 23, 8, 26, 29, 44, 47, 90, 50, 11, 14, 32, 136, 214, 84, 221, 96)
列 = Array(5, 8, 12, 15)

For i = 7 To 36
  For j = 5 To 8
    Worksheets("部門").Cells(行(i - 7), 列(j - 5)).Value = Worksheets("List2").Cells(i, j).Value
  Next j
Next i

End With
End Function

Private Sub DoFilter(rngScope As Range, _
          rngCriteria As Range, _
          rngCopyTo As Range)
 
'  AdvancedFilterの実行

  rngScope.AdvancedFilter _
      Action:=xlFilterCopy, _
      CriteriaRange:=rngCriteria, _
      CopyToRange:=rngCopyTo, _
      Unique:=False
  
End Sub

Range("E60").Value = Worksheets("List2").Range("E7").Valueでやると簡素化できないので変数使ってみることにしました。
不規則な行の変化で、配列がわからずつまずいていました
>>(10,13,26,27,29係)は本店にデーターなし(支店2内の部門)
ですのでとりあえず支店2を選択したときに出力したい行に抽出しました。
本店分だけですが、これでいいでしょうか?
この程度で時間かかってすいません。

【49654】Re:2表出力
回答  Hirofumi  - 07/6/14(木) 20:57 -

引用なし
パスワード
   >Range("E60").Value = Worksheets("List2").Range("E7").Valueで
>やると簡素化できないので変数使ってみることにしました。
>不規則な行の変化で、配列がわからずつまずいていました
>>>(10,13,26,27,29係)は本店にデーターなし(支店2内の部門)
>ですのでとりあえず支店2を選択したときに出力したい行に抽出しました。
>本店分だけですが、これでいいでしょうか?

hiroさんとしては、この結果で善いのですか?
要は、自分の得たい結果が出れば、コードが如何に有れそれで善いと思いますが?

>この程度で時間かかってすいません。

人が書いたコードを完全に理解しないまでも、
どの部分で何をやって居るかを理解して、
少なくと自分の得たい事を付け加えられたのですから、
上出来の部類だと思いますよ?(時間が掛るのは当然)

申し訳有りませんが、ここ2〜3日自分の事を遣らなければ成らないので、
すぐ、コードを提示できないのですが?
ただ、気に成る事が幾つか有ります

1、hiroさんの修正では、「Private Function AddUp」が2回繰り返すので、
 同じ転記が2度行われますがどうしますか?
2、転記先の行位置ですが、
 行 = Array(60, 63, 66, 81, 69, 93, 72, 75, 38, 214, 5, 41, 207, 20, 23, 8, 26, 29, 44, 47, 90, 50, 11, 14, 32, 136, 214, 84, 221, 96)
 で書かれたように、バラバラ名のですか?
 また、本店、支店A、支店Bはの転記先は、全て上記の行位置なのですか?
3、転記先「部門」で、行が飛んでいますが、この行位置は、既に何か書き込まれて居るのですか?
 何が言いたいかと言うと、処理速度を上げるのにhiroさんがやった様に1セルずつ転記すると
 速度的に不利ななるので、E5:O221の範囲に配列で転記ができないかと考えるからです
 この場合、出力データの間は(飛んでいる行位置)は全てクリアされてしまいますので
 善いのかを知りたい為です

以上

【49667】Re:2表出力
発言  hiro  - 07/6/15(金) 1:29 -

引用なし
パスワード
   ▼Hirofumi さん:
ご教授ありがとうございます

>1、hiroさんの修正では、「Private Function AddUp」が2回繰り返すので、
> 同じ転記が2度行われますがどうしますか?
すいません私のミスです転記は1回で結構です
>2、転記先の行位置ですが、
> 行 = Array(60, 63, 66, 81, 69, 93, 72, 75, 38, 214, 5, 41, 207, 20, 23, 8, 26, 29, 44, 47, 90, 50, 11, 14, 32, 136, 214, 84, 221, 96)
> で書かれたように、バラバラ名のですか?
> また、本店、支店A、支店Bはの転記先は、全て上記の行位置なのですか?
はいそうです。
>3、転記先「部門」で、行が飛んでいますが、この行位置は、既に何か書き込まれて居るのですか?
 A B C  D  E   F    G   H   I   J     
2
3         売上        差益
4      目標 実績 達成率 目標 実績 達成率 差益率  
5   本年 
6   前年
7   差額

1       K  L   M    N   O   P
2
3         仕入        在庫
4      目標 実績 前年比 目標 実績 前年比 
5   本年 
6   前年
7   差額

シート部門のレイアウトは上記のようになっていまして
各グループ別に小計しています
グループ分けは下記のようになっています

本店                        
グループ1     11.16.23.24        
グループ2     14.15.17.18.25    
グループ3     9.12.19.20.22    
グループ4     1.2.3.5.7.8
グループ5 4.28                
グループ6     21                    
グループ7 6                    
グループ8 30                    
支店A                        
グループ1 12.19.22            
グループ2     11.16.17.26.28    
グループ3 8.9.21
グループ4 18.20    
グループ5 1.2.7
グループ6     5        
支店B            
グループ1     13.10.27
グループ2 29

現在F.I.J.M.P列に数式が入っています 各グループの小計欄にも数式が入っています、本店のグループ1の小計範囲はD17:P19です
下手な説明ですいません

お時間ができましたらよろしく修正ください

【49680】Re:2表出力
回答  Hirofumi  - 07/6/15(金) 19:57 -

引用なし
パスワード
   以下を変更して下さい ★印追加、●印削除

vntCPosは、「部門」シートの出力列位置を指定しています、Array内の数値は、

  '◆累計を転記するシートの基準位置を設定(指定位置の下の行に転記)
  Set rngOther = Worksheets("部門").Cells(4, "C") '★追加

を基準とした、列Offsetで表わしています
売上がE列=2、差益H列=5、仕入L列=9、在庫O列=12

vntClearは、「部門」シートのデータをクリアする行位置を指定しています
vntRPosは、「部門」シートのデータ転記行位置を指定しています
Array内の30個の数値は、

  '◆累計を転記するシートの基準位置を設定(指定位置の下の行に転記)
  Set rngOther = Worksheets("部門").Cells(4, "C") '★追加

を基準とした、書き込む「係」の行Offsetで表わしています
例えばE5=1、E8=4、尚転記しない所は""で指定します

PS:
 1、支店Aのグループ5が、書き込む欄が2つなのにデータは3つ転記する様に成っていますが?
 2、質問では累計値なのに、「 - 07/6/14(木) 19:10 -」のコードでは、1日のデータですが?

Public Sub Main()
  
  Dim vntKeyB1 As Variant
  Dim rngOther As Range  '★追加
  Dim vntItem As Variant '★追加
  Dim vntCPos As Variant '★追加
  Dim vntRPos As Variant '★追加
  Dim vntClear As Variant '★追加
  Dim strProm As String
    .
    .
  If Not IsDate(Left(vntKeyA2, 4) _
      & "/" & Mid(vntKeyA2, 5, 2) _
          & "/" & Right(vntKeyA2, 2)) Then
    GoTo Wayout
  End If
  
  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益", "仕入", "在庫") '★追加
  
  '◆累計を転記する別シートの位置
  '(上記、vntItemに対応する物とし、転記先基準からの列Offset値)
  '売上がE列 差益H列 仕入L列 在庫O列
  vntCPos = Array(2, 5, 9, 12) '★追加
  
  '◆部門転記データのクリアする行位置
  vntClear = Array(1, 4, 7, 10, 16, 19, 22, 25, 28, _
          34, 37, 40, 43, 46, 56, 59, 62, 65, _
          68, 71, 77, 80, 86, 89, 92) '★追加
  '◆部門データの転記行位置を設定
  '転記先C4セルを基準とし、基準からの行Offsetで指定
  '例えばE5=1、E8=4、尚転記しない所は""で指定
  Select Case vntKeyB1 '★追加
    Case "本店" '★追加
      vntRPos = Array(56, 59, 62, 77, 65, 89, 68, 71, 34, "", _
              1, 37, "", 16, 19, 4, 22, 25, 40, 43, _
              86, 46, 7, 10, 28, "", "", 80, "", 92) '★追加
    Case "支店A" '★追加
      vntRPos = Array(77, 80, "", "", 86, "", 83, 34, 37, "", _
              16, 1, "", "", "", 19, 22, 56, 4, 59, _
              40, 7, "", "", "", 25, "", 28, "", "") '★追加
    Case "支店B" '★追加
      vntRPos = Array("", "", "", "", "", "", "", "", "", 4, _
              "", "", 1, "", "", "", "", "", "", "", _
              "", "", "", "", "", "", 7, "", 16, "") '★追加
  End Select '★追加
  
  '◆累計を転記するシートの基準位置を設定(指定位置の下の行に転記)
  Set rngOther = Worksheets("部門").Cells(4, "C") '★追加
  
  '画面更新を停止
  Application.ScreenUpdating = False
    ・
    ・
  strProm = "抽出条件に一致するレコードが有りません"
  If Not AddUp(rngList, rngResult, rngWork, vntKeyA1, _
        vntKeyB1, clngColumns, clngItem, vntItem, rngOther, _
            vntCPos, vntRPos, vntClear) Then '★変更、引数変更
    GoTo Wayout
  End If
  If Not AddUp(rngList, rngResult.Offset(, 10), _
        rngWork, vntKeyA2, vntKeyB1, clngColumns, _
            clngItem, vntItem) Then     '★変更、引数変更
    GoTo Wayout
  End If

  strProm = "処理が完了しました"
    ・
    ・
  '画面更新を再開
  Application.ScreenUpdating = True
  
  Set rngWork = Nothing
  Set rngList = Nothing
  Set rngResult = Nothing
  Set rngOther = Nothing '★追加
  
  MsgBox strProm, vbInformation
     
End Sub

'★引数追加
Private Function AddUp(rngList As Range, rngResult As Range, _
            rngWork As Range, vntKeyA1 As Variant, _
            vntKeyB1 As Variant, lngColumns As Long, _
            lngItem As Long, _
            vntItem As Variant, _
            Optional rngOther As Range, _
            Optional vntCPos As Variant, _
            Optional vntRPos As Variant, _
            Optional vntClear As Variant) As Boolean '★引数追加

  '◆「1係」の列位置を指定(基準セル位置からの列Offset:基準がA1で「1係」がD列なら3)
  Const clngBegin As Long = 3
  
  Dim vntTop As Variant
'  Dim vntItem As Variant '●削除

  '●記述位置変更のため削除
  '◆「項目」列の抽出条件文字列を設定
'  vntItem = Array("売上", "差益", "仕入", "在庫") '●削除
  
  '年度先頭の日付を取得
    ・
    ・
  With rngResult
    '出力結果の下に行列を入れ替え値のみPaste
    .PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=True
    Application.CutCopyMode = False
    '転記するRangeが有り、且つ転記行位置が指定された場合
    If (Not rngOther Is Nothing) _
        And VarType(vntRPos) = vbArray + vbVariant Then  '★追加
      For i = UBound(vntCPos) To 0 Step -1 '★追加
        '転記列位置の指定が有るなら
        If vntCPos(i) <> "" Then '★追加
          '転記先データを消去
          For j = 0 To UBound(vntClear) '★追加
            rngOther.Offset(vntClear(j), vntCPos(i)) = Empty '★追加
          Next j '★追加
          'データを転記
          For j = 0 To UBound(vntRPos) '★追加
            If vntRPos(j) <> "" Then '★追加
              rngOther.Offset(vntRPos(j), vntCPos(i)).Value _
                  = .Offset(j + 2, lngRows + i).Value '★追加
            End If '★追加
          Next j '★追加
        End If '★追加
      Next i '★追加
    End If '★追加
    .Parent.Activate
    .Select
  End With
     
End Function

【49704】Re:2表出力
発言  hiro  - 07/6/17(日) 23:27 -

引用なし
パスワード
   ▼Hirofumi さん:
修正ありがとうございます
そして大変申し訳ないのですが、私の説明不足でお詫びしなくてはならないことがあります。
シート部門のレイアウトは本店の下に支店Aその下に支店Bの表を作成しておりました。支店Aを選択したときのデータ転記行は170,173,"","",182,"",176,145,148,"",127,115,"","","","",130,133,161,118,,164,151,121,"","","",136,"",139,"","" 行目
支店Bのときは
"", "", "", "", "", "", "", "", "", 211, "", "",207, "", "", "", "", "", "", "", _
"", "", "", "", "", "", 214, "", 221, ""行目になるよにレイアウトしていました。説明不十分ですいません
>    Case "支店A" '★追加
>      vntRPos = Array(166, 169, "", "", 178........)
>    Case "支店B" '★追加
>      vntRPos = Array("", "", "", "", "", "", "", "", "", 207             "", "", 203...........) の訂正だけでは無理ですね?

昨日から試しているのですがうまくいかず返事がおそくなってしまいました
それから転記したいのはhirohumi様のおっしゃるとおり累計値です私がコード間違ってupしたみたいです すいません
また時間の空きましたときに修正箇所教えて頂けますでしょうか
最終的にはList2抽出した前年累計値もシート部門の本年累計値の一行下に転記したいと思ってます
  A   B   C   D   E   F   G   H   I   J
1
2
3              売上        差益
4           目標 実績 達成率 目標 実績 達成率 差益率
5       本年
6 11係    前年
7       差額
8       本年
9  16係    前年
10       差額

シート部門はこんなかんじになってます
今回はせっかく修正いただいたのに説明不足で御迷惑かけてほんとにすいませんでした。


>  
>  

【49713】Re:2表出力
回答  Hirofumi  - 07/6/18(月) 12:13 -

引用なし
パスワード
   いろいろ数値をいじって上手くいきませんか?
私のコードは、基本的に入出力の位置の変更が簡単に出来る様に書いている積りです
(勘違い、バグでパーフェクトでは有りませんが?)
入力でも出力でも基準のセル位置を決めて、そこからのOffsetで相対的に追っています
これは、入力のList、出力のListを左右に何列か、上下に何行かずらしたい時は、
各基準位置を変更するだけで対応できるという事です

詰まり、今回の様な場合、「部門」シートの表(本店、支店A、支店B)を
1表と考えるか3表と考えるかに因っても対応が変わります

多分、hiroさんがいじった方向は、本店、支店A、支店Bを1つの表と考えて、修正した物と思います
これはどういう事かと言うと、
基準セル位置、

  '◆累計を転記するシートの基準位置を設定(指定位置の下の行に転記)
  Set rngOther = Worksheets("部門").Cells(4, "C") '★追加

を変えないで、位置を指定しようとした場合です

この場合、内容は見て居ませんがvntRPosの値は、「07/6/17(日) 23:27」のレスの様に変更すれば善いのでが?、
セルのクリアが邪魔をすると思います(実行する度に本店位置の表がクリアされますので)、
対策案として

クリアをさせない案

「Function AddUp」の中の

          '転記先データを消去
          For j = 0 To UBound(vntClear)
            rngOther.Offset(vntClear(j), vntCPos(i)) = Empty
          Next j

 をコメントアウトもしくは、削除する
 
の案が考えられます

また、本店、支店A、支店Bをそれぞれ別な表として捉える場合の修正は、

例えば、本店の基準セル位置(売上目標の前列で本年の上の行)は変わらず、C4とし、
同様に、支店Aの基準セル位置(売上目標の前列で本年の上の行)をC118とし
同様に、支店Bの基準セル位置(売上目標の前列で本年の上の行)をC208とします

部門データの転記行位置を設定を以下の様に変更します

  '◆部門データの転記行位置を設定
  '転記先C4セルを基準とし、基準からの行Offsetで指定
  '例えばE5=1、E8=4、尚転記しない所は""で指定
  Select Case vntKeyB1
    Case "本店"
      '◆累計を転記するシートの基準位置を設定(指定位置の下の行に転記)
      Set rngOther = Worksheets("部門").Cells(4, "C")
      vntRPos = Array(56, 59, 62, 77, 65, 89, 68, 71, 34, "", _
              1, 37, "", 16, 19, 4, 22, 25, 40, 43, _
              86, 46, 7, 10, 28, "", "", 80, "", 92)
    Case "支店A"
      '◆累計を転記するシートの基準位置を設定(指定位置の下の行に転記)
      Set rngOther = Worksheets("部門").Cells(118, "C")
      vntRPos = Array(56, 59, "", "", 68, "", 62, 31, 34, "", _
              13, 1, "", "", "", "", 16, 19, 47, 4, _
              "", 50, 37, 7, "", "", "", 22, "", 25)
    Case "支店B"
      '◆累計を転記するシートの基準位置を設定(指定位置の下の行に転記)
      Set rngOther = Worksheets("部門").Cells(208, "C")
      vntRPos = Array("", "", "", "", "", "", "", "", "", 4, _
              "", "", 1, "", "", "", "", "", "", "", _
              "", "", "", "", "", "", 7, "", 13, "")
  End Select

この場合のvntRPosの値は、rngOtherの行位置を0とした行Offsetで表します

次に、セルをクリアする部分が邪魔なので以下の部分を削除します

「Function AddUp」の中の

          '転記先データを消去
          For j = 0 To UBound(vntClear)
            rngOther.Offset(vntClear(j), vntCPos(i)) = Empty
          Next j


以上

>最終的にはList2抽出した前年累計値もシート部門の本年累計値の一行下に転記したいと思ってます

これは、2回目の

  If Not AddUp(rngList, rngResult.Offset(, 10), _
        rngWork, vntKeyA2, vntKeyB1, clngColumns, _
            clngItem, vntItem) Then
    GoTo Wayout
  End If

に引数、rngOther.Offset(1)、vntCPos、vntRPosを与えればできます

【49714】Re:2表出力
回答  Hirofumi  - 07/6/18(月) 12:16 -

引用なし
パスワード
   修正で間違えるといけないので、変更のない「Private Sub DoFilter」以外をUpします
尚、コメントは、Up出来る行数を超えるといけないので削除して有ります

Public Sub Main2()
  
  '◆Listのデータ列数(A列〜AG列)
  Const clngColumns As Long = 33
  '◆「日付」の列位置を指定(基準セル位置からの列Offset:基準がA1で「日付」がA列なら0)
  Const clngDate As Long = 0
  '◆「店舗」の列位置を指定(基準セル位置からの列Offset:基準がA1で「店舗」がB列なら1)
  Const clngKey As Long = 1
  '◆「項目」の列位置を指定(基準セル位置からの列Offset:基準がA1で「項目」がC列なら2)
  Const clngItem As Long = 2
  
  Dim lngRows As Long
  Dim rngList As Range
  Dim rngResult As Range
  Dim rngWork As Range
  Dim vntKeyA1 As Variant
  Dim vntKeyA2 As Variant
  Dim vntKeyB1 As Variant
  Dim rngOther As Range
  Dim vntItem As Variant
  Dim vntCPos As Variant
  Dim vntRPos As Variant
  Dim strProm As String

  '◆Listの先頭セル位置を基準とする(列見出し「日付」のセル位置)
  Set rngList = Worksheets("List").Cells(1, "A")

  '◆List2の先頭セル位置を基準とする(列見出し「店舗」のセル位置)
  Set rngResult = Worksheets("List2").Cells(5, "B")
  
  Application.ScreenUpdating = False
  
  With rngList
    lngRows = .CurrentRegion.Rows.Count - 1
    If lngRows <= 0 Then
      strProm = "データが有りません"
      GoTo Wayout
    End If
  End With
  
  With rngResult
    vntKeyA1 = .Parent.Cells(2, 2).Value
    vntKeyA2 = .Parent.Cells(2, 3).Value
    vntKeyB1 = .Parent.Cells(3, 2).Value
    .CurrentRegion.ClearContents
  End With
  strProm = "抽出日付が、日付と認められません"
  If Not IsDate(Left(vntKeyA1, 4) _
      & "/" & Mid(vntKeyA1, 5, 2) _
          & "/" & Right(vntKeyA1, 2)) Then
    GoTo Wayout
  End If
  If Not IsDate(Left(vntKeyA2, 4) _
      & "/" & Mid(vntKeyA2, 5, 2) _
          & "/" & Right(vntKeyA2, 2)) Then
    GoTo Wayout
  End If
  
  '◆「項目」列の抽出条件文字列を設定
  vntItem = Array("売上", "差益", "仕入", "在庫")
  
  '◆累計を転記する別シートの位置
  vntCPos = Array(2, 5, 9, 12)
  
  '◆部門データの転記行位置を設定
  Select Case vntKeyB1
    Case "本店"
      Set rngOther = Worksheets("部門").Cells(4, "C")
      vntRPos = Array(56, 59, 62, 77, 65, 89, 68, 71, 34, "", _
              1, 37, "", 16, 19, 4, 22, 25, 40, 43, _
              86, 46, 7, 10, 28, "", "", 80, "", 92)
    Case "支店A"
      Set rngOther = Worksheets("部門").Cells(118, "C")
      vntRPos = Array(56, 59, "", "", 68, "", 62, 31, 34, "", _
              13, 1, "", "", "", "", 16, 19, 47, 4, _
              "", 50, 37, 7, "", "", "", 22, "", 25)
    Case "支店B"
      Set rngOther = Worksheets("部門").Cells(208, "C")
      vntRPos = Array("", "", "", "", "", "", "", "", "", 4, _
              "", "", 1, "", "", "", "", "", "", "", _
              "", "", "", "", "", "", 7, "", 13, "")
  End Select
  
  With Worksheets
    Set rngWork = .Add(After:=.Item(.Count)).Cells(1, "A")
  End With
  With rngWork
    rngList.Resize(, clngColumns).Copy Destination:=.Item(1)
    'AdvancedFilter条件範囲の列見出しの出力
    With .Offset(, clngColumns)
      .Offset(, 1).Resize(, 2).Value _
          = rngList.Offset(, clngDate).Value
      .Offset(, 3).Value = rngList.Offset(, clngKey).Value
      .Offset(, 4).Value = rngList.Offset(, clngItem).Value
    End With
  End With
  
  strProm = "抽出条件に一致するレコードが有りません"
  If Not AddUp(rngList, rngResult, rngWork, vntKeyA1, _
          vntKeyB1, clngColumns, clngItem, vntItem, _
            rngOther, vntCPos, vntRPos) Then
    GoTo Wayout
  End If
  If Not AddUp(rngList, rngResult.Offset(, 10), rngWork, vntKeyA2, _
          vntKeyB1, clngColumns, clngItem, vntItem, _
            rngOther.Offset(1), vntCPos, vntRPos) Then
    GoTo Wayout
  End If

  strProm = "処理が完了しました"
  
Wayout:

  If Not rngWork Is Nothing Then
    Application.DisplayAlerts = False
    rngWork.Parent.Delete
    Application.DisplayAlerts = True
  End If
  
  Application.ScreenUpdating = True
  
  Set rngWork = Nothing
  Set rngList = Nothing
  Set rngResult = Nothing
  Set rngOther = Nothing
  
  MsgBox strProm, vbInformation
     
End Sub

Private Function AddUp(rngList As Range, rngResult As Range, _
            rngWork As Range, vntKeyA1 As Variant, _
            vntKeyB1 As Variant, lngColumns As Long, _
            lngItem As Long, _
            vntItem As Variant, _
            Optional rngOther As Range, _
            Optional vntCPos As Variant, _
            Optional vntRPos As Variant) As Boolean

  '◆「1係」の列位置を指定(基準セル位置からの列Offset:基準がA1で「1係」がD列なら3)
  Const clngBegin As Long = 3
  
  Dim i As Long
  Dim j As Long
  Dim lngRows As Long
  Dim vntResult As Variant
  Dim vntTop As Variant
  
  vntTop = Left(vntKeyA1, 4) & "/" & Mid(vntKeyA1, 5, 2) _
          & "/" & Right(vntKeyA1, 2)
  vntTop = DateValue(vntTop)
  vntTop = ">=" & Format(DateSerial(Year(vntTop), _
            Month(vntTop), 1), "yyyymmdd")
  AddUp = True
  With rngWork
    ReDim vntResult(UBound(vntItem))
    .Offset(1, lngColumns + 1).Value = vntTop
    .Offset(1, lngColumns + 2).Value = "<=" & vntKeyA1
    .Offset(1, lngColumns + 3).Resize(UBound(vntItem) + 1).Value _
        = "=" & """=" & vntKeyB1 & """"
    For i = 0 To UBound(vntItem)
      .Offset(1, lngColumns + 4).Value _
          = "=" & """=" & vntItem(i) & """"
      DoFilter rngList.CurrentRegion, .Offset(, lngColumns + 1) _
                  .Resize(2, 4), .Resize(, lngColumns)
      lngRows = .CurrentRegion.Rows.Count
      With .Offset(lngRows, clngBegin).Resize(, lngColumns - clngBegin)
        .FormulaR1C1 = "=Sum(R[-" & (lngRows - 1) & "]C:R[-1]C)"
      End With
      vntResult(i) = .Offset(lngRows).Resize(, lngColumns).Value
      vntResult(i)(1, lngItem + 1) = vntItem(i) & "累計"
    Next i
    .Offset(1, lngColumns + 2).Resize( _
          UBound(vntItem) + 1).Value = vntKeyA1
    For i = 0 To UBound(vntItem)
      .Offset(1 + i, lngColumns + 4).Value _
          = "=" & """=" & vntItem(i) & """"
    Next i
    DoFilter rngList.CurrentRegion, .Offset(, lngColumns + 2) _
        .Resize(UBound(vntItem) + 1 + 1, 3), .Resize(, lngColumns)
    lngRows = .CurrentRegion.Rows.Count
    If lngRows = 1 Then
      AddUp = False
      rngResult.Parent.Activate
      Exit Function
    End If
    vntTop = .Offset(1, lngItem).Resize(lngRows).Value
    For i = 1 To lngRows - 1
      For j = 0 To UBound(vntItem)
        If vntTop(i, 1) = vntItem(j) Then
          vntTop(i, 1) = j
          Exit For
        End If
      Next j
    Next i
    .Offset(1, lngColumns).Resize(lngRows - 1).Value = vntKeyB1
    .Offset(1).Resize(lngRows - 1, lngColumns + 1).Sort _
        Key1:=.Offset(1, lngColumns), Order1:=xlAscending, _
        Header:=xlNo, OrderCustom:=1, _
        MatchCase:=False, Orientation:=xlTopToBottom, _
        SortMethod:=xlStroke
    .Offset(1, lngColumns).EntireColumn.ClearContents
    For i = 0 To UBound(vntItem)
      .Offset(lngRows + i).Resize(, _
          lngColumns).Value = vntResult(i)
    Next i
    Application.Intersect(.CurrentRegion, _
        .CurrentRegion.Offset(, 1)).Copy
  End With
  
  With rngResult
    .PasteSpecial Paste:=xlPasteValues, _
        Operation:=xlNone, _
        SkipBlanks:=False, Transpose:=True
    Application.CutCopyMode = False
    If (Not rngOther Is Nothing) _
        And VarType(vntRPos) = vbArray + vbVariant Then
      For i = UBound(vntCPos) To 0 Step -1
        If vntCPos(i) <> "" Then
          For j = 0 To UBound(vntRPos)
            If vntRPos(j) <> "" Then
              rngOther.Offset(vntRPos(j), vntCPos(i)).Value _
                  = .Offset(j + 2, lngRows + i).Value
            End If
          Next j
        End If
      Next i
    End If
    .Parent.Activate
    .Select
  End With
     
End Function

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