2

I have a table with column A containing incrementing numerical values, and column B being a bunch of names. I need to filter the table according the names, and have column C update with the difference between the value in column A in the current row and the cell above..

For example, I'd like to have something like this which, when filtered according to the Name column, should update the difference like so

I have tried to use SUBTOTAL function in a few different ways but to no avail. Ideally it'd update once the filter in the table is changed. I tried to do this in VBA but so far I've gotten macro that only filters with the hard-coded filter criteria.

Solutions in either excel formulas/python/vba are all welcomed and greatly appreciated!

I apologise in advance if this question isn't up to standards as Im new here :) Thank you in advance!

@JvdV: This is the outcome of me trying to implement your formula, This is after filtering.

bigbumbly
  • 33
  • 4
  • Looking at your screenshot, I believe you made a mistake with the ranges :). Please look carefully! If you can't find the error than let me know what formula there is currently in your cell C2. – JvdV Aug 17 '18 at 09:04

2 Answers2

1

REVISED ANSWER

So after your explenation I have looked into a formula that will give you the difference of the current row B-value minus the B-value of occurance of the A-value before that.

=IFERROR(B2-LOOKUP(2,1/($A$1:A1=A2),$B$1:B2),0)

Taking your sample data, it would look like this:

enter image description here

Then when you apply the filter, it would look like this:

enter image description here

So with this workaround you dont have the correct value when no filter is applied, but in this case I assumed you are interested in the difference when it IS filtered!

The formula is entered in cell C2 and dragged down.

EDIT

If this is not the answer you'r after and you DO need the values when it is not filtered, make use of a UDF like below:

Public Function LastVisibleCell(CL As Range) As Long

Dim RW As Long, X As Long
RW = CL.Row - 1
On Error GoTo 1

If RW > 1 Then
    For X = RW To 1 Step -1
        If ActiveSheet.Rows(X).EntireRow.Hidden Then
        Else
            LastVisibleCell = Cells(CL.Row, 2).Value - Cells(X, 2).Value
            Exit For
        End If
    Next X
Else
1:    LastVisibleCell = 0
End If

End Function

Call it from cell C2 like: =LastVisibleCell(A2) and drag down. When you apply your filter, the cells will update.

Beware, this will take ages to update on large datasets!

JvdV
  • 70,606
  • 8
  • 39
  • 70
  • Hi JvdV, thank you for your reply! unfortunately, that's not what i was looking for. Again, apologies for being vague, I've updated the question for clarity! – bigbumbly Aug 16 '18 at 01:17
  • Hi @JvdV, thank you! this works beautifully! I changed the data type to double to allow for decimal points though. Thank you again! – bigbumbly Aug 20 '18 at 05:21
0

After 3 days of intense (albeit ineffective) Google-ing, I finally came across this answer also on stack overflow.

However, as I'm working on a large set of data (>150,000 rows), the method in the question uses too much memory. Using VBA to paste the formulas into visible cells only does not seem to alleviate the problem.

Sub CopyPasteFormula()
    Dim Ws As Worksheet
    Dim LRow As Long
    Dim PasteRng As Range

    Set Ws = Worksheets("Translated Data")
    Ws.Range("$D$2:$D$200000").AutoFilter Field:=4, Criteria1:="<>-", Operator:=xlFilterValues
    LRow = Ws.Range("D" & Rows.Count).End(xlUp).Row
    Set PasteRng = Ws.Range("A3:A" & LRow).SpecialCells(xlCellTypeVisible)
    Ws.Range("A3").Copy
    PasteRng.PasteSpecial xlPasteFormulas
    Application.CutCopyMode = False
End Sub

Above is my macro code to attempt reduce the memory use... Appreciate any feedback!

Pang
  • 9,564
  • 146
  • 81
  • 122
bigbumbly
  • 33
  • 4
  • If all you interested in is to get the difference between the two rows when it's filtered you could apply a formula like: `=IFERROR(B3-LOOKUP(2,1/($A$2:A2=A3),$B$2:B2),"")`. If first row is headers than this goes into cell `B3`. Just drag down. This doesn't make much sense when no filter is applied. – JvdV Aug 16 '18 at 08:53
  • If you want to stay in the VBA codes, maybe look into using the filtervalue in a `.FindNext` loop pasting your formula. Also instead of pasting a formula, you could just get your needed value through vba extracting value with last visible cell. Code shouldn't be hard to put together. – JvdV Aug 16 '18 at 08:55
  • Hi @JvdV, your formula doesnt seem to work for me.. ideally i'd stay away from VBA and more to formulas. Thanks anyway! will continue searching – bigbumbly Aug 17 '18 at 06:36
  • the formula works with the following assumptions: 1) Names are in column A. 2) Numbers are in column B. 3). Headers in row 1. 4) Formula pasted in C3 (not B3, my bad), and need to be dragged down. If it doesnt work, please show me a screenshot of what you did. – JvdV Aug 17 '18 at 06:52
  • @JvdV, i attached the screenshot in the question. Also right now im working on a workaround based off some code i found online (cant find the link anymore): `Public Function NextVisibleCell(Range As Range) As Range Application.Volatile Dim i As Long Set Range = Range.Cells(Range.Rows.Count, Range.Columns.Count) For i = 1 To Rows.Count - Range.Row If Not Range.Offset(i).EntireRow.Hidden Then Set NextVisibleCell = Range.Offset(i) Exit Function End If Next i End Function ` but i cant get it to reference the previous row, only the current... – bigbumbly Aug 17 '18 at 08:37
  • I have revised my answer to try make it clear what I meant to do. – JvdV Aug 17 '18 at 08:49
  • @JvdV, sorry, forgot to update with the filtered table, it seems to leave blanks and the values don't tally up. Also, i'd like to see the differences when its not filtered too if it's possible. Could you take a look at the code above and guide me in changing it to reference the previous row? i thought changing the part `If Not Range.Offset(i).EntireRow.Hidden` to `If Not Range.Offset(i-2).EntireRow.Hidden` would help but it gave me haywire results. [link to original question is here](https://stackoverflow.com/questions/21593675/find-the-next-visible-row/21609341#21609341) – bigbumbly Aug 17 '18 at 09:04
  • Updated answer. – JvdV Aug 17 '18 at 09:38