Formula apply to certain rows - excel

I am working on a macro that was previously written by an old employee. I am a new VBA user so I am not versed on how to properly do this.
I need the formula to not apply to rows where "IBK" is present. Right now it is applying to every row.
I have tried to actually just re-write and filter the different criteria and apply the formula that way, however, the macro wouldn't work
this is the formula
Columns("Q:Q").Select
Selection.Clear
Range("Q1").Select
ActiveCell.FormulaR1C1 = "New Savings"
Range("Q2").Select
ActiveCell.Formula = "=P2-(7/D2)"
Selection.AutoFill Destination:=Range("Q2:Q" & Range("A" &
Rows.Count).End(xlUp).Row)
Range("Q2")
Picture attached is the sample data. I obviously work with far more data than this. I need the formula to know not to subtract 7 from the IBK through the macro. So the IBK’s would total 50 instead of 43.
Picture :

Read the comments and adjust the parameters
Sub ApplyFormula()
Dim evalSheet As Worksheet
Dim formulaRange As Range
Dim worksheetName As String
Dim colEval As String
Dim colFormula As String
Dim formulaText As String
Dim colNumber As Integer
Dim firstRow As Byte
Dim lastRow As Long
' 1) Set some parameters
' Define name of sheet where formulas are going to be added
worksheetName = "sheet1"
Set evalSheet = ThisWorkbook.Worksheets(worksheetName)
'Set evalSheet = Sheet1 ' -> This could come from VBA Editor and replace the previous two lines. It's safer if you use the sheet vba codename see https://stackoverflow.com/questions/41477794/refer-to-sheet-using-codename
' Define the column letter where Managed Type is localted
colEval = "A"
' Define the column letter where Formulas should be added (New savings)
colFormula = "D"
' Define where evaluated range begins
firstRow = 2
' Define formula text. text between [] will be replaced
formulaText = "=IF([colEval][firstRow] = 'IBK', P[firstRow], P[firstRow] - (7 / D[firstRow]))"
' 2) Adjust stuff and add the formulas
' Adjust the formula to replace the single quotes with doubles
formulaText = Replace(formulaText, "'", """")
formulaText = Replace(formulaText, "[colEval]", colEval)
formulaText = Replace(formulaText, "[firstRow]", firstRow)
' Get the column number from the column letter
colNumber = Columns(colEval).Column
' Get the last row with data in column evaluated
lastRow = evalSheet.Cells(evalSheet.Rows.Count, colNumber).End(xlUp).Row
' Set the range to be evaluated
Set formulaRange = evalSheet.Range(colFormula & firstRow & ":" & colFormula & lastRow)
' Add the formulas
formulaRange.Formula = formulaText
End Sub

Make the following changes
'add 4 lines
Dim colIBK As String, newFormula As String
On Error Resume Next
colIBK = Split(Cells(1, Application.Match("Managed Type", Range("A1:BB1"), 0)).Address(True, False), "$")(0)
On Error GoTo 0
Columns("Q:Q").Select
Selection.Clear
Range("Q1").Select
ActiveCell.FormulaR1C1 = "New Savings"
Range("Q2").Select
'add 1 line and change the next
newFormula = "=if(" & colIBK & "2 = ""IBK"","""",P2-(7/D2))"
ActiveCell.Formula = newFormula
Selection.AutoFill Destination:=Range("Q2:Q" & Range("A" & Rows.Count).End(xlUp).Row)
Range("Q2").Select
After getting colIBK, you might test for "" and bail out with error message
if the column is not found.
newFormula could also be just P2 "=if(" & colIBK & "2 = ""IBK"",P2,P2-(7/D2))"

Related

Formula in first blank and filled down to end of data

I have the below code where in all other columns there is many populated rows, what I need this formula to do in column F is to find the first blank, then place the formula in it and fill it down to the last row.
What is currently happening is I have the range as F26 as this is usually first blank but this could change and I want the code to identify this and also have the formula dynamically know what row it is on, so for example if one month the first blank was in cell F30 the range would find it and the formula would start as E30*G30.
Any help would be greatly appreciated.
Private Sub calc()
Dim lastrow As Long
Dim rng As Range
lastrow = ThisWorkbook.Worksheets("Indiv").Cells(Rows.Count, 1).End(xlUp).Row
Set rng = Range("F26:F" & lastrow)
rng.Formula = "=Round((E26*G26),2)"
End Sub
You need to find the first free row in column F and then bulid your formula with this row:
Option Explicit
Private Sub calc()
Dim ws As Worksheet ' define worksheet
Set ws = ThisWorkbook.Worksheets("Indiv")
Dim LastRowA As Long ' find last used row in column A
LastRowA = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
Dim FirstFreeRowF As Long ' find first free row in column F (if first 2 rows have data)
FirstFreeRowF = ws.Cells(1, "F").End(xlDown).Row + 1
' fix issue if first or second row is empty
If FirstFreeRowF = ws.Rows.Count + 1 Then
If ws.Cells(1, "F").Value = vbNullString Then
FirstFreeRowF = 1
ElseIf ws.Cells(2, "F").Value = vbNullString Then
FirstFreeRowF = 2
End If
End If
' define range to add formula
Dim Rng As Range
Set Rng = ws.Range("F" & FirstFreeRowF, "F" & LastRowA)
' add formula
Rng.Formula = "=Round((E" & FirstFreeRowF & "*G" & FirstFreeRowF & "),2)"
End Sub
So this will consider F5 the first free row and fill in the formula in the selected range as seen below:
I think you should find the last used row in column F, so that you could know the next row is blank
lastrowF=sheets(sheetname).range("F" & rows.count).end(xlup).row
So the next row would be like
range("F" & lastrowF+1).formula="Round((E" & lastrowF+1 & "*G" & lastrowF+1 & ",2)"

Trying to loop to format data for graphing

I've been working on this for a bit, and I've just come to a roadblock. I'm trying to format some data for graphing in Excel, and it looks like this:
Example Data
I'd like to have the output look like this:
Desired Output
The actual number of faults and days vary wildly, so it has to be open-ended, so it can do a full search of the imported file. I'm trying to do it using VBA without relying on a formula.
Let me know if there's anything I could be doing different.
Here's the code:
Sub Graph()
Dim GraphDataWS, DataWS, FormWS As Worksheet
Dim criteria1, InspectedMtr As String
Dim totalrow, ErrorRangevar, DateRangeVar, Row1, Col1 As Long
Dim Daterange, ErrorRange As Range
Dim criteria2 As Variant
Dim ErrorCount, Output As Double
Worksheets("Graph Data").Activate
Set Worksheet = ActiveWorkbook.Sheets("Graph Data")
Cells.Select
Selection.ClearContents
Selection.ClearContents
Set GraphDataWS = ActiveWorkbook.Sheets("Graph Data")
Set FormWS = ActiveWorkbook.Sheets("Formulas")
Set DataWS = ActiveWorkbook.Sheets("Data")
totalrow = FormWS.Range("A21").Value
Worksheets("Data").Range("A1:A" & totalrow).SpecialCells(xlCellTypeVisible).Copy (Worksheets("Graph Data").Range("B1"))
Worksheets("Data").Range("E1:E" & totalrow).SpecialCells(xlCellTypeVisible).Copy (Worksheets("Graph Data").Range("A1"))
With GraphDataWS
ErrorRangevar = GraphDataWS.Cells(Rows.Count, "A").End(xlUp).Row
GraphDataWS.Range("A1:A" & ErrorRangevar).Copy (GraphDataWS.Range("C1:C" & ErrorRangevar))
GraphDataWS.Range("C2:C" & ErrorRangevar).RemoveDuplicates Columns:=1
DateRangeVar = GraphDataWS.Cells(Rows.Count, "B").End(xlUp).Row
GraphDataWS.Range("B1:B" & DateRangeVar).Copy (GraphDataWS.Range("D1:D" & DateRangeVar))
GraphDataWS.Range("D2:D" & DateRangeVar).RemoveDuplicates Columns:=1
'DateRangeVar = GraphDataWS.Cells(Rows.Count, "B").End(xlUp).row
Range("D2").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Range("E1").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlNone, SkipBlanks:=False, Transpose:=True
ErrorRangevar = ErrorRangevar + 2
Worksheets("Graph Data").Activate
Output = 0
Set Daterange = GraphDataWS.Range(Cells(1, 4), Cells(1, DateRangeVar))
Set ErrorRange = GraphDataWS.Range("C1:C" & ErrorRangevar)
For a = 2 To ErrorRangevar
criteria1 = Cells(a, 3).Value
For b = 2 To ErrorRangevar
criteria2 = Cells(a, 4).Value
For i = 2 To ErrorRangevar
If ((Cells(i, 1)) = criteria1) And (Cells(i, 2) = criteria2) Then
Output = Output + 1
End If
Next i
Row1 = ErrorRange.Find(What:=criteria1).Row
Col1 = Daterange.Find(What:=criteria2).Column
Cells(Row1, Col1).Value = Output
MsgBox criteria1 & " " & Row1 & " " & criteria2 & " " & Col1 & " Output: " & Output
Output = 0
Next b
Next a
GraphDataWS.Range("E2").Value = Output
End With
End Sub
Any other suggestions or comments are welcome, I'm still learning VBA/Excel. Thank you!
First, I'm sorry as I can't understand this sentence :
to graph information from that
porting the information from a table
Anyway, other than create a pivot table from the data seen in your first image to get the expected result as seen in your second image ... I try to make the code based on the data seen in your first image to get the expected result as seen in you second image.
Sub test()
Dim rgdt As Range: Dim dateCol As Range: Dim cell As Range
Dim rgdt1 As String: Dim rgdt2 As String
Set rgdt = Sheets("Sheet1").UsedRange
Set rgdt = rgdt.Resize(rgdt.Rows.Count - 1, rgdt.Columns.Count).Offset(1, 0)
rgdt1 = "Sheet1!" & rgdt.Columns(1).Address
rgdt2 = "Sheet1!" & rgdt.Columns(2).Address
With Sheets("Sheet2").Range("A1")
.Value = "NAME"
rgdt.Copy Destination:=.Offset(1, 0)
.Range(rgdt.Columns(1).Address).RemoveDuplicates Columns:=1, Header:=xlNo
.Range(rgdt.Columns(2).Address).RemoveDuplicates Columns:=1, Header:=xlNo
Set dateCol = .Range(rgdt.Columns(2).Address).SpecialCells(xlConstants)
dateCol.Copy
.Offset(0, 1).PasteSpecial Paste:=xlPasteAll, Transpose:=True
dateCol.Clear
For Each cell In .Range(rgdt.Columns(1).Address).SpecialCells(xlConstants)
With cell.Offset(0, 1).Resize(1, dateCol.Rows.Count)
.Value = "=countifs(" & rgdt1 & "," & cell.Address & "," & rgdt2 & ",B$1)"
.Value = .Value
.Replace What:=0, Replacement:="", MatchCase:=True
End With
Next
End With
End Sub
The sub assumed that there is nothing else in "Sheet1" but the data seen in your example data image.
First it create rgdt variable as the range of the data in "Sheet1" (sheet "Data" in your case, so change accordingly) without including the header.
Then it create rgdt1 and rgdt2 string variable to point which sheet and which column of rgdt.
Then it prepares the "skeleton" of expected result in "Sheet2" (Sheet "Graph Data" in your case):
fill cell A1 with "NAME"
copy the rgdt to cell A1.offset(1,0)
remove duplicate value in column A
remove duplicate value in column B
set the range of column B with data as dateCol variable (without the header)
copy the dateCol and paste transpose to cell A1.offset(0,1)
clear the value in dateCol
Next, it populate the value for the expected count result by looping to each cell which has value in column A, where on each loop it fill the range of cells after the looped cell to the right with COUNTIFS formula, remove the formula as value, then replace zero (0) result with nothing.
If you want to test the sub, create a new workbook, copy your data into cell A1 of "Sheet1", copy also the sub, then run the sub. See the expected result in "Sheet2".

VBA macro: If Range Contains Words from Another Range Then Type x in Third Range

I would like to solve the following problem:
In Worksheet1 I have a range in text form from O3 to O4500. If the cells in this range contain certain words, I want an "x" to be put in the range U3:U4500 (in the same row). The words to be tested are in range B4:B15 in another Worksheet (Worksheet2).
I made it work with the following code (solution1), but now I don't want to type the code manually for word1, word2, words3... instead it should be taken from the other range in Worksheet 2 (see my draft below in solution2). I believe the problem are the "* *" which are missing when I use the referral to the other range.
Any help is very much appreciated!
Sub solution1()
Dim i As Long
For i = 3 To 4500
If LCase$(Worksheet1.Range("O" & i).Value) Like "*word1*" Or _
LCase$(Worksheet1.Range("O" & i).Value) Like "*word2*" Or _
LCase$(Worksheet1.Range("O" & i).Value) Like "*word3*" Then
Worksheet1.Range("U" & i).Value = "x"
End If
Next
End Sub
Sub solution2()
Dim i As Long, c As Long
For i = 3 To 4500
For c = 4 To 15
If LCase$(Worksheet1.Range("O" & i).Value) Like LCase$(Worksheet2.Range("B" & c).Value) Then
Worksheet1.Range("U" & i).Value = "x"
End If
Next
Next
End Sub
try something like:
Sub solution2()
Dim i As Long, c As Long
searchstring = LCase$(Worksheets("Worksheet2").Range("B1").Value & "|" & Worksheets("Worksheet2").Range("B2").Value & "|" & Worksheets("Worksheet2").Range("B3").Value)
For i = 2 To 9
If Len(LCase$(Worksheets("Worksheet1").Range("O" & i).Value)) < 1 Then GoTo neexxtt
'line above prevents empty lines to be marked
If InStr(searchstring, LCase$(Worksheets("Worksheet1").Range("O" & i).Value)) <> 0 Then Worksheets("Worksheet1").Range("U" & i).Value = "x"
neexxtt:
Next
End Sub
A VBA Lookup: Using an (Array)Formula For Partial Matches
In Excel, in cell U3, you could use the following array formula:
=IF(COUNT(MATCH("*"&Sheet2!$B$4:$B$15&"*",O3,0))>0,"X","")
and copy it down (adjust the lookup worksheet name (Sheet2)).
The following solution is based on this formula avoiding any loops.
Sub VBALookup()
Const Flag As String = "x"
' Reference the ranges.
Dim srg As Range ' Source
Dim drg As Range ' Destination
Dim lrg As Range ' Lookup
With Worksheet1
Set srg = .Range("O3", .Cells(.Rows.Count, "O").End(xlUp))
Set drg = srg.EntireRow.Columns("U")
End With
With Worksheet2
Set lrg = .Range("B4", .Cells(.Rows.Count, "B").End(xlUp))
End With
' Build the array formula.
Dim ArrayFormula As String
ArrayFormula = "=IF(COUNT(MATCH(""*""&'" & Worksheet2.Name & "'!" _
& lrg.Address & "&""*""," & srg.Cells(1).Address(0, 0) & ",0))>0,""" _
& Flag & ""","""")"
' Write the formulae (values).
With drg
' Write the array formula to the first cell.
.Cells(1).FormulaArray = ArrayFormula
' Autofill to the bottom.
.Cells(1).AutoFill .Cells, xlFillDefault
' Not sure, but instead of the previous 2 lines, in Office 365,
' the following single line should work:
'.Cells.Formula = ArrayFormula
' Convert to values (out-comment if you want to keep the formulae).
.Value = .Value
End With
End Sub

Exce VBA how to generate a row count in that starts with specific row and stops at last row? Formula is flawed

So I have what might be a simple issue. I have a worksheet where I'm just hoping to generate a row count starting with cell A4. So A4 = 1, A5 = 2 , etc. The problem is I'm not sure how to configure this with the following goal:
1 - I'm hoping the count starts with cell A4 and ends the count at the final row with data.
The code I have below only works if I manually put A4 = 1, and also populates formulas past the last row unfortunately.
Please help if this is possible.
Sub V14()
With ThisWorkbook.Worksheets("DCT")
.Cells(5, 1).Resize(.Cells(.Rows.Count, 2).End(xlUp).Row - 1).Formula = "=IF(DCT!B5="""","""",DCT!A4+1)"
End With
End Sub
Write Formula to Column Range
The Code
Sub V14()
Const wsName As String = "DCT" ' Worksheet Name
Const tgtRow As Long = 4 ' Target First Row Number
Const tgtCol As String = "A" ' Target Column String
Const critCol As String = "B" ' Criteria Column String
' Define worksheet ('ws').
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(wsName)
' Define Last Non-Empty Cell ('cel') in Criteria Column ('critCol').
Dim cel As Range
Set cel = ws.Cells(ws.Rows.Count, critCol).End(xlUp)
' Define Target Column Range ('rng').
Dim rng As Range
Set rng = ws.Cells(tgtRow, tgtCol).Resize(cel.Row - tgtRow + 1)
' Define Target Formula ('tgtFormula').
Dim tgtFormula As String
tgtFormula = "=IF('" & wsName & "'!" & critCol & tgtRow _
& "="""","""",MAX('" & wsName & "'!" & tgtCol _
& "$" & tgtRow - 1 & ":" & tgtCol & tgtRow - 1 & ")+1)"
' Write Target Formula to Target Range.
rng.Formula = tgtFormula
' If you just want to keep the values:
'rng.Value = rng.Value
End Sub
I think you might just need an extra IF:
Sub V14()
With ThisWorkbook.Worksheets("DCT")
.Cells(4, 1).Resize(.Cells(.Rows.Count, 2).End(xlUp).Row - 1).Formula = "=IF(DCT!B4="""","""",IF(A3="""",1,SUM(DCT!A3,1)))"
End With
End Sub
Report any question you have or bug you have encountered. If, according to your judgment, this answer (or any other) is the best solution to your problem you have the privilege to accept it (link).
Dim target As String
Dim lastrow As Long
target = "A4"
lastrow = ActiveSheet.UsedRange.Rows.count
'for example
Range(target) = "1"
Range(target).Offset(1, 0) = "2"
Range(Range(target),Range(target).Offset(1, 0)).Select
Selection.AutoFill Destination:=Range(target & ":A" & lastrow + Range(target).Row - 1), Type:=xlFillDefault
You only got to change the target cell, this does the rest.

VLOOKUP from another sheet, apply formula every nth row

I'm working on the below formula to Vlookup data from another sheet. The formula must be placed on the 14th column, and every 7 rows, vlookuping the first column value.
Sub test3()
'Vlookuping on Column N
Dim lastRow As Long
lastRow = Cells(Rows.Count, 14).End(xlUp).Row 'Checks last row with data
Dim cel As Range, rng As Range
Dim sheetName, lookupFrom, myRange 'variables
sheetName = "Plan2" 'the worksheet i want to get data from
lookupFrom = ActiveCell.Offset(0, -14).Address '
myRange = "'" & sheetName & "'!1:1048576"
For i = 3 To lastRow Step 7 '
Cells(i, 14).Select 'i= first value; step= lines to jump
ActiveCell.Formula = "=VLOOKUP(" & lookupFrom & ";" & myRange & "; 14; FALSE)"
Next i
End Sub
Example Sheet
I want to place the formula on the pink cells (column N), vlookuping the pink value from the first cell on another worksheet. My actual formula isn't even executing.
Try the code below, with 2 exceptions:
1.Modify "VlookRes" to your Sheet name - where you want to results to be.
2.You have Merged Cells in Column A (according to your image uploaded), you are merging Rows 2 untill 6 in column A, this means that the value of Cell A3 will be 0. If you want the values to read from the third row, start the merging from row 3 (and soon for the next values in Column A).
Option Explicit
Sub test3()
'Vlookuping on Column N
Dim ShtPlan As Worksheet
Dim ActSht As Worksheet
Dim lastRow As Long
Dim sheetName As String
Dim lookupFrom As String
Dim myRange As String
Dim i As Long
' modify this Sheet Name to your sheet name (where you want to keep your results)
Set ActSht = Sheets("VlookRes")
lastRow = ActSht.Cells(ActSht.Rows.Count, 14).End(xlUp).Row ' Checks last row with data
sheetName = "Plan2" 'the worksheet i want to get data from
Set ShtPlan = Sheets(sheetName)
myRange = "'" & sheetName & "'!1:1048576"
For i = 3 To lastRow Step 7
lookupFrom = ActSht.Cells(i, 1).Address ' ActiveCell.Offset(0, -14).Address '
Cells(i, 14).Formula = "=VLOOKUP(" & lookupFrom & "," & myRange & ", 14, FALSE)"
Next i
End Sub

Resources