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