Excel VBA質問箱 IV

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

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


905 / 13644 ツリー ←次へ | 前へ→

【77616】マクロ化の検討 VBAビギナー 15/11/10(火) 15:58 質問[未読]
【77617】Re:マクロ化の検討 独覚 15/11/10(火) 17:32 回答[未読]
【77618】Re:マクロ化の検討 独覚 15/11/10(火) 17:34 発言[未読]
【77621】Re:マクロ化の検討 VBAビギナー 15/11/11(水) 8:36 お礼[未読]
【77619】Re:マクロ化の検討 β 15/11/10(火) 19:49 発言[未読]
【77622】Re:マクロ化の検討 VBAビギナー 15/11/11(水) 8:40 回答[未読]

【77616】マクロ化の検討
質問  VBAビギナー  - 15/11/10(火) 15:58 -

引用なし
パスワード
   以前こちらで、ご質問させていただき迅速な回答に感激しました。
ありがとうございました。

さて、さっそくですが今回下記の用な表をVBAもしくはEXCEL関数等を使って
1〜2回の動作で作りたいのですが、何か良い案はありますでしょうか。


製品            製品重量    糖度
みかんA            10g        10
みかんA            11g        10
みかんA            12g        10
みかんB            15g        18
みかんB            17g        20
みかんB            16g        20
りんごA            20g        5
りんごA            22g        5
りんごA            21g        5
りんごA            25g        5
りんごB            27g        8
ぶどう            30g        25
ぶどう            33g        25
ぶどう            31g        24



みかんA            12g        ok
みかんB            17g        error
りんごA            25g        ok
りんごB            27g        ok
ぶどう            33g        error


商品の重量は最大値を、糖度は同じでなければエラーとなるようにしたい。
商品それぞれの検索範囲(データベース)が必要になると思うのでそれぞれの検索範囲が決定するような方法をみつけなければならないように思います。

今考えているのが、かなり回りくどいのですが、
1.品名が違う場合は、その手前で○をつける。
2.○のついたセルをコピーしSheet2に貼り付ける。←ここまで完成。
3.Sheet2に貼り付けた製品名を一つずつ検索し、Sheet3に貼り付ける。
(みかんAとみかんBとのセルの間隔を十分あけ、かぶらないよう貼り付ける。)
4.Sheet3に貼り付けられたそれぞれのデータベースから最大値等を検出、コピーしSheet5に貼り付ける。

下記に今回作ったVBAを記載します。この他の方法でも何か良い案がございましたら、
是非参考にさせていただきたく存じます。回答お待ちしております。
よろしくお願いします。
-----------------------------------------------------------------------
Sub ボタン2_Click()
  Dim myrow As Integer
  Dim i As Integer

  myrow = Cells(Rows.Count, 2).End(xlUp).Row
  
    For i = 1 To myrow
  
      If Not Cells(i, 2).Value = Cells(i + 1, 2).Value Then
      Cells(i, 1).Value = "○"
    
  
    End If
    
  Next i
  
End Sub

-----------------------------------------------------------------------
Sub ボタン3_Click()

Dim foundcell As Range, firstcell As Range
  Set foundcell = Cells.Find(what:="○")
  If foundcell Is Nothing Then
    MsgBox "見つかりません"
    Exit Sub
  Else
    Set firstcell = foundcell
    foundcell.Resize(1, 2).Copy Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
  End If
  Do
    Set foundcell = Cells.FindNext(foundcell)
    If foundcell.Address = firstcell.Address Then
      Exit Do
    Else
      foundcell.Resize(1, 2).Copy Sheets("Sheet2").Cells(Rows.Count, 1).End(xlUp).Offset(1, 0)
    End If
  Loop
End Sub

【77617】Re:マクロ化の検討
回答  独覚  - 15/11/10(火) 17:32 -

引用なし
パスワード
   ▼VBAビギナー さん:
全てワークシート関数で行う場合です。
また、バージョンは2007以降でレイアウトは以下とします。

Sheet1
    A    B   C
1  製品   重量  糖度
2 みかんA  10   10
  〜

Sheet2
    A    B   C
1  製品   重量  糖度
2 みかんA  12   ok
  〜


Sheet2のA2セルに
=IFERROR(INDEX(Sheet1!A$2:A$100,SMALL(IF(FREQUENCY(IFERROR(MATCH(Sheet1!
A$2:A$100,Sheet1!A$2:A$100,0),""),ROW($1:$100)),ROW($1:$100),""),ROW(A1))),"")

B2セルに
=IF(A2="","",MIN(IF(Sheet1!A$2:A$100=A2,Sheet1!B$2:B$100,"")))

C2セルに
=IF(A2="","",IF(COUNT(0/FREQUENCY(IF(Sheet1!A$2:A$100=A2,Sheet1!C$2:C$100,""),Sheet1!C$2:C$100))=1,"○","×"))
と入力し、三つとも式の確定時にShift+Ctrl+Enterで式を確定してください。
式の確定後、式が{}で囲まれます。

その後下へフィルコピーしてください。

なお、Sheet1のデータが最大100行目までに対応しています。
100行以上ある場合は各式の「$100」部分全てを同じ値で大きくしてください。

それとA2セルの「ROW($1:$100)」部分は必ず1から最大行数までとしてください。

なお、Sheet2のA列は式で行わずにSheet1のA列をSheet2に貼り付け、データ-重複の削除を行う方法もあります。

【77618】Re:マクロ化の検討
発言  独覚  - 15/11/10(火) 17:34 -

引用なし
パスワード
   C2セルの式で◯をokに×をerrorにしてください。

【77619】Re:マクロ化の検討
発言  β  - 15/11/10(火) 19:49 -

引用なし
パスワード
   ▼VBAビギナー さん:

独覚さんからの関数処理で充分かとは思いますがVBA処理としての一例です。
元シートが "Sheet1"、結果を "Sheet2" に表示します。

Sub Sample()
  Dim MAXQ As Object
  Dim OKNG As Object
  Dim CONT As Object
  
  Dim c As Range
  
  Set MAXQ = CreateObject("Scripting.Dictionary")
  Set OKNG = CreateObject("Scripting.Dictionary")
  Set CONT = CreateObject("Scripting.Dictionary")
  
  With Sheets("Sheet1")
    For Each c In .Range("A2", .Range("A" & Rows.Count).End(xlUp))
      If MAXQ.exists(c.Value) Then
        If c.Offset(, 1).Value > MAXQ(c.Value) Then MAXQ(c.Value) = c.Offset(, 1).Value
        If c.Offset(, 2).Value <> CONT(c.Value) Then OKNG(c.Value) = "Error"
      Else
        MAXQ(c.Value) = c.Offset(, 1).Value
        OKNG(c.Value) = "OK"
        CONT(c.Value) = c.Offset(, 2).Value
      End If
    Next
  End With
  
  With Sheets("Sheet2")
    .UsedRange.ClearContents
    .Range("A1:C1").Value = Array("製品", "最大重量", "チェック")
    .Range("A2").Resize(MAXQ.Count).Value = WorksheetFunction.Transpose(MAXQ.Keys)
    .Range("B2").Resize(MAXQ.Count).Value = WorksheetFunction.Transpose(MAXQ.Items)
    .Range("C2").Resize(MAXQ.Count).Value = WorksheetFunction.Transpose(OKNG.Items)
    .Select
  End With
  
End Sub

【77621】Re:マクロ化の検討
お礼  VBAビギナー  - 15/11/11(水) 8:36 -

引用なし
パスワード
   独覚さん

早速の回答ありがとうございます。
VBAではなく関数だけで、複雑な処理ができることに驚きました。
関数にも興味が持てたので、これから精進してまいります。

【77622】Re:マクロ化の検討
回答  VBAビギナー  - 15/11/11(水) 8:40 -

引用なし
パスワード
   βさん
回答ありがとうございます。
VBAでの例も大変参考になりました。
プログラムに美しさすら感じます。
本当にありがとうございました。

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