I have a spreadsheet with over 10000 rows. I need to search it using InputBox (UPC field, input is from a barcode scanner).
I need to copy the row of the found cell, and paste it to another sheet.
This process should loop until the user cancels the InputBox.
I have done this, but it gives me an error on the SelectCells.Select line, but not every time.
Sub Scan()
Do Until IsEmpty(ActiveCell)
Dim Barcode As Double
Barcode = InputBox("Scan Barcode")
Dim ws As Worksheet
Dim SelectCells As Range
Dim xcell As Object
Set ws = Worksheets("Sheet1")
For Each xcell In ws.UsedRange.Cells
If xcell.Value = Barcode Then
If SelectCells Is Nothing Then
Set SelectCells = Range(xcell.Address)
Else
Set SelectCells = Union(SelectCells, Range(xcell.Address))
End If
End If
Next
SelectCells.Select
Set SelectCells = Nothing
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
Sheets("Sheet2").Select
ActiveSheet.Paste
Sheets("Sheet1").Select
Loop
End Sub
Copy Rows
Option Explicit
Sub Scan()
Const sName As String = "Sheet1"
Const Header As String = "Barcode"
Const dName As String = "Sheet2"
Const dFirstCellAddress As String = "A2"
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim surg As Range: Set surg = sws.UsedRange
Dim slCell As Range
Set slCell = surg.Cells(surg.Rows.Count, surg.Columns.Count)
Dim shCell As Range
Set shCell = surg.Find(Header, slCell, xlFormulas, xlWhole, xlByRows)
If shCell Is Nothing Then
MsgBox "The cell containing the header '" & Header _
& "' was not found.", vbCritical
Exit Sub
End If
Dim sfCol As Long: sfCol = surg.Column
Dim srg As Range
Set srg = sws.Range(sws.Cells(shCell.Row + 1, sfCol), slCell)
Dim scColIndex As Long: scColIndex = shCell.Column - sfCol + 1
Dim scrg As Range: Set scrg = srg.Columns(scColIndex)
Dim SelectedRows As Range
Dim Barcode As Variant
Dim srIndex As Variant
Do
Barcode = InputBox("Scan Barcode")
If Len(CStr(Barcode)) = 0 Then Exit Do
If IsNumeric(Barcode) Then
srIndex = Application.Match(CDbl(Barcode), scrg, 0)
If IsNumeric(srIndex) Then
If SelectedRows Is Nothing Then
Set SelectedRows = srg.Rows(srIndex)
Else
Set SelectedRows = Union(SelectedRows, srg.Rows(srIndex))
End If
End If
End If
Loop
If SelectedRows Is Nothing Then
MsgBox "No scan results.", vbExclamation
Exit Sub
End If
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dfCell As Range: Set dfCell = dws.Range(dFirstCellAddress)
Dim durg As Range: Set durg = dws.UsedRange
Dim dlRow As Long: dlRow = durg.Row + durg.Rows.Count - 1
Dim dlCell As Range
If dlRow < dfCell.Row Then
Set dlCell = dfCell
Else
Set dlCell = dws.Cells(dlRow + 1, dfCell.Column)
End If
SelectedRows.Copy dlCell
MsgBox "Rows copied.", vbInformation
End Sub
You can try something like this:
Sub Scan()
Dim Barcode As String, rngData As Range, m, rngDest As Range
'Column with barcodes
With Worksheets("Sheet1")
Set rngData = .Range("D1", .Cells(Rows.Count, "D").End(xlUp))
End With
'First paste postion
Set rngDest = Worksheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Offset(1)
Do
Barcode = InputBox("Scan Barcode")
If Len(Barcode) = 0 Then Exit Do
'm = Application.Match(Barcode, rngData, 0) 'Barcodes formatted as text
m = Application.Match(CDbl(Barcode), rngData, 0) 'Barcodes formatted as numbers
If Not IsError(m) Then
rngData.Rows(m).EntireRow.Copy rngDest 'copy to Sheet2
Set rngDest = rngDest.Offset(1)
Else
'if no match then what?
Debug.Print "no match"
End If
Loop
End Sub
Depending on how your barcodes are stored (as text, or a numeric values) you may need to use CDbl(Barcode) inside the call to Match()
Related
Hello all I did a macro in VBA that should check column D for the first empty cell then paste on that row but on column C, and when adding new info in the table it should take the first empty cell again, but it is replacing data, I don't check column C for first row because I have an filled cell midway, and if data were to replace that cell it should add a new row and avoid that.
`Sub CopyPasteToAnotherSheet()
Dim sourceRange As Range
Dim targetRange As Range
Dim lastRow As Long
Dim firstEmptyRow As Long
Set sourceRange = Selection
Set targetRange = Sheets("PARKING").Range("D18")
lastRow = targetRange.End(xlDown).Row
firstEmptyRow = Sheets("PARKING").Range("D" & lastRow).End(xlUp).Row + 1
If lastRow = targetRange.Row Then
targetRange.EntireRow.Insert
End If
If Sheets("PARKING").Range("C" & firstEmptyRow).Value <> "" Then
firstEmptyRow = firstEmptyRow + 1
End If
Set targetRange = Sheets("PARKING").Range("C" & firstEmptyRow)
sourceRange.Copy
targetRange.PasteSpecial xlPasteValues
End Sub
`
I have tried to work with different search ranges but it keeps overwriting data.
also if it would keep numbering the newly added rows when adding new data it would be great I am clueless on how I should do that
Append Values
Sub AppendValues()
Const PROC_TITLE As String = "Append Values"
Const DST_NAME As String = "PARKING"
Const DST_FIRST_CELL As String = "C18"
If Selection Is Nothing Then Exit Sub ' no visible workbooks open
If Not TypeOf Selection Is Range Then Exit Sub ' not a range
Dim srg As Range: Set srg = Selection
Dim sws As Worksheet: Set sws = srg.Worksheet
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
If Not sws.Parent Is wb Then Exit Sub ' not in this workbook
Dim dws As Worksheet: Set dws = wb.Sheets(DST_NAME)
If sws Is dws Then Exit Sub ' src. and dst. are the same worksheet
If dws.FilterMode Then dws.ShowAllData ' '.Find' will fail if 'dws' filtered
Dim dfCell As Range: Set dfCell = dws.Range(DST_FIRST_CELL)
Dim dlCell As Range
Set dlCell = dws.UsedRange.Find("*", , xlFormulas, , xlByRows, xlPrevious)
If Not dlCell Is Nothing Then
Set dfCell = dfCell.Offset(dlCell.Row - dfCell.Row + 1)
End If
Dim sarg As Range
For Each sarg In srg.Areas
dfCell.Resize(sarg.Rows.Count, sarg.Columns.Count).Value = sarg.Value
Set dfCell = dfCell.Offset(sarg.Rows.Count)
Next sarg
MsgBox "Values appended to worksheet """ & DST_NAME & """.", _
vbInformation, PROC_TITLE
End Sub
so i have a table named "Table1" in "sheet1" which range is from A2:B4, if i select B3 that would be Sheet("sheet1").range("Table1").cells(2,2) how would you check thru vba that the activecell in table1 is in cells(2,2)
im doing this because i will be copying/reflecting the value to another named table in another sheet to the same cells(2,2) the table has the same no. of rows and columns, it is exactly the same table just located in another sheet and in a different range
You could do it like this:
Sub Tester()
Dim rngT1 As Range, rngT2 As Range, rng As Range, rng2 As Range, addr
Set rngT1 = ActiveSheet.Range("Table1")
Set rngT2 = ActiveSheet.Range("Table2") 'could be different sheet...
Set rng = Application.Intersect(Selection, rngT1) 'part of selection within Table1
If Not rng Is Nothing Then 'any selection in table?
'get the address of the selection *relative* to Table1
addr = rng.Offset(-rngT1.Row + 1, -rngT1.Column + 1).Address(False, False)
Debug.Print addr
Set rng2 = rngT2.Range(addr) 'same relative range in Table2
rng2.Select 'for example
End If
End Sub
Reference the Same Cell in Another Same Sized Table
Sub ReferenceSameCell()
Dim wb As Workbook: Set wb = ThisWorkbook
Dim sws As Worksheet: Set sws = wb.Sheets("Sheet1")
Dim slo As ListObject: Set slo = sws.ListObjects("Table1")
Dim srg As Range: Set srg = slo.Range
Dim sCell As Range: Set sCell = ActiveCell
If Not sCell.Worksheet Is sws Then
MsgBox "Select a cell in worksheet '" & sws.Name & "'.", vbExclamation
Exit Sub
End If
If Intersect(sCell, srg) Is Nothing Then
MsgBox "Select a cell in table '" & slo.Name & "'.", vbExclamation
Exit Sub
End If
Dim dws As Worksheet: Set dws = wb.Sheets("Sheet2")
Dim dlo As ListObject: Set dlo = dws.ListObjects("Table2")
Dim drg As Range: Set drg = dlo.Range
Dim r As Long: r = sCell.Row - srg.Row + 1
Dim c As Long: c = sCell.Column - srg.Column + 1
Dim dCell As Range: Set dCell = drg.Cells(r, c)
Debug.Print r, c, sCell.Address, dCell.Address
End Sub
I would like to have a index match vba to be executed for one cell (C14) whereby the lookup cell would be C15. Please help advise where did the code went wrong?
Source data would be export workbook sheet1.
Sub Index_Match()
Dim custName As Range 'sourceRange
Dim BRN As Range 'lookupRange
Dim ws As Worksheet 'current sheet
Dim exportWb As Workbook
Dim exportWs As Worksheet
Set ws = Sheet1
Set exportWb = Workbooks.Open("C:\Users\hrhquek\desktop\export.xlsx")
Set exportWs = exportWb.Worksheets("Sheet1")
Set exportWb = ActiveWorkbook
ThisWorkbook.Activate
Set custName = exportWs.Cells(exportWs.Rows.Count, "B").End(xlUp).Row
Set BRN = exportWs.Cells(exportWs.Rows.Count, "E").End(xlUp).Row
ws.Cells(3, 14).Value = Application.WorksheetFunction.Index(custName,
Application.WorksheetFunction.Match(Cells(3, 15), BRN, 0))
End Sub
A VBA Lookup: INDEX/MATCH in VBA
Sub VBALookup()
' Source
Dim swb As Workbook
Set swb = Workbooks.Open("C:\Users\hrhquek\desktop\export.xlsx")
Dim sws As Worksheet: Set sws = swb.Worksheets("Sheet1")
Dim slRow As Long: sws.Cells(sws.Rows.Count, "E").End(xlUp).Row
Dim slrg As Range: Set slrg = sws.Range("E2:E" & slRow)
Dim svrg As Range: Set svrg = sws.Range("B2:B" & slRow)
' Destination
Dim dws As Worksheet: Set dws = Sheet1 ' code name in 'ThisWorkbook'
Dim dlCell As Range: Set dlCell = dws.Range("O3")
Dim dvCell As Range: Set dvCell = dws.Range("N3")
Dim dValue As Variant: dValue = dlCell.Value
' Attempt to find a match.
Dim MatchFound As Boolean
If Not IsError(dValue) Then
If Len(CStr(dValue)) > 0 Then
Dim sIndex As Variant: sIndex = Application.Match(dValue, slrg, 0)
If IsNumeric(sIndex) Then MatchFound = True
End If
End If
' Write result.
If MatchFound Then
dvCell.Value = svrg.Cells(sIndex).Value
MsgBox "Match found.", vbInformation
Else
dvCell.Value = Empty
MsgBox "No match found.", vbExclamation
End If
End Sub
I want to apply vlookup only on the blank cells through VBA. I am using the below code, but it gives me a Run-time error 13 "Type mismatch".When I run the code step by step via F8, I also get an error 2042 at position If i = "" Then, which also indicates "#N/A".
Dim FileName3 As String
FileName3 = "C:xxxxxx.xlsx"
Dim wb As Workbook: Set wb = ThisWorkbook
Dim lastrow As Long
Dim ws As Worksheet: Set ws = wb.Sheets("Data")
lastrow = ws.cells(Rows.Count, 1).End(xlUp).Row
Dim wb2 As Workbook: Set wb2 = Workbooks.Open(Filename:=FileName3, ReadOnly:=True)
Dim rng As Range: Set rng = ThisWorkbook.Worksheets("Data").Range("S2" & lastrow)
Dim lookupRange As Range: Set lookupRange = wb2.Sheets("Page 1").Range("B2" & lastrow)
Dim i As Range
For Each i In rng
If i = "" Then
i = Application.VLookup(ThisWorkbook.Sheets("Data").Range("A" & i.Row), lookupRange, 2, False)
'MsgBox c.Row
End If
'
Next i
'/////// paste by value
Sheets("Data").Columns(52).Copy
Sheets("Data ").Columns(52).PasteSpecialxlPasteValues
wb2.Close False
ThisWorkbook.Save
I had tried it before with WorksheetFunction.VlookUp, but the same error comes up.
The VlookUp should be executed in the datasheet ("Data") in column "S" for all empty cells.
The LookUp Values are located in another workbook file. I would appreciate it very much if someone could help me.
VBA VLookup For Blank Cells
Option Explicit
Sub VLookupBlanks()
Const sFilePath As String = "C:\xxxxxx.xlsx"
Application.ScreenUpdating = False
Dim swb As Workbook
Set swb = Workbooks.Open(Filename:=sFilePath, ReadOnly:=True)
Dim sws As Worksheet: Set sws = swb.Worksheets("Page 1")
Dim slRow As Long: slRow = sws.Cells(sws.Rows.Count, "B").End(xlUp).Row
Dim srg As Range: Set srg = sws.Range("B2:C" & slRow)
Dim dwb As Workbook: Set dwb = ThisWorkbook
Dim dws As Worksheet: Set dws = dwb.Worksheets("Data")
Dim dlRow As Long: dlRow = dws.Cells(dws.Rows.Count, "A").End(xlUp).Row
Dim drg As Range: Set drg = dws.Range("S2:S" & dlRow)
Dim dCell As Range
Dim dValue As Variant
For Each dCell In drg.Cells
If Len(CStr(dCell.Value)) = 0 Then
dValue = Application.VLookup( _
dCell.EntireRow.Columns("A").Value, srg, 2, False)
If Not IsError(dValue) Then dCell.Value = dValue
End If
Next dCell
swb.Close SaveChanges:=False
With drg.EntireRow.Columns("AZ")
.Value = .Value
End With
dwb.Save
Application.ScreenUpdating = True
MsgBox "Columns updated.", vbInformation
End Sub
Please, try removing of:
Dim rng As Range: Set rng = ThisWorkbook.Worksheets("Data").Range("S2" & lastrow)
Dim lookupRange As Range: Set lookupRange = wb2.Sheets("Page 1").Range("B2" & lastrow)
Dim i As Range
For Each i In rng
If i = "" Then
i = Application.VLookup(ThisWorkbook.Sheets("Data").Range("A" & i.Row), lookupRange, 2, False)
'MsgBox c.Row
End If
'
Next i
with:
Dim rngV As Range
Dim rng As Range: Set rng = ws.Range("S2:S" & lastrow)
Dim lookupRange As Range: Set lookupRange = wb2.Sheets("Page 1").Range("B2:C" & lastrow)
On Error Resume Next 'only to avoid an error if no any empty cell exists in rng
Set rngV = rng.SpecialCells(xlCellTypeBlanks)
On Error GoTo 0
If rngV Is Nothing Then Exit Sub 'no any empty cell...
rngV.Formula = "=Vlookup(A" & rngV.cells(1).row & ", " & lookupRange.Address(external:=True) & ", 2, False)"
I want to select particular columns and then paste this onto a particular sheet, if sheet exists then erase existing data and paste newly copied data. This should work in loop to be refreshed with new data entered in the main sheet.
My code creates the required sheet but pastes data into another new sheet.
Sub Datasort()
'The sheet with all the imported data columns must be active when this macro is run
Dim newSht As Worksheet, sSht As Worksheet, Hdrs As Variant, i As Long, Fnd As Range, Sheet_Name As String
Set sSht = Worksheets("all zip codes")
'Expand the array below to include all relevant column headers
Hdrs = Array("Country", "Zip codes", "GSS")
Application.ScreenUpdating = False
Sheet_Name = "Dataformatted"
Set newSht = Worksheets.Add(after:=sSht)
With sSht.UsedRange.Rows(1)
For i = LBound(Hdrs) To UBound(Hdrs)
Set Fnd = .Find(Hdrs(i), lookat:=xlWhole)
If Not Fnd Is Nothing Then
Intersect(Fnd.EntireColumn, sSht.UsedRange).Copy
newSht.Cells(1, i + 1).PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
newSht.Cells(1, i + 1).PasteSpecial Paste:=xlPasteColumnWidths
End If
Next i
Application.CutCopyMode = False
End With
If (Sheet_Exists(Sheet_Name) = False) And (Sheet_Name <> "") Then
Worksheets.Add(after:=sSht).Name = Sheet_Name
End If
Application.ScreenUpdating = True
End Sub
Function Sheet_Exists(WorkSheet_Name As String) As Boolean
Dim newSht As Worksheet
Sheet_Exists = False
For Each newSht In ThisWorkbook.Worksheets
If newSht.Name = WorkSheet_Name Then
Sheet_Exists = True
End If
Next
End Function
(not tested), but you're adding sheet everytime it runs, so assuming everything else works fine, you should:
replace Set newSht = Worksheets.Add(after:=sSht) with below
if not Sheet_Exists(Sheet_Name) then Worksheets.Add(after:=sSht).Name = Sheet_Name
Set newSht = Worksheets(Sheet_Name)
and remove the following part
If (Sheet_Exists(Sheet_Name) = False) And (Sheet_Name <> "") Then
Worksheets.Add(after:=sSht).Name = Sheet_Name
End If
Copy Worksheet Columns
Option Explicit
Sub Datasort()
Const sName As String = "all zip codes"
Const dName As String = "Dataformatted"
Const dfcAddress As String = "A1"
Dim Headers As Variant: Headers = VBA.Array("Country", "Zip codes", "GSS")
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim srg As Range: Set srg = sws.UsedRange
Dim shrg As Range: Set shrg = srg.Rows(1)
Application.ScreenUpdating = False
Dim dws As Worksheet
On Error Resume Next
Set dws = wb.Worksheets(dName)
On Error GoTo 0
If dws Is Nothing Then
Set dws = wb.Worksheets.Add(After:=sws)
dws.Name = dName
Else
dws.UsedRange.Clear
End If
Dim dfCell As Range: Set dfCell = dws.Range(dfcAddress)
Dim scrg As Range
Dim hIndex As Variant
Dim c As Long
For c = 0 To UBound(Headers)
hIndex = Application.Match(Headers(c), shrg, 0)
If IsNumeric(hIndex) Then
Set scrg = srg.Columns(hIndex)
dfCell.Resize(scrg.Rows.Count).Value = scrg.Value
dfCell.EntireColumn.ColumnWidth = scrg.EntireColumn.ColumnWidth
Set dfCell = dfCell.Offset(, 1)
End If
Next c
Application.ScreenUpdating = True
MsgBox "Data formatted."
End Sub