Macro to compare old prices with new prices for stock and show(-/+)

KalilMe

Active Member
Joined
Mar 5, 2021
Messages
399
Office Version
  1. 2016
Platform
  1. Windows
Hello,
in QW sheet will be multiple columns contain prices and every time I will add new column contain new prices .
in STOCK sheet contains data in columns A:E
what I want create report in columns G:L with formatting and borders by brings the prices from last column in QW sheet and put in column J , as to column K=column I* column J
column L =column K- column E
in lastrow for column G when amount is minus in column L then populate LOSE word ,amount is plus in column L then populate PROFIT word.
if there is empty cell in last column in QW when brings price from previous column(not the first column) for instance if there is price in columnL,M,N and if the id doesn't existed price in column N then will brings from column M .
when create report will match BATCH column for two sheets , also if there is ID in STOCK sheet and it's not existed in QW sheet then will show as in STOCK sheet.


subtra.xlsm
JKLM
1ITEMBATCH01/11/202402/11/2024
21APP PP FRUIT12.0011.00
32BAN FF FRUIT9.00
43CU CMC VEG11.0011.00
54FRU BANN MU22.0023.00
65PI PIA FRUIT21.0021.00
76PO PTT VEG12.0011.00
87TO TMA VEG5.004.00
98TE TEE FOOD23.0018.00
109TRB POT BNG22.0024.00
QW




subtra.xlsm
ABCDEFGHIJKLMNO
1ITEMBATCHQTYUNIT PRICETOTAL
21TO TMA VEG10.005.0050.00
32PO PTT VEG20.0010.00200.00
43BAN FF FRUIT100.0012.001,200.00
54APP PP FRUIT100.0010.001,000.00
65PI PIA FRUIT12.0022.00264.00
76TE TEE FOOD100.0023.002,300.00
87CU CMC VEG120.0021.002,520.00
98TRB POT BNG100.0022.002,200.00
109FRU BANN MU124.0022.002,728.00
11
12
13
14
STOCK



result
subtra.xlsm
ABCDEFGHIJKLMNO
1ITEMBATCHQTYUNIT PRICETOTALITEMBATCHQTYUNIT PRICETOTALD/P
21TO TMA VEG10.005.0050.001TO TMA VEG10.004.0040.00-10.00
32PO PTT VEG20.0010.00200.002PO PTT VEG20.0011.00220.0020.00
43BAN FF FRUIT100.0012.001,200.003BAN FF FRUIT100.009.00900.00-300.00
54APP PP FRUIT100.0010.001,000.004APP PP FRUIT100.0011.001,100.00100.00
65PI PIA FRUIT12.0022.00264.005PI PIA FRUIT12.0021.00252.00-12.00
76TE TEE FOOD100.0023.002,300.006TE TEE FOOD100.0018.001,800.00-500.00
87CU CMC VEG120.0021.002,520.007CU CMC VEG120.0011.001,320.00-1,200.00
98TRB POT BNG100.0022.002,200.008TRB POT BNG100.0024.002,400.00200.00
109FRU BANN MU124.0022.002,728.009FRU BANN MU124.0023.002,852.00124.00
11LOSE-1,578.00
12
13
STOCK
Cell Formulas
RangeFormula
L2:L10L2=K2-E2
L11L11=SUM(L2:L10)

I need macro , I don't PQ or PT , formulas
thanks
 

Excel Facts

Control Word Wrap
Press Alt+Enter to move to a new row in a cell. Lets you control where the words wrap.
A bit hard to understand some of that written information but try this with a copy of your workbook.

VBA Code:
Sub PROFITorLOSE()
  Dim d As Object
  Dim a As Variant
  Dim i As Long, j As Long, cols As Long
  Dim OT As Double, GT As Double
  
  Set d = CreateObject("Scripting.Dictionary")
  With Sheets("QW")
    a = .Range("K1").Resize(.Cells(Rows.Count, "K").End(xlUp).Row, .Cells(1, Columns.Count).End(xlToLeft).Column - 10)
  End With
  cols = UBound(a, 2)
  For i = 2 To UBound(a)
    For j = cols To 2 Step -1
      If Len(a(i, j)) > 0 Then
        d(a(i, 1)) = a(i, j)
        Exit For
      End If
    Next j
  Next i
  With Sheets("STOCK")
    a = .Range("A1:F1").Resize(.Range("A" & Rows.Count).End(xlUp).Row + 1).Value
    a(1, 6) = "D/P"
    For i = 2 To UBound(a) - 1
      a(i, 4) = d(a(i, 2))
      OT = a(i, 5)
      a(i, 5) = a(i, 3) * a(i, 4)
      a(i, 6) = a(i, 5) - OT
      GT = GT + a(i, 6)
    Next i
    a(UBound(a), 6) = GT
    a(UBound(a), 1) = IIf(GT >= 0, "PROFIT", "LOSE")
    With .Range("G1").Resize(UBound(a), 6)
      .Value = a
      .Columns(3).Resize(, 4).NumberFormat = "#,##0.00"
      Union(.Rows(1), .Cells(UBound(a), 1)).Font.Bold = True
      .Columns.AutoFit
    End With
  End With
End Sub
 
Upvote 0
Code:
Sub test()
    Dim s$(1), i&, r As Range, c As Range, ws As Worksheet
    Set ws = Sheets("stock")
    ws.Columns("g:l").Clear
    With Sheets("qw").[a1].CurrentRegion
        Set r = .Columns(.Columns.Count + 1)
        r.Cells(1) = "UP"
        r.Cells(2).Resize(r.Rows.Count - 1).Formula2R1C1 = _
        Replace("=index(#,max(if(#<>"""",column(c3:c[-1])-2)))", "#", "rc3:rc[-1]")
    End With
    s(1) = "Provider=Microsoft.Ace.OLEDB.12.0;Data Source=" & _
    ThisWorkbook.FullName & ";Extended Properties='Excel 12.0;HDR=Yes';"
    s(0) = "Select A.`ITEM`, A.`BATCH`, A.`QTY`, B.`UP` As `UNIT PRICE`, " & _
        "A.`QTY` * B.`UP` As `TOTAL`, A.`QTY` * B.`UP` - A.`TOTAL` As `D/P` " & _
        "From `STOCK$` As A Left Join `QW$` As B On A.`BATCH` = B.`BATCH`;"
    With CreateObject("ADODB.Recordset")
        .Open s(0), s(1), 3, 3, 1
        For i = 0 To .Fields.Count - 1
            ws.Cells(1, i + 7) = .Fields(i).Name
        Next
        ws.[g2].CopyFromRecordset .DataSource
    End With
    r.Clear
    With ws.[g1].CurrentRegion
        .HorizontalAlignment = xlCenter
        .Columns("d:l").NumberFormat = "#,0.00"
        Union(.Rows(1), .Rows(.Rows.Count + 1)).Font.Bold = True
        Set c = .Cells(.Rows.Count + 1, .Columns.Count)
        c.Formula = "=sum(r2c:r[-1]c)"
        .Cells(.Rows.Count + 1, 1) = IIf(c > 0, "GAIN", "LOOSE")
        .EntireColumn.AutoFit
        .Resize(.Rows.Count + 1).Borders.Weight = 2
    End With
End Sub
 
Upvote 0
A bit hard to understand some of that written information
maybe expression is bad ,sorry !🙏
after testing obviously every thing is perfect .:)
just I would create borders, I would a slight modification if you don't mind, please.
I would show average price instead of brings price from last column in QW sheet.
example for ID "TE TEE FOOD" QW sheet=18 and the price in stock sheet=23 so when show in result will be average(18,23)=21
thanks
 
Upvote 0
@Fuji
thanks for writing code for me .:)
but unfortunately shows error
ER.PNG


ER2.PNG
 
Upvote 0
just I would create borders, I would a slight modification if you don't mind, please.
I would show average price instead of brings price from last column in QW sheet.
example for ID "TE TEE FOOD" QW sheet=18 and the price in stock sheet=23 so when show in result will be average(18,23)=21
Like this?

VBA Code:
Sub PROFITorLOSE_v2()
  Dim d As Object
  Dim a As Variant
  Dim i As Long, j As Long, cols As Long
  Dim OT As Double, GT As Double
  
  Set d = CreateObject("Scripting.Dictionary")
  With Sheets("QW")
    a = .Range("K1").Resize(.Cells(Rows.Count, "K").End(xlUp).Row, .Cells(1, Columns.Count).End(xlToLeft).Column - 10)
  End With
  cols = UBound(a, 2)
  For i = 2 To UBound(a)
    For j = cols To 2 Step -1
      If Len(a(i, j)) > 0 Then
        d(a(i, 1)) = a(i, j)
        Exit For
      End If
    Next j
  Next i
  With Sheets("STOCK")
    a = .Range("A1:F1").Resize(.Range("A" & Rows.Count).End(xlUp).Row + 1).Value
    a(1, 6) = "D/P"
    For i = 2 To UBound(a) - 1
      a(i, 4) = (d(a(i, 2)) + a(i, 4)) / 2
      OT = a(i, 5)
      a(i, 5) = a(i, 3) * a(i, 4)
      a(i, 6) = a(i, 5) - OT
      GT = GT + a(i, 6)
    Next i
    a(UBound(a), 6) = GT
    a(UBound(a), 1) = IIf(GT >= 0, "PROFIT", "LOSE")
    With .Range("G1").Resize(UBound(a), 6)
      .Value = a
      .Columns(3).Resize(, 4).NumberFormat = "#,##0.00"
      Union(.Rows(1), .Cells(UBound(a), 1)).Font.Bold = True
      .Columns.AutoFit
      .Borders.LineStyle = xlContinuous
    End With
  End With
End Sub
 
Upvote 0
ok seem to works except one problem , if there is new ID in stock sheet without it's existed in QW sheet then shouldn't Calculate average . should keep the price as it.
subtra.xlsm
ABCDEFGHIJKL
1ITEMBATCHQTYUNIT PRICETOTALITEMBATCHQTYUNIT PRICETOTALD/P
21TO TMA VEG10.005.0050.001TO TMA VEG10.0024.50245.00195.00
32PO PTT VEG20.0010.00200.002PO PTT VEG20.0032.50650.00450.00
43BAN FF FRUIT100.0012.001,200.003BAN FF FRUIT100.0010.501,050.00-150.00
54APP PP FRUIT100.0010.001,000.004APP PP FRUIT100.0014.001,400.00400.00
65PI PIA FRUIT12.0022.00264.005PI PIA FRUIT12.0044.00528.00264.00
76TE TEE FOOD100.0023.002,300.006TE TEE FOOD100.00178.0017,800.0015,500.00
87CU CMC VEG120.0021.002,520.007CU CMC VEG120.0019.002,280.00-240.00
98TRB POT BNG100.0022.002,200.008TRB POT BNG100.0027.502,750.00550.00
109ASD FGG TR124.0010.002,728.009ASD FGG TR124.005.00620.00-2,108.00
1110FRU BANN MU124.0022.002,728.0010FRU BANN MU124.0022.502,790.0062.00
12PROFIT14,923.00
STOCK


the right
subtra.xlsm
ABCDEFGHIJKL
1ITEMBATCHQTYUNIT PRICETOTALITEMBATCHQTYUNIT PRICETOTALD/P
21TO TMA VEG10.005.0050.001TO TMA VEG10.0024.50245.00195.00
32PO PTT VEG20.0010.00200.002PO PTT VEG20.0032.50650.00450.00
43BAN FF FRUIT100.0012.001,200.003BAN FF FRUIT100.0010.501,050.00-150.00
54APP PP FRUIT100.0010.001,000.004APP PP FRUIT100.0014.001,400.00400.00
65PI PIA FRUIT12.0022.00264.005PI PIA FRUIT12.0044.00528.00264.00
76TE TEE FOOD100.0023.002,300.006TE TEE FOOD100.00178.0017,800.0015,500.00
87CU CMC VEG120.0021.002,520.007CU CMC VEG120.0019.002,280.00-240.00
98TRB POT BNG100.0022.002,200.008TRB POT BNG100.0027.502,750.00550.00
109ASD FGG TR124.0010.002,728.009ASD FGG TR124.0010.00620.00-2,108.00
1110FRU BANN MU124.0022.002,728.0010FRU BANN MU124.0022.502,790.0062.00
12PROFIT14,923.00
STOCK


and should delete the data for columns G:L before update data because I notice the code will leave some formatting I don't need it depending on increase or decrease data for stock sheet.
 
Upvote 0
TRy this Code.
VBA Code:
Sub CreateTable()
Application.ScreenUpdating = False
Dim Lrq&, Lrs&, Lcs&, T&
Dim Frng1 As Range, Frng2 As Range

Lrq = Sheets("QW").Range("A" & Rows.Count).End(xlUp).Row
With Sheets("STOCK")
Lrs = .Range("A" & Rows.Count).End(xlUp).Row
Lcs = .Cells(1, Columns.Count).End(xlToLeft).Column
.Range("A1").CurrentRegion.Resize(, 3).Copy .Range("G1")
For T = 2 To Lrs
Set Frng1 = Sheets("QW").Range("B2:B" & Lrq).Find(.Range("H" & T).Value)
If Not Frng1 Is Nothing Then
.Range("J" & T) = Sheets("QW").Cells(Frng1.Row, Lcs + 1).End(xlToLeft)
End If
Next T
.Range("K2:K" & Lrs).Formula = "=I2*J2"
.Range("L2:L" & Lrs).Formula = "=K2-e2"
.Range("G1:J1").Copy .Range("J1")
.Range("J1:L1") = Array("UNIT PRICE", "TOTAL", "D/P")
.Range("H1").CurrentRegion.Borders.LineStyle = xlContinuous
End With

Application.ScreenUpdating = True
End Sub
 
Upvote 0
Upvote 0
try change
Code:
    With Sheets("qw").[a1].CurrentRegion
        Set r = .Columns(.Columns.Count + 1)
        r.Cells(1) = "UP"
        r.Cells(2).Resize(r.Rows.Count - 1).Formula2R1C1 = _
        Replace("=index(#,max(if(#<>"""",column(c3:c[-1])-2)))", "#", "rc3:rc[-1]")
    End With
to
Code:
    With Sheets("qw").[a1].CurrentRegion
        Set r = .Columns(.Columns.Count + 1)
        r.Cells(1) = "UP"
        r.Cells(2).FormulaArray = Replace("=index(#,max(if(#<>"""",column(c3:c[-1])-2)))", "#", "rc3:rc[-1]")
        r.Cells(2).Resize(r.Rows.Count - 1).FillDown
    End With
 
Upvote 0

Forum statistics

Threads
1,224,820
Messages
6,181,154
Members
453,021
Latest member
Justyna P

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