Home » excel » excel – Storing the first value in a sequence and use the stored values where the condition meets

excel – Storing the first value in a sequence and use the stored values where the condition meets

Posted by: admin May 14, 2020 Leave a comment

Questions:

I have this table and the VBA code has to fetch Value from Product where the Primary value is Yes. But, Value has to be the First Value in the Sequence.

+---------+---------+---------+
| Product | Results | Primary |
+---------+---------+---------+
| A       |         |         |
| B       |         | Yes     |
| C       |         | Yes     |
| D       |         |         |
| E       |         | Yes     |
| F       |         |         |
| G       |         | Yes     |
| H       |         | Yes     |
| I       |         |         |
+---------+---------+---------+

Expecting results:

+---------+---------+---------+
| Product | Results | Primary |
+---------+---------+---------+
| A       |         |         |
| B       | A       | Yes     |
| C       | A       | Yes     |
| D       |         |         |
| E       | D       | Yes     |
| F       |         |         |
| G       | F       | Yes     |
| H       | F       | Yes     |
| I       |         |         |
+---------+---------+---------+

I have tried this below vba code, but doesn’t work as i expected.

Sub test()
    Dim i As Long
    Dim lr As Long

    lr = ActiveSheet.UsedRange.Rows.Count

    For i = 2 To lr
        If Range("D" & i).Value = "Yes" Then
            Range("C" & i).Value = Range("B" & i - 1).Value
        End If
    Next
End Sub
How to&Answers:

Excel Formula

Here is an example of how your formula can look. This first looks to see if the primary field is “Yes“. If so, then it checks if the previous result also was a yes, and grabs it’s the result if so. Otherwise, it grabs the first value based on your example.

=IF($C2=”Yes”, IF($C1=”Yes”, $B1, $A1),””)

Adjust this as needed!


VBA Code

I would suggest creating a way of finding your headers, that way it is easier to update down the road in case it changes or there are more fields added. Below I added an example of what I would attempt to do.

I used a helper function (Inject) to build the actual formula and make it easier to read/debug if there are issues.

Feel free to add your own custom error handling as well.

Just note this is one of many ways you could tackle this. I could even break this formula into even smaller components to abstract as much of it as possible.

Option Explicit

Private Sub AddResultsToTable()

    Dim Ws As Worksheet
    Set Ws = ActiveSheet

    'FIND COLUMN HEADERS TO USE IN FORMULA REFERENCES
    With Ws.UsedRange

        On Error GoTo Catch
        Dim Product As Range
        Set Product = .Find("Product")

        Dim Results As Range
        Set Results = .Find("Results")

        Dim Primary As Range
        Set Primary = .Find("Primary")

    End With

    'CREATE FORMULA. Example: =IF($C2="Yes", IF($C1="Yes", $B1, $A1),"")
    Dim CustomFormula As String
    CustomFormula = Inject("=IF(
Option Explicit Private Sub AddResultsToTable() Dim Ws As Worksheet Set Ws = ActiveSheet 'FIND COLUMN HEADERS TO USE IN FORMULA REFERENCES With Ws.UsedRange On Error GoTo Catch Dim Product As Range Set Product = .Find("Product") Dim Results As Range Set Results = .Find("Results") Dim Primary As Range Set Primary = .Find("Primary") End With 'CREATE FORMULA. Example: =IF($C2="Yes", IF($C1="Yes", $B1, $A1),"") Dim CustomFormula As String CustomFormula = Inject("=IF(${0}='Yes', IF(${1}='Yes', ${2}, ${3}),'')", _ Primary.Offset(1).Address(False, True), _ Primary.Address(False, True), _ Results.Address(False, True), _ Product.Address(False, True) _ ) 'SET FIRST RANGE EQUAL TO FORMULA & AUTOFILL FORMULA DOWN With Results.Offset(1) .Value = CustomFormula .AutoFill Range(.Address, Ws.Cells(Ws.Rows.Count, Product.Column).End(xlUp).Offset(, 1)) End With Exit Sub Catch: 'You can do your error handling here. MsgBox Err.Description, vbCritical End Sub 'METHOD THAT ALLOWS A STRING TO BE REPLACED WITH VARIABLES AND SPECIAL CHARACTERS Public Function Inject(ByVal Source As String, ParamArray Args() As Variant) As String '@AUTHOR: ROBERT TODAR '@EXAMPLE: Inject("${0}, ${1}!", "Hello", "Robert") --> Hello, Robert! 'REPLACE SINGLE QUOTES WITH DOUBLE QUOTES Inject = Source Inject = Replace(Inject, "'", """") 'REPLACE ${#} WITH VALUES STORED IN THE VALUE IN THAT INDEX. Dim Index As Integer For Index = LBound(Args, 1) To UBound(Args, 1) Inject = Replace(Inject, "${" & Index & "}", Args(Index), , , vbTextCompare) Next Index End Function 
='Yes', IF(='Yes', , ),'')", _ Primary.Offset(1).Address(False, True), _ Primary.Address(False, True), _ Results.Address(False, True), _ Product.Address(False, True) _ ) 'SET FIRST RANGE EQUAL TO FORMULA & AUTOFILL FORMULA DOWN With Results.Offset(1) .Value = CustomFormula .AutoFill Range(.Address, Ws.Cells(Ws.Rows.Count, Product.Column).End(xlUp).Offset(, 1)) End With Exit Sub Catch: 'You can do your error handling here. MsgBox Err.Description, vbCritical End Sub 'METHOD THAT ALLOWS A STRING TO BE REPLACED WITH VARIABLES AND SPECIAL CHARACTERS Public Function Inject(ByVal Source As String, ParamArray Args() As Variant) As String '@AUTHOR: ROBERT TODAR '@EXAMPLE: Inject("
Option Explicit Private Sub AddResultsToTable() Dim Ws As Worksheet Set Ws = ActiveSheet 'FIND COLUMN HEADERS TO USE IN FORMULA REFERENCES With Ws.UsedRange On Error GoTo Catch Dim Product As Range Set Product = .Find("Product") Dim Results As Range Set Results = .Find("Results") Dim Primary As Range Set Primary = .Find("Primary") End With 'CREATE FORMULA. Example: =IF($C2="Yes", IF($C1="Yes", $B1, $A1),"") Dim CustomFormula As String CustomFormula = Inject("=IF(${0}='Yes', IF(${1}='Yes', ${2}, ${3}),'')", _ Primary.Offset(1).Address(False, True), _ Primary.Address(False, True), _ Results.Address(False, True), _ Product.Address(False, True) _ ) 'SET FIRST RANGE EQUAL TO FORMULA & AUTOFILL FORMULA DOWN With Results.Offset(1) .Value = CustomFormula .AutoFill Range(.Address, Ws.Cells(Ws.Rows.Count, Product.Column).End(xlUp).Offset(, 1)) End With Exit Sub Catch: 'You can do your error handling here. MsgBox Err.Description, vbCritical End Sub 'METHOD THAT ALLOWS A STRING TO BE REPLACED WITH VARIABLES AND SPECIAL CHARACTERS Public Function Inject(ByVal Source As String, ParamArray Args() As Variant) As String '@AUTHOR: ROBERT TODAR '@EXAMPLE: Inject("${0}, ${1}!", "Hello", "Robert") --> Hello, Robert! 'REPLACE SINGLE QUOTES WITH DOUBLE QUOTES Inject = Source Inject = Replace(Inject, "'", """") 'REPLACE ${#} WITH VALUES STORED IN THE VALUE IN THAT INDEX. Dim Index As Integer For Index = LBound(Args, 1) To UBound(Args, 1) Inject = Replace(Inject, "${" & Index & "}", Args(Index), , , vbTextCompare) Next Index End Function 
, !", "Hello", "Robert") --> Hello, Robert! 'REPLACE SINGLE QUOTES WITH DOUBLE QUOTES Inject = Source Inject = Replace(Inject, "'", """") 'REPLACE ${#} WITH VALUES STORED IN THE VALUE IN THAT INDEX. Dim Index As Integer For Index = LBound(Args, 1) To UBound(Args, 1) Inject = Replace(Inject, "${" & Index & "}", Args(Index), , , vbTextCompare) Next Index End Function

Answer:

Assuming cols A B C use the below formula in B2

=If(C2="yes", if(B1="",A1,B1),"")

Copy this to all the linea below.

This will work as long as the first item is not primary.

U can even include this formula in vba and do the copy paste in vba