Evaluate data for any price changes

ItalianPlatinum

Well-known Member
Joined
Mar 23, 2017
Messages
803
Office Version
  1. 365
  2. 2019
Platform
  1. Windows
I am trying to find a way to easily know if any price changes from a very large dataset. Over 100k rows. Currently I am filtering by frequency, then using pivot tables and its cumbersome. I am looking if I can just have a column called "changes" so I only have to focus on any duplicates that have changes. There could be a lot of duplicates with the same price but I don't really care about those. The unique Identifier column A is what sets them apart. I did a snipbit below using XLBB to give a frame of reference what I am dealing with. In the future I will probably looking for a way to give me the changes but for right now babysteps and just looking for changes "Yes or No". Thank you as always for helping look at this.

Book1
ABCDEFGHIJ
5Not really needed if I have column J workingHELP
6IdentifierUnique IdentifierGroupGroup Class Price SKUFileFile NameFrequencyAny Change?
7AAA123456789Team11$ 10.00SKUAAANonFXXXXXXX12
8BBB987654321Team12$ 10.50SKUBBBNonFXXXXXXX11
9CCC112233446Team21$ 75.00SKUCCCNonFXXXXXXX11
10DDD124512566Team22$ 69.80SKUDDDNonFXXXXXXX11
11EEE122456789Team23$ 100.25SKUEEENonFXXXXXXX12
12FFF324512566Team34$ 100.00SKUFFFNonFXXXXXXX12
13GGG924512566Team35$ 74.00SKUGGGNonFXXXXXXX12
14HHH712233446Team498$ 9.00SKUHHHNonFXXXXXXX14
15III522456789Team598$ 5.60SKUIIINonFXXXXXXX13
16LLL624512566Team698$ 7.50SKULLLNonFXXXXXXX13
17AAA123456789Team11$ 9.00SKUAAANonFXXXXXXX12
18EEE122456789Team23$ 5.00SKUEEENonFXXXXXXX12
19FFF324512566Team34$ 7.00SKUFFFNonFXXXXXXX12
20GGG924512566Team35$ 74.00SKUGGGNonFXXXXXXX12
21HHH712233446Team498$ 9.00SKUHHHNonFXXXXXXX14
22III522456789Team598$ 5.60SKUIIINonFXXXXXXX13
23LLL624512566Team698$ 4.00SKULLLNonFXXXXXXX13
24HHH712233446Team498$ 9.00SKUHHHNonFXXXXXXX14
25III522456789Team598$ 5.60SKUIIINonFXXXXXXX13
26LLL624512566Team698$ 7.50SKULLLNonFXXXXXXX13
27HHH712233446Team498$ 10.00SKUHHHNonFXXXXXXX14
28III522456789Team598$ 5.60SKUIIINonFXXXXXXX13
29LLL624512566Team698$ 111.00SKULLLNonFXXXXXXX13
30LLL624512566Team698$ 123.00SKULLLNonFXXXXXXX13
Sheet1
Cell Formulas
RangeFormula
F7:F30F7="SKU"&A7
I7:I30I7=COUNTIF($A$7:$A$27,A7)
 
So I got spoiled by Etafs formulas because it also kicked back the price changes which I will eventually need. I for some reason cannot get yours to run my data starts on row 7 so i modified as so on my copy. thoughts? is there a way to capture that component too? There is no way to play his formula through VBA in anyway?

it got stuck at this:
VBA Code:
If id(i, 1) = id(j, 1) And price(i, 1) <> price(j, 1) Then

VBA Code:
Sub PriceChanges()
    Dim id, price, output()
    Dim i As Long, j As Long, numRow As Long
    Dim ws As Worksheet
    Dim checkedIDs As Object
    Set checkedIDs = CreateObject("Scripting.Dictionary")
   
    Set ws = ThisWorkbook.Worksheets("Sheet1")
   
    numRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    id = ws.Range("A7:A" & numRow).Value2
    price = ws.Range("E7:E" & numRow).Value2
    ReDim output(1 To numRow, 1 To 1)
   
    For i = 1 To numRow - 1
        If Not checkedIDs.exists(id(i, 1)) Then
            checkedIDs.Add id(i, 1), ""
            For j = i + 1 To numRow - 1
                If id(i, 1) = id(j, 1) And price(i, 1) <> price(j, 1) Then
                    checkedIDs(id(i, 1)) = "yes"
                    output(i, 1) = checkedIDs(id(i, 1))
                    Exit For
                Else
                    checkedIDs(id(i, 1)) = "no"
                    output(i, 1) = checkedIDs(id(i, 1))
                End If
            Next j
        Else
            output(i, 1) = checkedIDs(id(i, 1))
        End If
    Next i
   
    ws.Range("J7").Resize(UBound(output, 1), 1).Value = output
End Sub
 
Upvote 0

Excel Facts

When they said...
When they said you are going to "Excel at life", they meant you "will be doing Excel your whole life".
How about this? Adjusted for data in row 7 and returned the new price for the first instances.
VBA Code:
Sub PriceChanges2()
    Dim id, price, output()
    Dim i As Long, j As Long, numRow As Long
    Dim ws As Worksheet
    Dim checkedIDs As Object
    Set checkedIDs = CreateObject("Scripting.Dictionary")
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    numRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    id = ws.Range("A7:A" & numRow).Value2
    price = ws.Range("E7:E" & numRow).Value2
    ReDim output(1 To numRow, 1 To 2)
    For i = 1 To numRow - 6 'data row minus 1
        If Not checkedIDs.exists(id(i, 1)) Then
            checkedIDs.Add id(i, 1), price(i, 1)
            For j = i + 1 To numRow - 6 'data row minus 1
                If id(i, 1) = id(j, 1) And price(i, 1) <> price(j, 1) Then
                    checkedIDs(id(i, 1)) = "yes"
                    checkedIDs(price(i, 1)) = price(j, 1)
                    output(i, 1) = checkedIDs(id(i, 1))
                    output(i, 2) = checkedIDs(price(i, 1))
                    Exit For
                Else
                    checkedIDs(id(i, 1)) = "no"
                    checkedIDs(price(i, 1)) = price(j, 1)
                    output(i, 1) = checkedIDs(id(i, 1))
                    output(i, 2) = price(i, 1)
                End If
            Next j
        Else
            output(i, 1) = checkedIDs(id(i, 1))
            output(i, 2) = ""
        End If
    Next i
    ws.Range("J7").Resize(UBound(output, 1), 2).Value = output
End Sub
 
Last edited:
Upvote 0
Ok that works at least but the data is considerably different than the formula route. is there no way me for to just set that sort, unque filter formula in a range? I even tried Forumula2 and that didnt work

1713052966868.png


1713053017458.png
 
Upvote 0
Not getting what you’re trying to do. If you want a formula why use a macro to insert a formula? Why not just use the formula?
 
Upvote 0
I have users running the VBA daily so I cannot "leave" a formula in that cell. The VBA kicks off with deleting all cells in each sheet then running through its process. So is there no way just to "place" a formula in the range as if I am doing myself? I am sure I am over simplifying something that is more complex than that. I am sure replicating it via VBA is cumbersome.
 
Upvote 0
Ok having slight problem getting it set with VBA when I do the below which i think should work it says "TRUE" regardless of changes or not. Do you see anything visibly wrong I am doing?
This was not the original question but just in terms of converting @etaf formula to VBA you can give this a try.
PS: Normally people just use a single "@" I just wanted it to stand out. It is a place holder that the replace uses to insert the last row value.
I expect it will only work in MS365 or O 2021 though

VBA Code:
Sub AddFormula()

Dim WsSummary As Worksheet, WsChanges As Worksheet
Dim lrS As Long
Dim strForm As String

Set WsSummary = Worksheets("Summary")
Set WsChanges = Worksheets("Changes")

With WsSummary
    lrS = .Cells(Rows.Count, "E").End(xlUp).Row
End With

With WsChanges
    .Cells.ClearContents
    strForm = "=SORT(UNIQUE(FILTER(Summary!$A$7:$H$@@@,COUNTIFS(Summary!$A$7:$A$@@@,Summary!$A$7:$A$@@@,Summary!$E$7:$E$@@@,""<>""&Summary!$E$7:$E$@@@)>0,""No Changes""),1))"
    .Range("A2").Formula2 = Replace(strForm, "@@@", lrS)

End With

End Sub
 
Upvote 0
Nice, wonderful that worked. Thanks for all of you for helping me on this. Think I am all set here. Not too sure the concept of @@@ but it sure worked lovely
 
Upvote 0
If you're working with a large data set consider using VBA arrays to optimize performance.
What do you consider as duplicate record? Do you only look at the Identifier and Price ... Or do you consider other columns as well?
 
Upvote 0
This VBA formula simulates the FILTER, SORT and UNIQUE using VBA arrays. It also only considers Identifier and Price for duplicate records (unless you indicate otherwise). See the comparison to the provided formula by@etaf. There should be a significant difference in performance compared to using the formula, however, it's harder to maintain. See which option is better for you.
Book1
QRSTUVWXYAJAKALAMANAOAPAQARAS
2etafetafetafetafetafetafetafetafCubistCubistCubistCubistCubistCubistCubistCubistCubistCubist
3AAA123456789Team1110SKUEEENonFXXXXXXX1AAA1.23E+08Team1110SKUEEENonFXXXXXXX12Yes
4AAA123456789Team119SKUHHHNonFXXXXXXX1AAA1.23E+08Team119SKUHHHNonFXXXXXXX14Yes
5EEE122456789Team23100.25SKUIIINonFXXXXXXX1EEE1.22E+08Team23100.25SKUIIINonFXXXXXXX14Yes
6EEE122456789Team235SKUIIINonFXXXXXXX1EEE1.22E+08Team235SKUIIINonFXXXXXXX14Yes
7FFF324512566Team34100SKULLLNonFXXXXXXX1FFF3.25E+08Team34100SKULLLNonFXXXXXXX15Yes
8FFF324512566Team347SKULLLNonFXXXXXXX1FFF3.25E+08Team347SKULLLNonFXXXXXXX15Yes
9HHH712233446Team4989SKUEEENonFXXXXXXX1HHH7.12E+08Team49810SKUNonFXXXXXXX10Yes
10HHH712233446Team4989SKUIIINonFXXXXXXX1LLL6.25E+08Team6984SKUHHHNonFXXXXXXX14Yes
11HHH712233446Team4989SKUIIINonFXXXXXXX1LLL6.25E+08Team698111SKUNonFXXXXXXX10Yes
12HHH712233446Team49810SKUNonFXXXXXXX1LLL6.25E+08Team698123SKUNonFXXXXXXX10Yes
13LLL624512566Team6987.5SKUGGGNonFXXXXXXX1
14LLL624512566Team6984SKUHHHNonFXXXXXXX1
15LLL624512566Team6987.5SKULLLNonFXXXXXXX1
16LLL624512566Team698111SKUNonFXXXXXXX1
17LLL624512566Team698123SKUNonFXXXXXXX1
Sheet4
Cell Formulas
RangeFormula
Q3:X17Q3=SORT(UNIQUE(FILTER(A3:H26,COUNTIFS($A$3:$A$26,$A$3:$A$26,$E$3:$E$26,"<>"&$E$3:$E$26)>0),1))
AJ3:AS12AJ3=SORT(Z3:AI12)
Dynamic array formulas.

VBA Code:
Sub PriceChanges4()
    Dim id, price, output()
    Dim i As Long, numRow As Long
    Dim ws As Worksheet
    Dim uniquePrices As Object
    Set uniquePrices = CreateObject("Scripting.Dictionary")
 
    Set ws = ThisWorkbook.Worksheets("Sheet1")
    numRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
    id = ws.Range("A6:A" & numRow).Value2
    price = ws.Range("E6:E" & numRow).Value2
 
    ReDim output(1 To numRow, 1 To 1)
    For i = 2 To numRow - 5
        If Not uniquePrices.exists(id(i, 1)) Then
            uniquePrices.Add id(i, 1), CreateObject("Scripting.Dictionary")
        End If
        If Not uniquePrices(id(i, 1)).exists(price(i, 1)) Then
            uniquePrices(id(i, 1)).Add price(i, 1), "Yes"
        Else
            uniquePrices(id(i, 1))(price(i, 1)) = "No"
        End If
    Next i
    ' Check if there's only one price for each ID and mark as "No"
    For i = 2 To numRow - 5
        If uniquePrices(id(i, 1)).Count = 1 Then
            uniquePrices(id(i, 1))(price(i, 1)) = "No"
        End If
    Next i
 
    For i = 2 To numRow - 5
        output(i - 1, 1) = uniquePrices(id(i, 1))(price(i, 1))
    Next i
    ' Output the result to the worksheet
    ws.Range("J7").Resize(UBound(output, 1), 1).Value = output
 
    With Range("A6:J" & Range("A" & Rows.Count).End(xlUp).Row)
        .AutoFilter Field:=10, Criteria1:="Yes" 'Field 10 = Column J
        .Sort key1:=Range("A6"), order1:=xlAscending, Header:=xlYes
        .Copy Range("Q6")
        .AutoFilter
    End With
 
End Sub
 
Upvote 0
If you're working with a large data set consider using VBA arrays to optimize performance.
What do you consider as duplicate record? Do you only look at the Identifier and Price ... Or do you consider other columns as well?
yea just identifier and price. I will give your code a try. Because I am working with a lot of data so there could be some performance degradation - i have yet to try either on the big data set.
 
Upvote 0

Forum statistics

Threads
1,216,520
Messages
6,131,135
Members
449,626
Latest member
Stormythebandit

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top