Excel VBA質問箱 IV

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

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


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

【18110】冗長なコードの簡略化について カド 04/9/15(水) 19:22 質問[未読]
【18111】Re:冗長なコードの簡略化について IROC 04/9/15(水) 19:56 回答[未読]
【18113】Re:冗長なコードの簡略化について カド 04/9/15(水) 21:01 お礼[未読]
【18112】Re:冗長なコードの簡略化について Hirofumi 04/9/15(水) 20:37 回答[未読]
【18114】Re:冗長なコードの簡略化について カド 04/9/15(水) 21:10 質問[未読]
【18115】Re:冗長なコードの簡略化について Hirofumi 04/9/15(水) 22:20 回答[未読]
【18116】Re:冗長なコードの簡略化について カド 04/9/15(水) 22:43 質問[未読]
【18117】Re:冗長なコードの簡略化について Kein 04/9/16(木) 1:30 回答[未読]
【18118】Re:冗長なコードの簡略化について Kein 04/9/16(木) 1:32 発言[未読]
【18149】Re:冗長なコードの簡略化について カド 04/9/16(木) 15:09 お礼[未読]
【18119】Re:冗長なコードの簡略化について 禰宜 04/9/16(木) 1:56 回答[未読]
【18150】Re:冗長なコードの簡略化について カド 04/9/16(木) 15:11 お礼[未読]
【18153】Re:冗長なコードの簡略化について 禰宜 04/9/16(木) 16:03 発言[未読]

【18110】冗長なコードの簡略化について
質問  カド  - 04/9/15(水) 19:22 -

引用なし
パスワード
   以下のようにifが並ぶ冗長なコードを簡略化したいのですが、
良い方法がありますか?  


<冗長なコード>

If (bun_cell.Offset(Count, 0) = "ア物語") And (bun_cell.Offset(Count, 1) = "済")
    Sum0 = Sum0 + bun_cell.Offset(Count, -68)

  End If
  

  If (bun_cell.Offset(Count, 0) = "ア物語") And (bun_cell.Offset(Count, 1) = "活動中")    
    Sum1 = Sum1 + bun_cell.Offset(Count, -68)
    
  End If
  

  If (bun_cell.Offset(Count, 0) = "ア物語") And (bun_cell.Offset(Count, 1) = "(採用)")    
    Sum2 = Sum2 + bun_cell.Offset(Count, -68)
      End If
  
  
     If (bun_cell.Offset(Count, 0) = "ア物語") And (bun_cell.Offset(Count, 1) = "(却下)")    
    Sum3 = Sum3 + bun_cell.Offset(Count, -68)
      End If
  
  
  If (bun_cell.Offset(Count, 0) = "ア物語") And (bun_cell.Offset(Count, 1) = "却下3")        
    Sum4 = Sum4 + bun_cell.Offset(Count, -68)
      End If

【18111】Re:冗長なコードの簡略化について
回答  IROC  - 04/9/15(水) 19:56 -

引用なし
パスワード
   and前をifで判定して、
つぎに and 以降を select case にしては如何でしょうか?

また、Countはプロパティが存在するので、変数名に使わない方がよいです。

【18112】Re:冗長なコードの簡略化について
回答  Hirofumi  - 04/9/15(水) 20:37 -

引用なし
パスワード
     Dim vntValue As Variant
  
  With bun_cell
    If .Offset(Count, 0) = "ア物語" Then
      vntValue = .Offset(Count, -68).Value
      Select Case .Offset(Count, 1).Value
        Case "済"
          Sum0 = Sum0 + vntValue
        Case "活動中"
          Sum1 = Sum1 + vntValue
        Case "(採用)"
          Sum2 = Sum2 + vntValue
        Case "(却下)"
          Sum3 = Sum3 + vntValue
        Case "却下3"
          Sum4 = Sum4 + vntValue
      End Select
    End If
  End With

【18113】Re:冗長なコードの簡略化について
お礼  カド  - 04/9/15(水) 21:01 -

引用なし
パスワード
   ▼IROC さん:
回答ありがとうございます。

>select case にしては如何でしょうか?

caseというのがあるのですね。使ってみます。

【18114】Re:冗長なコードの簡略化について
質問  カド  - 04/9/15(水) 21:10 -

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

わざわざコードの提示ありがとうございます。

じつは、実際は、
"ア物語"だけでなく、"イ物語"や"ウ物語"があって、以下のように
なるのですが、これを更にシンプルに出来ますか?

  With bun_cell
    If .Offset(Count, 0) = "ア物語" Then
      vntValue = .Offset(Count, -68).Value
      Select Case .Offset(Count, 1).Value
        Case "済"
          Sum0 = Sum0 + vntValue
        Case "活動中"
          Sum1 = Sum1 + vntValue
        Case "(採用)"
          Sum2 = Sum2 + vntValue
        Case "(却下)"
          Sum3 = Sum3 + vntValue
        Case "却下3"
          Sum4 = Sum4 + vntValue
      End Select
    End If
  End With

  With bun_cell
    If .Offset(Count, 0) = "イ物語" Then
      vntValue = .Offset(Count, -68).Value
      Select Case .Offset(Count, 1).Value
        Case "済"
          Sum5 = Sum5 + vntValue
        Case "活動中"
          Sum6 = Sum6 + vntValue
        Case "(採用)"
          Sum7 = Sum7 + vntValue
        Case "(却下)"
          Sum8 = Sum8 + vntValue
        Case "却下3"
          Sum9 = Sum9 + vntValue
      End Select
    End If
  End With

以下続く

【18115】Re:冗長なコードの簡略化について
回答  Hirofumi  - 04/9/15(水) 22:20 -

引用なし
パスワード
   >じつは、実際は、
>"ア物語"だけでなく、"イ物語"や"ウ物語"があって、以下のように
>なるのですが、これを更にシンプルに出来ますか?

配列を使って、ループすれば善いのでは?
実際の、セルの位置等に寄りますので、このままではコードまで提示できません

【18116】Re:冗長なコードの簡略化について
質問  カド  - 04/9/15(水) 22:43 -

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

状況を改めて言いますと、
A列に、バナナ、みかん、イチゴ、すいか、メロン
B列に、山田、酒井、吉田、佐藤、田中
が、それぞれランダムに出てきます。
そして、C列に売上個数が出てきます。

そのようなデータが1000行ある時に、
バナナは山田さんに計38個売った。
バナナは酒井さんに計30個売った。



みかんは山田さんに計3個売った。



このような集計がしたいのですが、これをすっきり書けたらなと思っています。


     A   B    C
1    みかん 山田   8
2    いちご 佐藤   6
3    いちご 山田   5


1000 バナナ 佐藤   3

【18117】Re:冗長なコードの簡略化について
回答  Kein  - 04/9/16(木) 1:30 -

引用なし
パスワード
   別シート(仮にSheet2)に集計結果を出すとして

Sub 集計()
  With Application
   .ScreenUpdating = False
   .DisplayAlerts = False
  End With
  Rows(1).Insert xlShiftDown
  Range("A1:C1").Value = Array("商品", "氏名", "個数")
  Range("AA1").Value = "商品名,販売先氏名"
  With Range("A2", Range("A65536").End(xlUp)).Offset(, 26)
   Ad1 = "Sheet1!" & .Address
   Ad2 = "Sheet1!" & .Offset(, -24).Address
   .Formula = "=$A2&"",""&$B2"
   .Copy
   .PasteSpecial xlPasteValues
  End With
  Application.CutCopyMode = False
  With Sheets("Sheet2")
   .Range("A:C").ClearContents
   Range("AA1", Range("AA65536").End(xlUp)).AdvancedFilter _
    xlFilterCopy, , .Range("A1"), True
   .Range("C1").Value = "販売個数計"
   With .Range("C2", .Range("A1").End(xlDown).Offset(, 2))
     .Formula = "=SUMIF(" & Ad1 & ",$A2," & Ad2 & ")"
     .Copy
     .PasteSpecial xlPasteValues
   End With
   .Range("A:A").TextToColumns DataType:=xlDelimited, Comma:=True
   .Range("A1").CurrentRegion.Sort Key1:=.Range("A1"), _
   Order1:=xlAscending, Header:=xlYes, Orientation:=xlSortColumns
  End With
  Range("AA:AA").ClearContents
  Rows(1).Delete xlShiftUp
  Sheets("Sheet2").Activate
  With Application
   .CutCopyMode = False
   .ScreenUpdating = True
   .DisplayAlerts = True
  End With
End Sub

集計対象シートを開いて実行して下さい。
なお1行目は、仮の項目を入れて最後に削除してます。表を作るなら項目を入れる
のがExcelの常識ですけどね。

【18118】Re:冗長なコードの簡略化について
発言  Kein  - 04/9/16(木) 1:32 -

引用なし
パスワード
   Sub 集計()
  Dim Ad1 As String, Ad2 As String

と、変数を宣言しておいて下さい。

【18119】Re:冗長なコードの簡略化について
回答  禰宜  - 04/9/16(木) 1:56 -

引用なし
パスワード
   失礼いたします。

ADOを使ってこんなコードでも可能ですね^^

Sub ADO_TEST()
    
    Set CN = CreateObject("ADODB.Connection")
    
    CN.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
        "Data Source=" & ThisWorkbook.FullName & ";" & _
        "Extended Properties=""Excel 8.0;HDR=NO;IMEX=1"""

    CN.Open
    
    Set RS = CreateObject("ADODB.Recordset")
    
    Set RS = CN.Execute _
    ("SELECT F1,F2,SUM(F3) FROM [Sheet1$A1:C65536] GROUP BY F1,F2")
    
    Sheets(2).Range("A1").CopyFromRecordset RS
    
    RS.Close
    CN.Close
    Set RS = Nothing
    Set CN = Nothing

End Sub

データのあるシート名が"Sheet1"、出力先が2番目のシートとしています。
EXCELのVersion等によっては動きませんが、接続情報を変えれば動作すると
思います。

参考まで^^

【18149】Re:冗長なコードの簡略化について
お礼  カド  - 04/9/16(木) 15:09 -

引用なし
パスワード
   ▼Kein さん:
回答ありがとうございます。

ご提示いただいたコードで目的の処理をすることは出来ました。

【18150】Re:冗長なコードの簡略化について
お礼  カド  - 04/9/16(木) 15:11 -

引用なし
パスワード
   ▼禰宜 さん:
回答ありがとうございます。

”抽出条件でデータ型が一致しません。”
というエラーが出てしまいました。

【18153】Re:冗長なコードの簡略化について
発言  禰宜  - 04/9/16(木) 16:03 -

引用なし
パスワード
   ▼カド さん:
>▼禰宜 さん:
>回答ありがとうございます。
>
>”抽出条件でデータ型が一致しません。”
>というエラーが出てしまいました。

型が一致しない・・・・なぜだろう?

確認なのですが、A列とB列は文字列、C列は数字で、
データは1行目からはじまり項目名はついていないんですよね?

シート名は「Sheet1」で記述しています。

ためしに、先に私が記述したコードの、

>Set RS = CN.Execute _
>("SELECT F1,F2,SUM(F3) FROM [Sheet1$A1:C65536] GROUP BY F1,F2")

上の部分を以下に置き換えてみてください。

Set RS = CN.Execute _
("SELECT F1,F2,SUM(F3) FROM [Sheet1$A1:C1000] GROUP BY F1,F2")

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