Loop through cells and copy paste values according to if condition - vba

I want to loop through a range of cells and extract specific information. I am trying to copy paste the cell.offset(0,-2) of the cell (a range) in sheet("Tracker") in the next empty cell of column D in sheet("1") if the value of the cell is the same as the variable r.Value (a variable that is an input value that changes everytime, so it has to stay as a variable). SO, since I am having cell (range) you understand its a loop for all the cells in the column G of the sheet("Tracker"). It works so far but the only thing that it does is get the first cell offset and paste it in the cell d1 of the destination sheet, overwritting my header. I want it to paste it from cell D2(first empty cell) and do this for all cells that abide by the if condition. Any ideas? The code is provided below..
The code below is the revised one!
The problem with the dates is as shown above.. I want to be as it appears inside the cell, not on the top of the page..
Dim v As Range
Set v = Sheets("1").Cells(Worksheets("1").Rows.Count, "D").End(xlUp)
With Sheets("Tracker")
For Each cell In .Range(.Cells(2, "G"), .Cells(.Rows.Count, "G").End(xlUp))
If cell.Value = r.Value Then
Set v = v.Offset(1, 0)
v = cell.Offset(0, -2).Value
End If
Next cell
End With

Avoid select; explicitly define the parent worksheet; look from the bottom up to find the last populated cell; define your range with a starting point and an ending point.
Dim v As Range
Set v = WORKSheets("1").Cells(WORKSheets("1").Rows.Count, "D").End(xlUp)
with WORKSheets("Tracker")
For Each cell In .Range(.cells(2, "G"), .cells(.rows.count, "G").End(xlUp))
If Int(cell.Value2) = Int(r.Value2) Then
Set v = v.Offset(1, 0)
v = cell.Offset(0, -1).value
end if
Next cell
end with

Related

Add same amount of rows as in another column

I've created a button to copy and paste table from one worksheet to another, to the first blank cell in a column. I'd like to add date (cell A19) and name (cell A5) to the other column, with same amount of lines which have been add.
Scheme of the table has been added as a pic, down below is my piece of code. Tried with the offset but didnt work for me
Dim TblToSave As Range
Dim RangeToPaste As Range
Set TblToSave = ThisWorkbook.Worksheets("Sheet1").Range("D22", Range("O22").End(xlDown))
TblToSave.Copy
ThisWorkbook.Worksheets("db").Activate
Set RangeToPaste = ThisWorkbook.Worksheets("Db").Range("C" & Rows.Count).End(xlUp).Offset(1)
RangeToPaste.PasteSpecial xlPasteValues
I managed to figure it out, this one was known by me but I dont know if it is the best way, the most optimal, not burden for workbook
Dim Lastrow As Integer
Lastrow = ThisWorkbook.Worksheets("db").Cells(Rows.Count, 3).End(xlUp).Row
For Each cell In ThisWorkbook.Worksheets("db").Range("C2:C" & Lastrow)
If Not IsEmpty(cell) AND IsEmpty (cell.Offset(,-1)) Then
cell.Offset(, -1).Value = ThisWorkbook.Worksheets("Sheet1").Range("A5").Value
cell.Offset(, -2).Value = ThisWorkbook.Worksheets("Sheet1").Range("A20").Value
End If
Next
Unfortunately it amends the data from each row, as expected. I need to add it to Offset(,-1) and Offset(,-2) only for new entries (so copied and pasted), the previous stays as they are

Copy Cell and Move to Another Cell (Offset) - VBA BEGINNER

I have a column that has many blanks and entries. I want to take the entries (ignoring the blanks) and move them over to the right once and down twice replacing the contents. I have a feeling you would use the offset function, however I don't know how to write this in VBA. I've only used offset as a formula. Any help would be appreciated...
here's a one liner:
Range("A:A").SpecialCells(xlCellTypeConstants).Offset(2, 1).FormulaR1C1 = "=R[-2]C[-1]" '<--| change "A:A" to actual column index
or, should your "not blank" cells derive from formulas in the cells:
Range("A:A").SpecialCells(xlCellTypeFormulas).Offset(2, 1).FormulaR1C1 = "=R[-2]C[-1]"
First you need to create a loop, that moves through all the values of your range. There many ways to create loops, but here is one example:
'find last row of range
lastrow = ActiveSheet.UsedRange.Rows.Count
'Loops through the values from 2 to the last row of range
For x=2 to lastrow
Next x
Then I recommend to loop through the range and check each cell value for your criteria using the IF function:
'Checks for blank value in column A. If not blank
If Cells(x, 1).Value <> "" then
'Do Something
End IF
Now in order to copy all values in a new range, just set the values of the old and new cell equal:
'Moves value from column A to column B and two cells down
Cells(x+2, 2).Value = Cells(x, 1).Value
In summary your code would look something like this:
Sub MoveValue ()
lastrow = ActiveSheet.UsedRange.Rows.Count
For x=2 to lastrow
If Cells(x, 1).Value <> "" then
Cells(x+2, 2).Value = Cells(x, 1).Value
End IF
Next x
End Sub

Excel VBA Index/Match within IF function

I'm trying to setup a VBA code that loops through each cell in column M and returns the value of Column L if the cell contains a number, and goes through an index/match function if Column L doesn't contain a number. Then if the index/match doesn't find what it's looking for, it goes through another vlookup. I'm having trouble with the syntax of the third part of this (the vlookup at the end). I'm not sure if it should be another Else statement or an if statement or an ISerror or something different entirely. Right now I have it set up as the second if/else. I'm also wondering if I will have problems due to the fact that the index/match function has text as the input and should return a number. Any suggestions/advice on this is much appreciated. Below is what I have so far.
Sub Ranking_2()
Dim cell As Range, rng As Range
Set rng = Range("L2:L120")
For Each cell In rng
If WorksheetFunction.IsNumber(cell.Value) Then
cell.Offset(0, 1).Value = cell.Value
Else: cell.Offset(0, 1).Value = WorksheetFunction.Index(ThisWorkbook.Sheets(1).Range("K:K"), WorksheetFunction.Match(cell.Offset(0, 1) & cell.Offset(0, 5), ThisWorkbook.Sheets(1).Range("A:A") & ThisWorkbook.Sheets(1).Range("H:H"), 0))
If:cell.Offset(0,1).Value= WorksheetFunction.IsError(
Else: cell.Offset(0, 1).Value = WorksheetFunction.VLookup(cell.Offset(0, -11), ThisWorkbook.Sheets(2).Range("A1:D136"), 3, 0)
End If
Next
End Sub
you may want to adopt these changes to your code
Option Explicit
Sub Ranking_2()
Dim cell As Range
Dim lookUp1Sht As Worksheet
Dim lookUp2Rng As Range
Dim val1 As Variant
Set lookUp1Sht = ThisWorkbook.Worksheets("LookUp1Sht") '<--| set the worksheet you're making the first lookup
Set lookUp2Rng = ThisWorkbook.Worksheets("LookUp2Sht").Range("A1:C136") '<--| since you're this range returning column "C" value it suffices limiting it to column "C"
For Each cell In Range("L2:L120").SpecialCells(xlCellTypeConstants) '<--| limit looping through wanted range not blank cells only
With cell '<--| reference current cell
Select Case True
Case IsNumeric(.Value) '<--| if current cell value can be evaluated as "number"...
.Offset(0, 1).Value = CDbl(.Value)
Case Not IsError(LookUp1(lookUp1Sht, .Offset(0, 1).Value, .Offset(0, 5).Value, val1)) '<-- if "first" lookup doesn't return an "error"...
.Offset(0, 1).Value = val1 '<--| then write the 3rd argument passed from LookUp1() function
Case Else '<-- if all preceeding "cases" failed...
.Offset(0, 1).Value = Application.VLookup(.Offset(0, -11), lookUp2Rng, 3, 0) '<-- write "second" lookup return value
End Select
End With
Next
End Sub
Function LookUp1(sht As Worksheet, val1 As Variant, val2 As Variant, val As Variant) As Variant
Dim f As Range
Dim firstAddress As String
With sht '<--| reference passed worksheet
Set f = .Range("A:A").Find(what:=val1, LookIn:=xlValues, lookat:=xlWhole) '<-- look for first passed value in its column "A"
If Not f Is Nothing Then '<--| if found...
firstAddress = f.Address '<--| store found cell address to stop subsequent FindNext() loop upon wrapping back to it
Do '<--| loop
If f.Offset(, 7).Value = val2 Then '<--| if corresponding value in column "H" matches val2...
val = .Cells(f.row, "K") '<-- set 3rd argument to value in column "K" corresponding to the "double" match
Exit Function '<--| exit function
End If
Set f = .Range("A:A").FindNext(f) '<-- go on looking for val1 in column "A"
Loop While f.Address <> firstAddress '<-- stop looping upon wrapping back on first cell found
End If
End With
LookUp1 = CVErr(xlErrValue) '<-- if no "double" match occurred then return "#VALUE!" error
End Function
please note that:
change "LookUp1Sht" and "LookUp2Sht" to your actual worksheets names
Match and LookUp Application functions handle possible errors without halting the macro and simply returning the error value
This I only used in .Offset(0, 1).Value = Application.VLookup(.Offset(0, -11)..., so that if the "last chance lookup" ever returned an error you would have it written in your .Offset(0,1) cell
use SpecialCells() method to return a filtered group of the range you call it on: for instance using xlCellTypeConstants as its Type parameter you'd get back not empty cell only
use IsNumeric() function instead of [WorksheetFunction.IsNumber()[(https://msdn.microsoft.com/en-us/library/office/ff840818(v=office.15).aspx) since the former will recognize string "5" as a number, while the latter would not

VBA Excel find and replace WITHOUT replacing items already replaced

I am looking to make an excel script that can find and replace data, but for the love of everything I cannot figure out how to write it.
Situation:
A-----------B-----------C
Cat-------Dog------Banana
Dog------Fish------Apple
Fish------Cat-------Orange
So the macro would look at the data in a cell in column B, then look at the adjacent cell in column C, and replace all instances of that data in column A with what if found in C. So the results would be:
A---------------B-----------C
Orange------Dog------Banana
Banana------Fish------Apple
Apple--------Cat-------Orange
But that's not all, I would like it to not change cells in A that already have been changed once! (I'm trying this with changing the background colour)
Any help? I am at a complete loss.
EDIT:
Okay I found out how to do the easy part (replacing), but I cannot find out how to not change cells that already have been changed once. Here is my code:
Sub multiFindNReplace()
Dim myList, myRange
Set myList = Sheets("sheet1").Range("A2:B3") 'two column range where find/replace pairs are
Set myRange = Sheets("sheet1").Range("D2:D5") 'range to be searched
For Each cel In myList.Columns(1).Cells
myRange.Replace what:=cel.Value, replacement:=cel.Offset(0, 1).Value, ReplaceFormat:=True
Next cel
End Sub
As far as I can tell, ReplaceFormat:=True
doesn't do anything ;/ so items that already have been replaced once still are being replaced! Is there a way to somehow make this work?
Here's the answer using your recommendation with color as a one-time limiter:
Sub Replace_Once()
'Find last row using last cell in Column B
LastRow = Range("B" & Rows.Count).End(xlUp).Row
'Clear colors in Column A
Range("A1:A" & LastRow).Interior.ColorIndex = xlNone
'Look at each cell in Column B one at a time (Cel is a variable)
For Each Cel In Range("B1:B" & LastRow)
'Compare the cell in Column B with the Value in Column A one at a time (C is a variable)
For Each C In Range("A1:A" & LastRow)
'Check if the Cell in Column A matches the Cell in Column B and sees if the color has changed.
If C.Value = Cel.Value And C.Interior.Color <> RGB(200, 200, 200) Then
'Colors the cell
C.Interior.Color = RGB(200, 200, 200)
'Updates the value in Column A with the cell to the right of the Cell in Column B
C.Value = Cel.Offset(0, 1).Value
End If
Next
Next
'Uncomment the line below to remove color again
'Range("A1:A" & LastRow).Interior.ColorIndex = xlNone
End Sub

vba searching through rows and their associated columns and highlight if conditions meet

The code below would search through a row and its associated columns.
For Row 7, if it is a "N" or "TR" and if all entries are blank below line 12,the code would hide the entire column.
However, I still need help with some further help!
If there is a "N" or "TR" in row 7. If there is something writen in any cell, (rather than leaving it alone), can I highlight its associated cell in row 7 in yellow?
If ther eis a "Y" in row 7, If there is any empty cells, can I highlight its associated cell in row 7 in yellow?
Thank you so much! special thanks to KazJaw for my previous post about simular issue
Sub checkandhide()
Dim r As Range
Dim Cell As Range
Set r = Range("A7", Cells(7, Columns.Count).End(xlToLeft))
For Each Cell In r
If Cell.Value = "N" Or Cell.Value = "TR" Then
If Cells(Rows.Count, Cell.Column).End(xlUp).Row < 13 Then
Cell.EntireColumn.Hidden = True
End If
End If
Next
End Sub
attached example of spreadsheet
Here you have an improved version of your code (although I might need further clarifications... read below).
Sub checkandhide()
Dim r as Range, Cell As Range, curRange As Range
Set r = Range("A7", Cells(7, Columns.Count).End(xlToLeft))
For Each Cell In r
Set curRange = Range(Cells(13, Cell.Column), Cells(Rows.Count, Cell.Column)) 'Range from row 13 until last row in the given column
If Cell.Value = "N" Or Cell.Value = "TR" Then
If Application.CountBlank(curRange) = curRange.Cells.Count Then
Cell.EntireColumn.Hidden = True
Else
Cell.Interior.ColorIndex = 6 'http://dmcritchie.mvps.org/excel/colors.htm
End If
ElseIf Cell.Value = "Y" Then
If Application.CountBlank(curRange) > 0 Then
Cell.Interior.ColorIndex = 6 'http://dmcritchie.mvps.org/excel/colors.htm
End If
End If
Next
End Sub
I am not sure if I have understood your instructions properly and thus I will describe here what this code does exactly; please, comment any issue which is not exactly as you want and such that I can update the code accordingly:
It looks for all the cells in range r.
If the given cell (which might be in row 7 or in any other row below it) meets one of the conditions, the corresponding actions would be performed.
Part of the conditions depends on curRange, which is defined as all the rows between row number 13 until the end of the spreadsheet.
Specific conditions:
a) If the value of the current cell is N or TR. If all the cells in curRange are blank, the current column is hidden. If there is, at least, a non-blank cell, the background color of the given cell would be set to yellow.
b) If the value of the current cell is Y and there is, at least, one cell in curRange which is not blank, the background color of the background cell would be set to yellow.