Create a list of unique values when referencing a column in excel - excel

I have two worksheets in the same workbook. In Sheet1 Column 1 is of expected stock barcodes, in Sheet2, Column 2 is comprised of the barcodes which I scanned.
I wrote a formula in conditional formatting to check items Column 2 and color them if they are not in Column 1, but I don't want to have to scroll through the entire list to see this.
What I want to do is populate a third (and fourth for quantity) column with only entries that are in Column 2 and not Column 1, and if possible, list the number of times it was found in Column 2.
Example:
Column 1
bc123
bc1234
bc12345
bc123456
bc1234567
Column 2
bc12345
bc123456
bc56789
bc67890
bc67890
Column 3 (Automatically populated with unique entries from column 2)
bc56789 1
bc67890 2
Thank you!

Here, my VBA approach for your problem:
Public Sub findAndCount()
Dim sh1, sh2 As Worksheet
Dim foundCell As Range
Dim startSheet2, resultRow As Integer
'Set sheets
Set sh1 = Sheets("Sheet1")
Set sh2 = Sheets("Sheet2")
'Set the start row of column from Sheet2
startRow = 1
resultRow = 1
'Clear old result from column C & D of Sheet1
sh1.Range("C:D").ClearContents
'Loop all row of column 2 from Sheet2 until blank
Do While sh2.Range("B" & startRow) <> ""
'Find value in column A of Sheet1
Set foundCell = sh1.Range("A:A").Find(sh2.Range("B" & startRow), LookIn:=xlValues)
'If match value is not found
If foundCell Is Nothing Then
'Find result is already exist or not
Set foundCell = sh1.Range("C:C").Find(sh2.Range("B" & startRow), LookIn:=xlValues)
'If result is not exist, add new result. (Here, I show result in Sheet1, you can change it.)
If foundCell Is Nothing Then
'Set barcode
sh1.Range("C" & resultRow) = sh2.Range("B" & startRow)
'Set count
sh1.Range("D" & resultRow) = 1
'Increase result row
resultRow = resultRow + 1
'If already exist
Else
'Increase count
foundCell.Offset(0, 1) = foundCell.Offset(0, 1).Value + 1
End If
End If
'Increase row
startRow = startRow + 1
Loop
End Sub

Related

Search match twice 2 keywords same column and copy result to another sheet

I am stuck i don't know what code to use so i can search the same column twice for 2 different keyword and then copy data from the same row to another spreadsheet in sequence from a start cell. for details here's what i am trying to do.
Limit the search within a range of the worksheet (ex. Sheet 1 B1:N:200)
Search the 8th column (I) of the limit range Sheet1 for keyword ("Goods")
Copy the data found in the 2nd (C) and 5th column (F) of same row where instance "Goods " is found
Paste Value of Sheet 1 - column 2 to Sheet2 - Column 3 (no format values only), and Sheet 1 column 5 to Sheet 2 Column4 (with format and values) on a specific starting point (ex. Sheet 2 - B3) Next Match Result will be Sheet 2 - B4 and so on
5.Search AGAIN the 8th column of Sheet1 for keyword ("Services") starting from the top (B1:N1)
6.Copy the data found in the 2nd (C) and 5th column (F) of same row where instance "Services" is found
Paste Value of Sheet 1 - column 2 to Sheet2 - Column 3 (no format values only), and Sheet 1 column 5 to Sheet 2 Column4 (with format and values) to next row after the last PASTE from "Goods" was done. (ex last row match paste was C35 and D35 new found value should be paste in C36 a D36)
Ending Output should be all "Goods" results first then "Services" results
I hope i have conveyed what i need clearly
I am trying to work on this code that i found here but i just don't get how to insert the 2nd search loop for services., how to paste on specific cell in sheet2, how to follow the last row for services paste
Sub CopyCells
Dim lngLastRowSht1 As Long
Dim lngLastRowSht2 As Long
Dim counterSht1 As Long
Dim counterSht2 As Long
With Worksheets(1)
lngLastRowSht1 = .Cells(.Rows.Count, 8).End(xlUp).Row
lngLastRowSht2 = Worksheets(2).Cells(Worksheets(2).Rows.Count, 5).End(xlUp).Row
For counterSht1 = 1 To lngLastRowSht1
For counterSht2 = 1 To lngLastRowSht2
If Sheets(1).Range("" & (counterSht1)).Value = "Goods" Then
Sheets(2).Range("B" & (counterSht2), "D" & (counterSht2)).Value = Sheets(1).Range("C" & counterSht1, "D" & counterSht1).Value
End If
Next counterSht2
Next counterSht1
End With
End Sub
Edit1
As per request of sir Chris this is how it should look like
Answer for this Query was best solved by #CDP1802 Worked as needed.
I learned that I needed 2 counters for it to work :) and I also learned how to properly label target destination.
Thank you for this community:)
Increment the target row after each copy.
Option Explicit
Sub CopyCells()
Const ROW_START = 3
Dim wb As Workbook, ws1 As Worksheet, ws2 As Worksheet
Dim n As Long, r As Long, lastrow1 As Long, lastrow2 as Long
Dim keywords, word, t0 As Single: t0 = Timer
keywords = Array("Goods", "Services")
Set wb = ThisWorkbook
Set ws1 = wb.Sheets(1)
Set ws2 = wb.Sheets(2)
lastrow2 = ROW_START
Application.ScreenUpdating = False
With ws1
lastrow1 = .Cells(.Rows.Count, "I").End(xlUp).Row
For Each word In keywords
For r = 1 To lastrow1
If Len(.Cells(r, "I")) = 0 Then
Exit For
ElseIf .Cells(r, "I") = word Then
'Sht1 col 2 to Sht2 Col 3 (no format values only)
'Sht1 col 5 to Sht2 Col 4 (with format and values)
ws2.Cells(lastrow2, "C") = .Cells(r, "B")
ws2.Cells(lastrow2, "D") = .Cells(r, "E")
.Cells(r, "E").Copy
ws2.Cells(lastrow2, "D").PasteSpecial xlPasteFormats
lastrow2 = lastrow2 + 1
n = n + 1
End If
Next
Next
End With
Application.ScreenUpdating = True
MsgBox r - 1 & " rows scanned " & vbLf & n & " rows copied", _
vbInformation, Format(Timer - t0, "0.0 secs")
End Sub
You could make two routines: one for services and one for goods. But that code and the code above isn't very efficient.
Since Services & Goods are in the same column, try using the autofilter:
Sheets(2).UsedRange.autofilter Field:=8, Criteria1:=Array("Goods", "Services"), VisibleDropDown:=False, Operator:=xlFilterValues
Sheets(2).UsedRange.SpecialCells(xlCellTypeVisible).Copy
Sheets(1).Range("A1").PasteSpecial
Application.CutCopyMode = False

Excel copy-paste range on specific sheet according to cell value

I have a workbook with a master sheet called "NIR" containing the following data: Column A contains product names(the same as the rest of the worksheets names);Column B contains quantity and Column C contains prices.
I want to create a VBA to search in my master sheet "NIR" in Column A and copy Columns B and C to specific sheets according to master sheet "NIR" ,cells in Column A.
Example:
Sheet "NIR"
A3="shoes"
A4="pants"
B3 = 3 (pairs)
C3 = 10 (price)
copy B3 and C3 to sheets "shoes" and "pants"according to Sheet"NIR" A3
Try:
Option Explicit
Sub Macro1()
Dim LastRowNIR As Long, i As Long, LastRowWs As Long
Dim arr As Variant
With ThisWorkbook.Worksheets("NIR")
'Find the last row of column A
LastRowNIR = .Cells(.Rows.Count, "A").End(xlUp).Row
'Import all data in an array starting from A1 to C last row
arr = .Range("A1:C" & LastRowNIR)
'Loop array
For i = LBound(arr) To UBound(arr)
With ThisWorkbook.Worksheets(arr(i, 1))
'Find the last row of column B
LastRowWs = .Cells(.Rows.Count, "B").End(xlUp).Row
'Write in the next available row the quantity
.Range("B" & LastRowWs + 1).Value = arr(i, 2)
'Write in the next available row the prices
.Range("C" & LastRowWs + 1).Value = arr(i, 3)
End With
Next i
End With
End Sub

Matching text in cells of one column against cells in columns with a variable number of rows

I have an Excel file with two sheets: Master and sheet two.
Master has one column of roughly 50 rows each containing a word.
Sheet two has 23 columns of varying lengths, the largest going up to 95 rows.
My goal is to use column one on Master to search each column on sheet 2 for text matches and then output all the matches below their respective columns on sheet 2.
The issue is after the first column on sheet 2 the matching often misses words.
Sub CompareFNL()
Application.ScreenUpdating = False
Dim WS As Worksheet
Set WS = Sheets("Master")
Dim rng As Range
Dim Column2 As Integer
Dim RowsMaster As Integer, Rows2 As Integer
RowsMaster = WS.Cells(100, 1).End(xlUp).row
Rows2 = Worksheets(2).Cells(100, 1).End(xlUp).row
Column2 = Worksheets(2).Cells(1, 24).End(xlToRight).Column
' Get the number of used rows for each sheet
With Worksheets(2)
For c = 1 To Column2
For i = 1 To Rows2
'Loop through Sheet 2
For j = 1 To RowsMaster
'Loop through the Master sheet
If .Cells(i, c) = WS.Cells(j, 1) Then
'If a match is found:
Worksheets(2).Cells(i + 110, c) = WS.Cells(j, 1)
'Copy int sheet2 in their respective columns
Exit For
End If
Next j
Next i
Next c
'Store blank cells inside a variable
On Error GoTo NoBlanksFound
Set rng = Range("a110:x250").SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
'Delete blank cells and shift upward
rng.Rows.delete Shift:=xlShiftUp
'ERROR HANLDER
NoBlanksFound:
MsgBox "No Blank cells were found"
End With
Application.ScreenUpdating = True
End Sub
can you add .Cells(i,j).Value to see whether it works or not:
If .Cells(i, c).Value = WS.Cells(j, 1).Value Then

How to delete all rows from sheet1 which is not in sheet2

friends I have Two Excel Sheets which is shown below...
**Sheet_1** **Sheet_2**
ID Name Address ID Name Address
1 A Any 2 B Any
2 B Any 4 D Any
3 C Any 5 E Any
4 D Any
5 E Any
I want to delete all rows from Sheet_1 which is not in Sheet_2.
Note: ID of sheets is unique
I'm not sure if I got this right, but you want to delete rows that are not in Sheet2?
So that would make your Sheet1 to be a copy of Sheet2, wouldn't it?
Well, anyways, here is the code of the main Sub:
Sub Main()
Set idsToExclude = CreateObject("Scripting.Dictionary"): idsToExclude.CompareMode = TextCompare
'fill dictionary with IDs from sheet 2
Set idsToExclude = CreateDictFromColumns("Sheet2", "A", "B")
'find last populated row
xEndRow = Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
'iterate all rows from bottom to top
For i = xEndRow To 2 Step -1
'get value of cell at current row and 1st column
currentCellValue = ActiveSheet.Cells(i, 1).Value
'if row doesnt met criteria, delete it
If Not idsToExclude.Exists(currentCellValue) Then
Rows(i).Delete
End If
Next
End Sub
And the Function to get the Ids and names from a specific Sheet:
Function CreateDictFromColumns(sheet As String, keyCol As String, valCol As String) As Object
Set dict = CreateObject("Scripting.Dictionary"): dict.CompareMode = TextCompare
Dim rng As Range
Dim i As Long
Dim lastCol As Long '// for non-adjacent ("A:ZZ")
Dim lastRow As Long
lastRow = Sheets(sheet).Range(keyCol & Sheets(sheet).Rows.Count).End(xlUp).Row
Set rng = Sheets(sheet).Range(keyCol & "1:" & valCol & lastRow)
lastCol = rng.Columns.Count
For i = 2 To lastRow
If (rng(i, 1).Value = "") Then Exit Function
dict.Add rng(i, 1).Value, rng(i, lastCol).Value
Next
Set CreateDictFromColumns = dict
End Function
Note: If you want to make the contrary (delete IDs in Sheet1 that are in Sheet2), just remove the Not Operator from the following line:
If Not idsToExclude.Exists(currentCellValue) Then
As you can see, some parts are hard-coded. My suggestion is to adapt those parts and make it more dynamical, I had to write it like that due to lack of details in question.

Comparing two columns in the same sheet

I have two columns A and B, If A Column have the specific value for Eg: High then the corresponding B Column should contain the Date value.
If A Column have the specific value for Eg: High and the corresponding B Column does not have date value then the cell should be highlighted as Red.
Sub ColorColB()
Dim sht As Worksheet
Dim LastRow, i As Long
Set sht = ActiveSheet
Find the last cell in column A... counts how many rows
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Run a loop.. checking if there is nothing in column B then color it red
For i = 1 to LastRow
If cells(i, 2) = "" then Range("B" & i).Interior.Color = RGB(255, 0, 0)
Next i
End sub

Resources