Vlookup Multiple sheets using reference - excel

I have 8 sheets with Multiple columns data , i want these 7 sheets vlookup with sheet8 and what ever the ids are there in sheet8 should be present in all 7 sheets remaining row should be deleted.
the code is below what i have but its not working proerly still i can see some id with #N/A present in the data.
Sub delete()
Dim arr(), msg As String
Dim c As Range
Dim ws_lrow, ws8_lrow, i As Integer
Dim ws As Worksheet
ws8_lrow = Sheets("Sheet8").Cells(Rows.Count, 1).End(xlUp).Row
ReDim arr(ws8_lrow)
For i = 2 To ws8_lrow
arr(i - 2) = Sheets("Sheet8").Cells(i, 1).Value
Next i
For Each ws In ActiveWorkbook.Sheets
ws_lrow = ws.Cells(Rows.Count, 2).End(xlUp).Row
For Each c In ws.Range("B2:B" & ws_lrow)
If IsInArray(c, arr()) = 0 Then
msg = msg & "User '" & c & "' from: " & ws.Name & vbCrLf
c.EntireRow.delete xlShiftUp
End If
Next c
Next ws
MsgBox "The following users have been deleted:" & vbCrLf & msg
End Sub
Private Function IsInArray(valToBeFound As Variant, arr As Variant) As Boolean
Dim element As Variant
On Error GoTo IsInArrayError: 'array is empty
For Each element In arr
If element = valToBeFound Then
IsInArray = True
Exit Function
End If
Next element
Exit Function
IsInArrayError:
On Error GoTo 0
IsInArray = False
End Function

You are comitting a classical mistake when iterating over a range of rows, top down, and deleting rows throughout the process. In this type of situation the easiest and correct way is to loop from the bottom up. This loop should be fixed:
'For Each c In ws.Range("B2:B" & ws_lrow)
' If IsInArray(c, arr()) = 0 Then
' msg = msg & "User '" & c & "' from: " & ws.Name & vbCrLf
' c.EntireRow.delete
' End If
'Next c
Loop from the bottom up like this:
For i = ws_lrow to 2 step -1
If IsInArray(ws.Range("B" & i).value, arr) = 0 Then
msg = msg & "User '" & ws.Range("B" & i).value & "' from: " & ws.Name & vbCrLf
ws.Rows(i).delete
End If
Next i

Related

display only cells with value in Pop Up Form

the macro below takes two cell values (from first and second column)
and displays the column and there cell content in a Pop up Form
Im trying to add the condition that only the column and cell value is displayed if the cell contains value.
something like that =IF(A1<>"",result,"")
but I dont know how to implement that for all cells not only for a specific one.
Option Explicit
Const rangeForSearch = "G2"
Const rowTitles = 4
Dim arrTmp
Dim lastRow As Long, lastColumn As Long
Dim textForSearch As String, textForSearch_withoutSpaces As String
Dim strTmp As String
Dim i As Long, j As Long
Sub searchPerson()
Application.ScreenUpdating = False
With ActiveSheet
textForSearch = .Range(rangeForSearch)
If textForSearch = "" Then
MsgBox "Input text in cell """ & rangeForSearch & """ and try again!", vbCritical
Application.ScreenUpdating = True
Exit Sub
End If
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
lastColumn = .Cells(rowTitles, .Columns.Count).End(xlToLeft).Column
If lastRow <= rowTitles Or lastColumn <= 2 Then
MsgBox "Dataset is wrong! Check it and try again!", vbCritical
Application.ScreenUpdating = True
Exit Sub
End If
arrTmp = .Range(.Cells(rowTitles, "A"), .Cells(lastRow, lastColumn))
End With
'---------------------------------------
textForSearch_withoutSpaces = Replace(textForSearch, " ", "")
For i = LBound(arrTmp, 1) + 1 To UBound(arrTmp, 1)
strTmp = Replace(arrTmp(i, 1) & arrTmp(i, 2), " ", "")
If StrComp(textForSearch_withoutSpaces, strTmp, vbTextCompare) = 0 Then Exit For
Next i
If i = UBound(arrTmp, 1) + 1 Then
strTmp = textForSearch & vbCrLf & vbCrLf & "No dataset!"
Else
strTmp = textForSearch
For j = 3 To lastColumn
strTmp = strTmp & vbCrLf & vbCrLf & arrTmp(1, j) & ": " & arrTmp(i, j)
Next j
End If
Application.ScreenUpdating = True
MsgBox strTmp, , "Result"
End Sub
maybe
For j = 3 To lastColumn
If Not IsEmpty(arrTmp(i, j)) Then strTmp = strTmp & vbCrLf & vbCrLf & arrTmp(1, j) & ": " & arrTmp(i, j)
Next j

Updating For Each loop variable

The aim is to find the circularity between value in column c and all values obtained from updated "firstvalue" variable which are comma separated and stored in column "M".
Sub circular()
Dim rng As Range, rng2 As Range, firstvalue As String, secondvalue As String
Set sh = ThisWorkbook.Worksheets("Sheet1")
lr = sh.Range("C" & Rows.Count).End(xlUp).Row
For Each rng In sh.Range("C5:C" & lr) 'iterating over each cell in column "c" from C5 till lastrow "lr".
firstvalue = rng.Offset(0, 10).value 'Corresponding cell value which is comma seperated in column
"M" i:e after 10 columns from "C".
Dim n As Variant
For Each n In Split(firstvalue, ",") 'Looping through each value obtained from split function.
Set rng2 = sh.Range("C5:C" & lr).Find(Trim(n), LookIn:=xlValues) 'Finding that split value again
in column "C".
If Not rng2 Is Nothing Then 'if exists in column c then get.
secondvalue = rng2.Offset(0, 10).value 'corresponding cell values.
firstvalue = firstvalue & "," & secondvalue 'now first value is concatnated
with initial firstvalue
End If
Next n
MsgBox firstvalue
'Now i want to itterate over updated "firstvalue" in split function and this goes on in circular
fashion until rng value exists in firstvalue.
Next rng 'then change next rng and continue the above whole process for this value and so on.
End Sub
This code is working for initial firstvalue, can any one suggest any method to iterate over updated first value.
I'm not sure if I understand your goal exactly, but this code should find all predecessors for each task:
Sub circular()
Dim sh As Worksheet
Dim rTask As Range
Dim oCell As Range
Dim oFound As Range
Dim lr As Long, j As Long
Dim aPredecessors As Variant
Dim sCurTask As String
Dim secondValue As String
Set sh = ThisWorkbook.Worksheets("Sheet1")
lr = sh.Range("C" & Rows.Count).End(xlUp).Row
Set rTask = sh.Range("C5:C" & lr)
For Each oCell In rTask
sCurTask = Trim(oCell.Text)
aPredecessors = getPredecessors(Trim(oCell.Offset(0, 10).Text))
j = LBound(aPredecessors)
Do Until j > UBound(aPredecessors)
secondValue = aPredecessors(j)
If sCurTask = secondValue Then
ReDim Preserve aPredecessors(j)
Debug.Print "Task '" & sCurTask & "': Cyclic link '" & secondValue & "' for '" & Join(aPredecessors, ",") & "'!"
aPredecessors(j) = aPredecessors(j) & " !!!"
Else
If secondValue <> vbNullString Then
Set oFound = rTask.Find(secondValue, LookIn:=xlValues)
If oFound Is Nothing Then
ReDim Preserve aPredecessors(j)
Debug.Print "Task '" & sCurTask & "': Task '" & secondValue & "' for '" & Join(aPredecessors, ",") & "' not found!"
aPredecessors(j) = aPredecessors(j) & " ???"
Else
Call addNewTasks(aPredecessors, Trim(oFound.Offset(0, 10).Text))
End If
End If
End If
j = j + 1
Loop
oCell.Offset(0, 11).Value = Join(aPredecessors, ",")
Next oCell
End Sub
Function getPredecessors(sPredecessors As String)
Dim i As Long
Dim aTemp As Variant, sRes As String
Dim sTest As String
sRes = vbNullString
aTemp = Split(sPredecessors, ",")
For i = LBound(aTemp) To UBound(aTemp)
sTest = Trim(aTemp(i))
If InStr("," & sRes & ",", "," & sTest & ",") = 0 Then sRes = sRes & sTest & ","
Next i
If Len(sRes) > 1 Then sRes = Left(sRes, Len(sRes) - 1)
getPredecessors = Split(sRes, ",")
End Function
Sub addNewTasks(aData As Variant, sPredecessors As String)
Dim i As Long, uB As Long
Dim aTemp As Variant
Dim sTest As String, sValid As String
aTemp = Split(sPredecessors, ",")
If UBound(aTemp) >= 0 Then ' Not empty
sValid = "," & Join(aData, ",") & ","
For i = LBound(aTemp) To UBound(aTemp)
sTest = Trim(aTemp(i))
If sTest <> vbNullString Then
If InStr(sValid, "," & sTest & ",") = 0 Then
uB = UBound(aData) + 1
ReDim Preserve aData(uB)
aData(uB) = sTest
sValid = "," & Join(aData, ",") & ","
End If
End If
Next i
End If
End Sub

How to select the cells in a column that have a specific text in their value

I'm trying to get the cells that contain match the certain text criteria I search for.
I keep getting the error
Run-Time error 424 Object required
on line 12
cell = Sheets("Sheet1").Range("A" & row_num)
and I'm not sure why?
Any and all help with this would be greatly appreciated!
Option Compare Text
Sub FindingColumn()
Dim Col1Rng As Range, Col3Rng As Range
Dim Column1Search As String, Column2Search As String, Column3Search As
String
row_num = 0
Column1Search = InputBox("Col 1 Criteria: ")
Do
DoEvents
row_num = row_num + 1
cell = Sheets("Sheet1").Range("A" & row_num)
If Col2Rng = Empty And InStr(cell, Column1Search) Then
Col2Rng = cell.Address(0, 0)
ElseIf InStr(cell, Column1Search) Then
Col2Rng = Col2Rng & "," & cell.Address(0, 0)
End If
Loop Until cell = ""
Range(Col2Rng).Select
End Sub
This should serve as the basis for what you're trying to do
Sub FindingColumn()
Dim Col1Rng As Range, Column1Search As String, foundCellCol1 As Range
Set Col1Rng = ActiveSheet.Range("A:A")
Column1Search = InputBox("Col 1 Criteria: ")
Set foundCellCol1 = Col1Rng.Find(What:=Column1Search)
If Not foundCellCol1 Is Nothing Then foundCellCol1.Select Else: MsgBox "Search term not found!"
End Sub
Can you generate a list in another location of all of the items that match?
Option Explicit
Sub FindingColumn()
Dim Col1Rng As Range, Column1Search As String, foundCellCol1 As Range, lastRow As Long, lastFoundRow As Long
lastRow = Range("A100000").End(xlUp).Row
Set Col1Rng = ActiveSheet.Range("A1:A" & lastRow)
Column1Search = InputBox("Col 1 Criteria: ")
Set foundCellCol1 = Col1Rng.Find(What:="*" & Column1Search & "*")
While Not foundCellCol1 Is Nothing
If Not foundCellCol1 Is Nothing Then
Range("B" & Range("B100000").End(xlUp).Row + 1) = foundCellCol1.Value
Set Col1Rng = ActiveSheet.Range("A" & foundCellCol1.Row & ":A" & lastRow)
lastFoundRow = foundCellCol1.Row
Set foundCellCol1 = Col1Rng.Find(What:="*" & Column1Search & "*")
If foundCellCol1.Row = lastFoundRow Then Set foundCellCol1 = Nothing
End If
DoEvents
Wend
End Sub

Where is the error in my VBA code that read duplicates?

I have an Excel file. In column B row 11 is my product number range up to 100 rows. The code should find duplicate values in the column B. My code is like this:
Dim tgtWB As Workbook
Dim tgtWS As Worksheet
Dim LstRow As Long
LstRow = range("B" & Rows.count).End(xlUp).Row
r = 11
For i = 11 To LstRow
Do until tgWS.Range("B" & i) = "0"
If tgtWS.Range("B" & i) = tgtWS.Range("B" & i+1) Then
msgbox " Duplicate/s found! " & vbCrLf & tgtWS.Range("B" &i).value
exit sub
else
r = r+1
end if
Loop
Next
I just inserted the Do until because the program would stop reading
duplicate values if values in column B are blank or zero(0). And
the code compares only the column B Row 11 and 12.
What am I doing wrong?
Please examine this to see if it can be adapted to your needs:
Sub John()
Dim tgtWS As Worksheet
Dim LstRow As Long
Set tgtWS = ActiveSheet
LstRow = Range("B" & Rows.Count).End(xlUp).Row
For i = 11 To LstRow
If tgtWS.Range("B" & i) = "0" Then Exit Sub
If tgtWS.Range("B" & i) = tgtWS.Range("B" & i + 1) Then
MsgBox " Duplicate/s found! " & vbCrLf & tgtWS.Range("B" & i).Value
Exit Sub
End If
Next i
End Sub
It will find the first set of duplicates (if they are consecutive records) You would need a double loop if the dups are not consecutive

Show in MSgBox all nonempty values from row

I am working on an Excel sheet of row size A:ZZ and there should only be 7 cells with values. I am trying to make a kind of "filter" that will check the number of non empty cells and in case when there will be more than 7 nonempty cells will print a message in MsgBox (and till this point is working). But in the MsgBox I would like to se also just those values from the row (separated eg. with coma) - this is although not working due to some problem with Intersect syntax. Here is the code
Sub blanks()
Dim a, b As Integer
a = 0
Range("A1").Select
Do
With ActiveSheet.Range(Rows(b))
b = ActiveCell.Row
a = Application.WorksheetFunction.CountA(ActiveSheet.Rows(b))
If a > 7 Then
MsgBox ("ERROR" & "/n" & Application.Intersect(.SpecialCells(xlCellTypeVisible)))
Exit Do
Else
ActiveCell.Offset(1, 0).Select
End If
End With
Loop Until ActiveCell = "stop"
End Sub
What is there wrong?
This will give you the constant values (i.e. not from a formula):
Sub ShowValues()
Dim rowNum As Long
Dim rowRange As Range
Dim valRange As Range
Dim msg As String
rowNum = 1
With ThisWorkbook.Worksheets("Sheet1")
Do While .Cells(rowNum, 1) <> "stop"
Set rowRange = .Cells(rowNum, 1).Resize(1, 702)
If Application.WorksheetFunction.CountA(rowRange) > 7 Then
'Add row number to message.
msg = msg & "Row: " & rowRange.Row & ": "
'Add values to message separated by comman.
For Each valRange In rowRange.SpecialCells(xlCellTypeConstants)
msg = msg & valRange.Value & ", "
Next valRange
'Remove last comma.
msg = Left(msg, Len(msg) - 2)
'Line break.
msg = msg & vbCr
End If
rowNum = rowNum + 1
Loop
End With
MsgBox msg, vbOKOnly + vbInformation
End Sub
or this will give you the addresses:
Sub ShowAddressOfValues()
Dim rowNum As Long
Dim rowRange As Range
Dim msg As String
rowNum = 1
With ThisWorkbook.Worksheets("Sheet1")
Do While .Cells(rowNum, 1) <> "stop"
Set rowRange = .Cells(rowNum, 1).Resize(1, 702)
If Application.WorksheetFunction.CountA(rowRange) > 7 Then
msg = msg & "Row: " & rowRange.Row & ". Address: " & _
rowRange.SpecialCells(xlCellTypeConstants).Address & vbCr
End If
rowNum = rowNum + 1
Loop
End With
MsgBox msg, vbOKOnly + vbInformation
End Sub

Resources