Search cell for matching value then copy - excel

I would like to filter my Excel table with VBA code.
A1, B1, C1 are titles
Column A = All (A2: xx)
Column B = Search Content`s (B2: xx)
Column C = (C2: xx)
Everything in column B should be searched for column A and if one or more is found then column C should be written.
I tried the following.
Sheets("Tabelle2").Range("A2:A2000").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range("B2:B2000"), CopyToRange:=Range("C2:C2000")
So that everything in column A is copied to column C but not to be compared to column B.
How can I make this work?

I suggest you to use a helping column, then you can easily do that without VBA coding.
Helping column formula:
=IF(ISERROR(MATCH(A2,$B$2:$B$9,0)),ROW(),"")
Then use following formula to extract not backuped servers list.
=IFERROR(INDEX($A$2:$A$31,SMALL($D$2:$D$31,ROW(1:1))),"")
See the file

You have to include Title.
Sub test()
Dim rngDB As Range
Dim rngCria As Range
Dim rngTo As Range
Dim Ws As Worksheet
Set Ws = Sheets("Tabelle2")
With Ws
Set rngDB = .Range("a1:a2000")
Set rngCria = .Range("B1", .Range("b" & Rows.Count).End(xlUp))
Set rngTo = .Range("c1")
End With
rngDB.AdvancedFilter xlFilterCopy, rngCria, rngTo
End Sub

Option Explicit
Sub ListMatches()
Dim rngColumnA As Range, celColumnB As Range, rngColumnB As Range
Set rngColumnA = Range("A2:A" & Range("A1000000").End(xlUp).Row)
Set rngColumnB = Range("B2:B" & Range("B1000000").End(xlUp).Row)
For Each celColumnB In rngColumnB
If Not rngColumnA.Find(What:=celColumnB) Is Nothing Then Range("C" & Range("C1000000").End(xlUp).Row + 1) = celColumnB.Value
Next celColumnB
End Sub

Using A Collection might be even faster in your application:
Sub ListMatches()
Dim R1 As Range, R2 As Range, R As Range, Nc As New Collection
Set R1 = Range("A2:A" & Range("A" & Rows.Count).End(xlUp).Row)
Set R2 = Range("B2:B" & Range("B" & Rows.Count).End(xlUp).Row)
On Error Resume Next
For Each R In R1
Nc.Add R.Value, R.Value
Next R
For Each R In R2
Err = 0
Nc.Add R.Value, R.Value, 1
If Err = 0 Then
Range("C" & Range("C" & Rows.Count).End(xlUp).Row + 1) = R.Value
Nc.Remove 1
End If
Next R
On Error GoTo 0
End Sub

Related

Real-Statistics Excel Add-on LJUNG formula

I'm using LJUNG formula from the Real-Statistics add-on. The issue is that the formula uses the empty cells in its calculation. Can anyone advise how to exclude empty cells?
=LJUNG(AXW3:AXW377)
The result for this is 0.000
While the manual highlight of the data specific array =LJUNG(AXW280:AXW340), provides the result of: 0.152.
A brilliant answer provided by Jeremy Hodge
Sub test(sht As Worksheet)
Dim c As Integer
Dim startCell As Range
Dim endCell As Range
Dim lastRow As Integer
lastRow = sht.UsedRange.Rows(sht.UsedRange.Rows.Count).Offset(1, 0).Row
For c = 1 To Range("XFD1").End(xlToLeft).Column
If IsEmpty(sht.Cells(2, c).Value) = False Then
Set startCell = sht.Cells(2, c)
Else
Set startCell = sht.Cells(1, c).End(xlDown)
End If
Set endCell = sht.Cells(1048576, c).End(xlUp)
sht.Cells(lastRow, c).Formula = "=AVERAGE(" & startCell.Address & ":" & endCell.Address & ")"
Next c
End Sub

Find the last filled row in a filtered column without dropping the Autofilter

How do I get the position of the last non-empty cell in a filtered column without dropping the applied Autofilter? I understand it's easy to get the number of the last visible row with
Dim ws as Worksheet, rng As Range
Set rng = Range(Letter & 1 & ":" & Letter & 1) ' where Letter is the letter code of the column
GetLastVisibleRow = ws.Range(Split(ws.Cells(, rng.Column).Address, "$")(1) & ws.Rows.count).End(xlUp).row
but I need the number of the last filled row instead. At the same time, I'd like to avoid setting
ws.AutoFilterMode = False
if it's possible.
Thanks in advance.
Probably not the most efficient or fastest method, but this appears to work:
Function GetLastCellOfColumn(ColLetter As String) As Range
Dim Col As Range
Dim Rw As Long
Set Col = Range(ColLetter & ":" & ColLetter)
Set GetLastCellOfColumn = Intersect(ActiveSheet.UsedRange, Col)
For Rw = GetLastCellOfColumn.Cells.Count To 1 Step -1
If Len(GetLastCellOfColumn.Cells(Rw).Value) > 0 Then
Set GetLastCellOfColumn = GetLastCellOfColumn.Cells(Rw)
Exit Function
End If
Next
End Function
A charming solution by #jkpieterse plus a useful comment by #BigBen is exactly what I was looking for. Just to finalize the thread, the function returning the row number is
Function GetLastFilledCellOfColumn(ws As Worksheet, ColLetter As String) As Long
Dim Col As Range, Urng As Range, Rw As Long
Set Col = ws.Range(ColLetter & ":" & ColLetter)
Set Urng = Intersect(ws.UsedRange, Col)
For Rw = Urng.Cells.count To 1 Step -1
If Not IsEmpty(Urng.Cells(Rw)) Then
GetLastFilledCellOfColumn = Rw
Exit Function
End If
Next
End Function
Problem solved.
So maybe this is an alternative way to look into:
Sub Test()
Dim rng As Range
Dim col As Long: col = 2 'Change to whichever column you interested in
Dim rw as Long
With Sheet1 'Change to whichever sheets CodeName you need
Set rng = .Range("_FilterDatabase").Columns(col)
rw = .Evaluate("MAX(IF(" & rng.Address & "<>"""",ROW(" & rng.Address & ")))")
End With
End Sub
I'm afraid I rushed this a little and might have made a mistake but will have to get going. Hopefully you understand whats going on =)
Edit:
The above would definately work, but as figured out through the chat, there is actually a ListObject involved, called Table1, which throws of the AutoFilter range. So here are two alternative ways of doing the same thing:
Sub Test()
Dim rng As Range
Dim col As Long: col = 2 'Change to whichever column you interested in
Dim rw as Long
With Sheet1 'Change to whichever sheets CodeName you need
Set rng = .Range("Table1")
rw = .Evaluate("MAX(IF(" & rng.Address & "<>"""",ROW(" & rng.Address & ")))")
End With
End Sub
Or, when you don't know the name of the table:
Sub Test()
Dim rng As Range
Dim col As Long: col = 2 'Change to whichever column you interested in
Dim rw as Long
With Sheet1 'Change to whichever sheets CodeName you need
Set rng = .ListObjects(1).Range
rw = .Evaluate("MAX(IF(" & rng.Address & "<>"""",ROW(" & rng.Address & ")))")
End With
End Sub

VBA - Highlight/Delete row if Range is Empty

I have a range of data, with CASE ID's in Column A, and Issues (1 through 10, or Columns B through K) in Columns B onwards.
Once certain issues are ruled out as 'normal', they would be removed from the Issues sheet based on their respective column. For ex: CASE ID #25, Issue 4 is ruled OK, then it would be deleted from Row 25, Column 5 (or Column E) but the CASE ID would remain.
The goal is that by doing this check after the fact, it may leave certain rows entirely blank, from Column B onwards (since the CASE ID would already be there.)
My code doesn't function successfully. Once run, it highlights several rows that are not entirely blank in the target range.
I'm trying to pinpoint rows in the range B2:P & lastrow where the entire row is blank, and then highlight these rows and subsequently delete them.
Code:
Public Sub EmptyRows()
lastrow = Sheets("Issues").Cells(Rows.Count, "A").End(xlUp).row
On Error Resume Next
Sheets("Issues").Activate
For Each rng In Range("B2:P" & lastrow).Columns
rng.SpecialCells(xlCellTypeBlanks).EntireRow.Interior.ColorIndex = 11
'rng.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
Next rng
Application.ScreenUpdating = True
End Sub
The purpose of first highlighting is to test the code works. If successful, they would be deleted entirely.
Your description says Columns B through K, but your code has B through P...
You can do it like this (adjust resize for actual columns involved):
Public Sub EmptyRows()
Dim lastRow As Long, sht As Worksheet, c As Range, rngDel As Range
Set sht = Sheets("Issues")
For Each c In sht.Range(sht.Range("A2"), sht.Cells(Rows.Count, 1).End(xlUp)).Cells
If Application.CountA(c.Offset(0, 1).Resize(1, 10)) = 0 Then
'build range to delete
If rngDel Is Nothing Then
Set rngDel = c
Else
Set rngDel = Application.Union(rngDel, c)
End If
End If
Next c
'anything to flag/delete ?
If Not rngDel Is Nothing Then
rngDel.EntireRow.Interior.ColorIndex = 11
'rngDel.EntireRow.Delete '<< uncomment after testing
End If
End Sub
Once run, it highlights several rows that are not entirely blank in the target range.
This is because you are selecting all blanks, instead of only rows where the entire row is blank.
See the code below
Public Sub EmptyRows()
With Sheets("Issues")
lastrow = .Cells(Rows.Count, "A").End(xlUp).row
Dim rng as Range
For Each rng In .Range("B2:B" & lastrow)
Dim blankCount as Integer
blankCount = Application.WorksheetFunction.CountA(rng.Resize(1,.Range("B:P").Columns.Count))
If blankCount = .Range("B" & lastRow & ":P" & lastRow).Columns.Count Then
Dim store as Range
If store Is Nothing Then Set store = rng Else: Set store = Union(rng, store)
End If
Next rng
End With
store.EntireRow.Interior.ColorIndex = 11
'store.EntireRow.Delete
End Sub
Gathering the ranges first and then modified them (changing color or deleting) will help to execute the code faster.
Here is another approach, using CountA
For Each cell In Range("A2:A" & Cells(Rows.Count, "A").End(xlUp).Row)
Dim rng As Range
Set rng = Range("A" & cell.Row & ":" & "P" & cell.Row)
If Application.WorksheetFunction.CountA(rng) = 1 Then
rng.EntireRow.Interior.ColorIndex = 11
End If
Next cell

VBA to look up value in table and copy formula

I have a two column look up table. Column 1 is a fixed list of items and column 2 has a formula in it.
In another table when someone enters data in say cell a1 and it matches an item in column 1 of my look up table I need the corresponding formula from column 2 copied and pasted into cell b2.
Lots of google searching trying to find a way for VLOOKUP to copy formula in lieu of cell value has returned nothing so I assume the only way to do it is via VBA?
This small sample assumes the data is in columns C and D:
Sub Matt()
Dim r As Range, Tabl As Range
Set Tabl = Range("C1:C1000")
Set r = Tabl.Find(What:=Range("A1").Value, After:=Tabl(1))
Range("B1").Formula = r.Offset(0, 1).Formula
End Sub
place a value in A1 and run the macro
EDIT#1:
This version will loop down column A
Sub Matt_The_Sequel()
Dim r As Range, Tabl As Range, N As Long
Set Tabl = Range("C1:C1000")
N = Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To N
Set r = Tabl.Find(What:=Range("A" & i).Value, After:=Tabl(1))
Range("B" & i).Formula = r.Offset(0, 1).Formula
Next i
End Sub
EDIT#2:
Sub Matt_The_Sequel2()
Dim r As Range, Tabl As Range, N As Long
Dim First_Row As Long
Set Tabl = Range("C1:C1000")
N = Cells(Rows.Count, "A").End(xlUp).Row
First_Row = 4
For i = First_Row To N
Set r = Tabl.Find(What:=Range("A" & i).Value, After:=Tabl(1))
Range("B" & i).Formula = r.Offset(0, 1).Formula
Next i
End Sub

Convert Text to Rows instead of Text to Columns

I have a text string that is using the ^ symbol as a delimiter.
I need to separate the text into new rows rather than new columns.
I need to create new rows to not overwrite the next line of data below it.
Is this possible without using a macro? I'm not against using one, I just wouldn't know where to start to write it.
Below is a pic of some sample data. The top part is how it's listed, and the bottom (in yellow) is how I would like it.
Using Excel 2010 on Windows 7 Pro.
Thanks to those that responded. A friend was able to help by providing the following code:
Sub Breakout()
Application.ScreenUpdating = False
LR = Cells(Rows.Count, 1).End(xlUp).Row
For r = LR To 2 Step -1
Set MyCell = Cells(r, 1)
Arry = Split(MyCell.Value, "^")
For c = 0 To UBound(Arry)
If c > 0 Then MyCell.Offset(c, 0).EntireRow.Insert
MyCell.Offset(c, 0) = Arry(c)
Next c
Next r
End Sub
Could try something like this:
Sub reArrange()
Dim inFirstRng As Range
Dim inRng As Range
Dim inCur As Variant
Dim outFirstRng As Range
Dim outCurRng As Range
Dim ws As Worksheet
'CHANGE ARGUMENT TO YOUR SHEET NAME
Set ws = Worksheets("Sheet2")
With ws
'CHANGE ARGUMENT TO WHATEVER THE FIRST CELL OR YOUR DATA INPUT IS IN COLUMN A
Set inFirstRng = .Range("A3")
Set inRng = .Range(inFirstRng, inFirstRng.End(xlDown))
'CHANGE ARGUMENT TO WHATEVER THE FIRST CELL OR YOUR DATA OUTPUT IS IN COLUMN A
Set outFirstRng = .Range("A9")
Set outCurRng = outFirstRng
End With
For Each cell In inRng.Cells
inCur = WorksheetFunction.Transpose(Split(cell.Value, "^"))
outCurRng.Resize(UBound(inCur), 1).Value = inCur
With ws
.Range("G" & outCurRng.Row & ":L" & outCurRng.Row).Value = _
.Range("G" & cell.Row & ":L" & cell.Row).Value
End With
Set outCurRng = outCurRng.Offset(UBound(inCur), 0)
Next cell
ws.Range("F" & outFirstRng.Row & ":F" & outCurRng.Row - 1).Value = 1
End Sub

Resources