他の列の値に基づいてセルを連結するVBAコード


0

これは私の日常のタスクで、画像1に示すように生データを取得し、データを並べ替える必要があります。通常、私が調べなければならないデータサンプルは、約2000行のアイテムです。

これを可能な限り合理化して、プロセスをステップに分解したいと思います。

  1. 列E(「CE名」)でデータを並べ替え、
  2. 列A(製品シリアル)および列E(「CE名」)の複製を条件付きでフォーマットし、
  3. G列(「原因コード」)で「L101」に等しくない値を探します(視覚的な目的で強調表示します)。
  4. (困難なステップ)列E(「CE名」)の値が同じで、列G(「原因コード」)の値が「L101」と等しくない場合、それらの値を分離します。

    注:これにより、2つのサンプルデータセットが作成されます。

    データサンプル1:列G(「原因コード」)に「L101」値を含むセットまたは単一行になります。

    データサンプル2:列G(「原因コード」)に「L101」値を含まないセットまたは単一行になります。

    EX:1画像1の行4および5、「C-375204」には、L101と等しくない2列G(「原因コード」)値があります。これが「データサンプル2」になります。

    EX:2イメージ1の行8および9、「C-375306」には「L101」および「L208」の列G(「原因コード」)値があります。「L101」値が存在するため、「データサンプル」になります。 1 "。

    EX:3イメージ1の行12および13、「C-376157」には2列G(「原因コード」)値「L101」があります。これは「データサンプル1」になります。

  5. すべてのデータが並べ替えられたら、コンマ( "、")で区切られた列E( "CE名")の値に基づいて、列B( "Symp")の値を連結します。

    例:画像1の行4および5、「C-375204」は列B(「Symp」)が画像3の行24の画像として「LM01、LM01」として表示されます。

  6. 余分なデータを削除して、画像3に示す最終製品を終了します。

生データ(画像1) 画像1:生データ

ペア(画像2) 画像2:ペア

最終データ(画像3) 画像3:最終データ


興味深いことに、はい、マクロを記録してフレームワークを提供し、それを一般化できます。ただし、ニーズを理解していれば、ピボットテーブルで問題を解決できるかもしれません。連結は行いませんが、探していると思うグループを作成します。たぶん十分であろうこと...
gns100

残念ながら、連結されたデータは、提示された最終データに最も関連しています。私は長い間「手動」でデータをソートしてきました。私はいくつかのVBAを学び始めましたが、これは私の現在の能力から外れています。
マーク

データサンプルをどのように分離しますか?画像3のように、空の行で区切られた同じテーブルにありますか?何かを並べ替えれば壊れませんか?LC106855とLC109164が異なるサンプルになるのはなぜですか?
クリストファーウェーバー

データサンプルはここでは空白行で区切られていますが、必須ではありません。別のシートにすることができます。手動プロセスであるため、ここで空白行で区切るだけです。ソートを混乱させないように、これを作成したときに最上位のデータセットのみを自動フィルター処理しました。あなたも正しいです。このデータセットをすばやくまとめたときに間違えました。LC109164は2ではなく「データサンプル1」の一部である必要があります
マーク

回答:


0

私はそれを磨く時間がありませんでしたし、いくつかのショートカットがありますが、これはあなたが求めていることに沿って何かをするはずです。

このコードは、マクロを実行しているシートの左上にテーブルがあることを想定しています。2つの新しいシートを作成し、そこにデータをダンプします。

Sub Sort()

Dim name As String, i As Integer, nameRange As Range, savedRange As Range, firstRange As Range, obj As Variant
'Set "E" to whatever Column contains the "CE Name"
Set nameRange = ActiveSheet.Range(Range("E2"), Range("E65000").End(xlUp))
Set savedRange = Nothing

'Make new sheets for sorted data
If Evaluate("ISREF('" & "Data 1" & "'!A1)") = False Then
    Sheets.Add(After:=ActiveSheet).name = "Data 1"
    Sheets.Add(After:=ActiveSheet).name = "Data 2"
End If

For Each obj In nameRange
    'Make Group
    If savedRange Is Nothing Then
            Set savedRange = Range(obj.Address)
            Set firstRange = Range(obj.Address)
    Else
            Set savedRange = Range(savedRange.Address, obj.Address)
    End If

    'Print Group
    If Not obj.Offset(1).Value = obj.Value Then
        If Not savedRange.Offset(0, 2).Find("L101 - Cycler", LookIn:=xlValues) Is Nothing Then
            'Data range 1
            Rows(firstRange.Row).Copy
            Sheets("Data 1").Range("A1").Insert
            Sheets("Data 1").Range("B1").Value = ConcatenateRow(savedRange.Offset(0, -3), ",")
        Else
            'Data Range 2
            Rows(firstRange.Row).Copy
            Sheets("Data 2").Range("A1").Insert
            Sheets("Data 2").Range("B1").Value = ConcatenateRow(savedRange.Offset(0, -3), ",")
        End If
        'reset group
        Set savedRange = Nothing
    End If

Next obj


End Sub

Function ConcatenateRow(rowRange As Range, joinString As String) As String
    Dim x As Variant, temp As String

    temp = ""
    For Each x In rowRange
        temp = temp & x & joinString
    Next

    ConcatenateRow = Left(temp, Len(temp) - Len(joinString))
End Function

クリストファー、コードに感謝します。これは非常に役立ちます。私は賛成票を投じるのに十分な評判がありません。また、上で書いたこのためにいくつかのコードに取り組んでいます。あなたは時間があれば、あなたがそれを検討し、いくつかの建設的なフィードバック/提案与えることができれば、私は大好きだ
マーク・

0

皆からの助けに感謝します。私はこれに精力的に取り組んでおり、多くのことを学びました。そのために書いたコードを共有したかったのです。使用したコードにコメント付きの参照をいくつか含めました。また、ご提案がありましたら、ぜひお聞かせください。

このコードは:

ユーザーが特定した原因値のディクショナリを作成して、原因となる値のディクショナリを作成し、CE-Nameが一致する原因値のディクショナリを作成します。

一致するCE名を持つSympを連結し、「ユーザーが特定した原因値」が一致するCE原因ディクショナリに存在しない限り、強調表示することにより連結されたセルを識別します。

余分な(不要な行)行をN / Aとして識別します

N / Aの行を削除します

次に、識別された(色付きの)行でデータを並べ替えます

Private Sub Auto_Combine() 'Step 5 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'******************************************************************************
'WIP Auto Combine cells based on Symp value

'******************************************************************************
'Variables

Dim PrevRefCell As String 'Refers to the Complaint Number Column A
Dim CurrRefCell As String 'Refers to the Complaint Number Column A
Dim PrevCombCell As Range
Dim CurrCombCell As Range
Dim PrevSympCell As String
Dim CurrSympCell As String
Dim PrevCausCell As Range
Dim CurrCausCell As Range

Dim FirstFour As String
Dim PrevFirstFour As String

Dim sh As Worksheet
Dim rn As Range
Dim k As Long
Dim CurRRow As Long
Dim PrevRow As Long
Dim i As Long

Dim Flag As Boolean



    Dim CauseDict As Object
    Set CauseDict = CreateObject("Scripting.Dictionary")
    CauseDict.Add "L101", "L101"
    CauseDict.Add "X101", "X101"
    CauseDict.Add "L304", "L304"

    Dim CauseDictItem As Variant


    Dim CurCauseDict As Object
    Set CurCauseDict = CreateObject("Scripting.Dictionary")

    Dim j As Variant
    Dim l As Variant

    Dim RefDict As Object
    Set RefDict = CreateObject("Scripting.Dictionary")




'******************************************************************************
'Counts Number Of active rows in ActiveSheet and set to variable "k"
'https://stackoverflow.com/questions/25056372/vba-range-row-count

Set sh = ThisWorkbook.ActiveSheet
'Set rn = sh.UsedRange
Set rn = Range("A1", sh.Range("A1").End(xlDown).End(xlDown).End(xlUp))
k = rn.Rows.Count + rn.Row - 1

'******************************************************************************
'Use this to incrememnt actual address
'Sets Values of ref cells to cell contents

'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
'For Loop A Begin
For CurRRow = 1 To k ' set row value currently at max row "k"

'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
'Insert Instructions Set below

    PrevRow = CurRRow - 1
'Assign increment cell locations to variables
    CurrRefCell = ActiveSheet.Range("A" & CurRRow).Value
    CurrSympCell = ActiveSheet.Range("P" & CurRRow).Value


    On Error GoTo ErrHandler:

    PrevRefCell = ActiveSheet.Range("A" & PrevRow).Value
    PrevSympCell = ActiveSheet.Range("P" & PrevRow).Value

                                        'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                                        'Nested Loop A.1 Begin
                                        'Compare Values and does set of instruction based on those values. in this case
                                        '"PrevRefCell" and "CurrRefCell"

                                        If InStr(CurrRefCell, PrevRefCell) > 0 Then ' If A.1
                                        'https://www.techonthenet.com/excel/formulas/instr.php
                                        'https://www.techonthenet.com/excel/formulas/if_then.php
                                        ' combine Symptom code combos to combo cell in column "O"

                                            Set CurrCombCell = ActiveSheet.Range("O" & CurRRow)
                                            Set PrevCombCell = ActiveSheet.Range("O" & PrevRow)

                                            CurrCombCell.Value = CurrSympCell & "," & PrevCombCell.Value

                                            Set CurrCausCell = ActiveSheet.Range("R" & CurRRow)
                                            Set PrevCausCell = ActiveSheet.Range("R" & PrevRow)

                                        ' After Combo is made N/A previous combo cell
                                            PrevCombCell.Value = "N/A"

                                            FirstFour = Left(CurrCausCell, 4)
                                            PrevFirstFour = Left(PrevCausCell, 4)

                                            If Not CurCauseDict.Exists(PrevFirstFour) Then
                                            CurCauseDict.Add PrevFirstFour, PrevFirstFour
                                            End If

                                            If Not CurCauseDict.Exists(FirstFour) Then
                                            CurCauseDict.Add FirstFour, FirstFour
                                            End If



                                                                                        ' Look for non "L101" cause codes can highlight CurrCombCell Yellow based on values
                                                                                        i = i - 1
                                                                                        'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                                                                                        'Nested Loop A.1.1 If Begin

                                                                                            For Each l In CurCauseDict.Keys
                                                                                                If CauseDict.Exists(l) Then
                                                                                                Flag = True
                                                                                                End If
                                                                                            Next
                                                                                                    If Flag = True Then
                                                                                                    '__________________
                                                                                                        Else
                                                                                                        CurrCombCell.Select
                                                                                                        With Selection.Interior
                                                                                                        .Pattern = xlSolid
                                                                                                        .PatternColorIndex = xlAutomatic
                                                                                                        .Color = 65535
                                                                                                        End With
                                                                                                    End If
ColorSKIP: '-----------------------------------------------------------------------------
                                                                                'Nested Loop A.1.1 If End
                                                                                'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                                        'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                                        'Nested Loop A.1 Else Begin
                                        ' if only single line item assign current symp to current comb location
                                        Else 'A.1 Else Begin

                                            CurCauseDict.RemoveAll

                                            i = 0
                                            Set CurrCombCell = ActiveSheet.Range("O" & CurRRow)
                                            CurrCombCell.Value = CurrSympCell
                                            Set CurrCausCell = ActiveSheet.Range("R" & CurRRow)

                                            FirstFour = Left(CurrCausCell, 4)

                                            If Not CurCauseDict.Exists(FirstFour) Then
                                            CurCauseDict.Add FirstFour, FirstFour
                                            On Error Resume Next
                                            End If

                                                                                'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                                                                                'Nested Loop A.1.2 If Begin
                                                                                    For Each j In CurCauseDict.Keys
                                                                                        If Not CauseDict.Exists(j) Then ' if current "beginning" dict key is in "ending" dict
                                                                                            CurrCombCell.Select
                                                                                            With Selection.Interior
                                                                                            .Pattern = xlSolid
                                                                                            .PatternColorIndex = xlAutomatic
                                                                                            .Color = 65535
                                                                                            End With

                                                                                            CurCauseDict.RemoveAll
                                                                                            Flag = False
                                                                                        End If
                                                                                     Next
                                                                                  'Nested Loop A.1.2 If End
                                                                                'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
                                        End If 'A.1 Else End
                                        'Nested Loop A.1 Else End
                                        'Nested Loop A.1 If End
                                        'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ErrHandler:
Next CurRRow
'For Loop A End
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


End Sub

Sub AA2_NA_Data_Sort() 'Step 6 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
'******************************************************************************
'Variables

Dim PrevRefCell As String
Dim CurrRefCell As String

Dim sh As Worksheet
Dim rn As Range
Dim k As Long
Dim CurRRow As Long
Dim PrevRow As Long


Range("A1").Select

'******************************************************************************
'Counts Number Of active rows in ActiveSheet and set to variable "k"
'https://stackoverflow.com/questions/25056372/vba-range-row-count

Set sh = ThisWorkbook.ActiveSheet
'Set rn = sh.UsedRange
Set rn = Range("A1", sh.Range("A1").End(xlDown).End(xlDown).End(xlUp))
k = rn.Rows.Count + rn.Row - 1

'******************************************************************************
'Use this to incrememnt actual address
'Sets Values of ref cells to cell contents

'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
'For Loop A Begin
    For CurRRow = 1 To k ' set row value currently at max row "k"

'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
'Insert Instructions Set below

    PrevRow = CurRRow - 1

    CurrRefCell = ActiveSheet.Range("O" & CurRRow).Value

    On Error GoTo ErrHandler:
    PrevRefCell = ActiveSheet.Range("O" & PrevRow).Value

'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
'Nested Loop A.1 Begin
'Compare Values and does set of instruction based on those values. in this case
'"PrevRefCell" and "CurrRefCell"

    If InStr(CurrRefCell, "N/A") > 0 Then
    'https://www.techonthenet.com/excel/formulas/instr.php
    'https://www.techonthenet.com/excel/formulas/if_then.php
    ActiveSheet.Range("A" & CurRRow).Activate
    Range(Selection, Selection.End(xlToRight)).Select
    Selection.ClearContents

    End If

'    Else

'Nested Loop A.1 Else End
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

'For Loop End
'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
ErrHandler:
    Next CurRRow


End Sub

Sub AA3_Color_Sort() 'Step 7 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

    '******************************************************************************
'Sort by CE Name
    ActiveSheet.AutoFilter.Sort.SortFields.Clear
    ActiveSheet.AutoFilter.Sort.SortFields.Add key:=Range _
        ("A:A"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortNormal
    With ActiveSheet.AutoFilter.Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

'******************************************************************************
'Sort By Color no fill on top

'    Range("A1:U120").Select
    ActiveSheet.AutoFilter.Sort.SortFields.Clear
    ActiveSheet.AutoFilter.Sort.SortFields.Add key:=Range _
        ("O:O"), SortOn:=xlSortOnCellColor, Order:=xlAscending, DataOption:= _
        xlSortNormal

    With ActiveSheet.AutoFilter.Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply

    End With
 End Sub
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.