Find same value and paste data at side of it - excel

I've searched everywhere and can't seem to find help on a macro I'm trying to get working to make life a little easier at work.
We have laser scanners and what I'm trying to do, is use a search box so we can scan a code, this will then check the full A column.
If something the code is found from A3, it will paste the data say from A3, B3 & C3 to say E3, F3, G3.
Currently the macro I have, Finds the data (say in A1) then copies the complete A ROW to sheet 2, yet I want it all to be on one sheet.
BEFORE SEARCHING 1111111
AFTER SEARCHING 1111111
USING THIS CODE
Option Explicit
Sub Main()
Application.ScreenUpdating = False
Dim rangeToSearch As range
Set rangeToSearch = Sheets(1).range("A2:A" & Sheets(1).range("A" & Rows.Count).End(xlUp).Row)
Dim searchAmount As String
searchAmount = InputBox("Type in the amount to search for:")
Dim cell As range
For Each cell In rangeToSearch
If cell = CLng(searchAmount) Then
Sheets(1).Rows(cell.Row & ":" & cell.Row).Copy
Sheets(2).Rows( _
Sheets(2).range("A" & Rows.Count).End(xlUp).Row + 1 & _
":" & _
Sheets(2).range("A" & Rows.Count).End(xlUp).Row + 1 _
).PasteSpecial _
Paste:=xlPasteValues, Operation:=xlNone, _
SkipBlanks:=False, Transpose:=False
Application.CutCopyMode = False
End If
Next
Application.ScreenUpdating = True
End Sub

I've slightly modified your code, now it's more simple and without loop statement:
Option Explicit
Sub Main()
Application.ScreenUpdating = False
Dim rangeToSearch As Range
With Sheets(1)
Set rangeToSearch = .Range("A2:A" & .Range("A" & .Rows.Count).End(xlUp).Row)
End With
Dim searchAmount As String
searchAmount = InputBox("Type in the amount to search for:")
Dim cell As Range
Set cell = rangeToSearch.Find(searchAmount, LookIn:=xlValues)
With Sheets(1)
If Not cell Is Nothing Then
.Range("E" & cell.Row & ":G" & cell.Row).Value = _
.Range("A" & cell.Row & ":C" & cell.Row).Value
Else
MsgBox "Value " & searchAmount & " not found"
.Range("L4").Value = searchAmount
End If
End With
Application.ScreenUpdating = True
End Sub

Related

Why won't the concatenate function in vba work?

I am new to vba and need a little help. I want to copy copy column A & C to sheet 2 but my concatenation syntax (my_range = rng1&":"&rng2) won't work.
I have tried other syntax too but it's just syntax to concatenate Strings into a single column and that's what I am looking for. What I want is Column A & C from sheet 1 to be copied in Column A & B in sheet 2.
Sub CommandButton1_Click()
Dim my_range As String, rng1 As String, rng2 As String
search_value = Sheets(2).Cells(i, 1).Value = 1
Sheets(1).Activate
For i = 2 To 100
If Sheets(1).Cells(i, 1).Value = search_value Then
rng1 = "A" & i
rng2 = "C" & i
my_range = rng1&":"&rng2
Sheets(1).Rande(my_range).Select
Selection.Copy
Sheets(2).Activate
Sheets(2).Range("A2").Select
Selection.PasteSpecial: xlPasteAll , SkipBlanks:=True, Transpose:=False
End If
Next
Application.CutCopyMode = False
Sheets(2).Cells(1, 2).Select
End Sub
The simplest way to create a range from one cell to the other is the following:
my_range = Range(rng1, rng2)
(I found some examples on this website.)
Do it like below :
rng1 = "A" & CStr(i)
rng2 = "C" & CStr(i)
my_range = rng1 & ":" & rng2

Checking to see if cell values are integers, if not then adding message

I have a column (col G) where I want to verify the values are numeric. If they are not numeric I want to paste an error message in col A. I don't get any errors when running my code, but it seems to print the error message even though there is a number in the cell.
Dim cell As Range
Dim lastRow As Long
lastRow = Range("G" & Rows.Count).End(xlUp).row
For Each cell In Range("G2:" & "G" & lastRow)
If IsNumeric(Range("G2:" & "G" & lastRow)) = True Then cell.Offset(0, -6).Value = cell.Offset(0, -6).Value & ", G is not a number"
Next
End Sub
Looping through cells with condition could be done like this:
Sub TestMe()
Dim cell As Range
Dim lastRow As Long
lastRow = Worksheets(1).Range("G" & Rows.Count).End(xlUp).Row
For Each cell In Worksheets(1).Range("G2:" & "G" & lastRow)
If IsError(cell) Then
cell.Offset(0, -6).Value = cell.Address & " is error!"
ElseIf Not IsNumeric(cell.Value) Then
cell.Offset(0, -6).Value = cell.Value & " is not a number"
End If
Next
End Sub
It is a good practice to refer to the parent worksheet as in Worksheets(1).Range....

How to copy the contents of two cells dynamically?

Right now my program works. But, I need to copy another cell that's next to the cell being copied when a match is found. I go through myrange1 and when I find a match in myrange2, I copy the contents from Column A in Sheet1 from whichever cell it's at. I want column B, same cell index, to be copied and pasted as well. My copied data is getting pasted in Column(s) R:S. of Sheet2. Column R is the numbers and S is the data.
Sub matchcopy()
Dim i&
Dim myrange1 As Range, myrange2 As Range, myrange3 As Range, cell As Range
' You can use the Codenames instead of Worksheet("Sheet1") etc.
Set myrange1 = Sheet1.Range("A1", Sheet1.Range("A" & Rows.Count).End(xlUp))
Set myrange2 = Sheet2.Range("A1", Sheet2.Range("A" & Rows.Count).End(xlUp))
Set myrange3 = Sheet2.Range("B1", Sheet2.Range("B" & Rows.Count).End(xlUp))
Sheet2.Range("R:S") = "" ' <~~ clear result columns
For Each cell In myrange1 ' presumably unique items
If Not IsError(Application.Match(cell.Value, myrange2, 0)) Then
'Sheet2.Cells(i, 2).Offset(, 1).Resize(1, 1).Copy
cell.Copy
With Sheet2.Range("R50000").End(xlUp)
i = i + 1 ' <~~ counter
.Offset(1, 0) = i ' counter i equals .Row - 1
.Offset(1, 1).PasteSpecial xlPasteFormulasAndNumberFormats
End With
Else
'MsgBox "no match is found in range"
End If
Next cell
Sheet2.Columns("R:S").EntireColumn.AutoFit
Call Set_PrintRnag
End Sub
Sub Set_PrintRnag()
Dim LstRw As Long
Dim Rng As Range
Dim strDesktop As String
Application.ScreenUpdating = True
strDesktop = CreateObject("WScript.Shell").SpecialFolders("Desktop")
LstRw = Sheet2.Cells(Rows.Count, "R").End(xlUp).Row
Set Rng = Sheet2.Range("R1:S" & LstRw)
With Sheet2.PageSetup
.LeftHeader = "&C &B &20 Cohort List Report:" & Format(Now, "mm/dd/yyyy")
.CenterFooter = "Page &P of &N"
.CenterHorizontally = False
.FitToPagesWide = 1
.RightFooter = ""
End With
Rng.ExportAsFixedFormat Type:=xlTypePDF, Filename:=strDesktop & "\CohortList " & " " & Format(Date, "mm-dd-yyyy") & ".pdf", Quality:=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
End Sub
https://learn.microsoft.com/en-us/office/vba/api/excel.range.offset
You have a cell in column 'A' BUT you want same row in column 'B'.
cell.Offset(0,1).value = cell.value

VBA incorrectly entering range as series name

I'm trying to create a dynamic graph in VBA in Excel. Unfortunately, when I generate the graph the values that are meant for the y axis are ending up as the series name. Here's the graph. I'm an extremely new VBA user, so I'm sure I am just overlooking a very basic error. Here is my code.
Sheets("Sheet1").Activate
Dim lRow As Long
Dim lCol As Long
'Find the last non-blank cell in column G and H
Range("G3:H500").Select
Do Until ActiveCell.Value = ""
ActiveCell.Offset(1, 0).Select
Loop
lastrow = ActiveCell.Row - 1
'Find the last non-blank cell in row 1
lCol = Cells(1, Columns.Count).End(xlToLeft).Column
MsgBox "Last Row: " & lastrow & vbNewLine & _
"" & Columns(lCol).Address(False, False)
Set rng = Range("G3:H300" & lastrow)
Set xrang = Range("F3:F300" & lastrow)
rng.Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ApplyChartTemplate ( _
"c:\users\name\appdata\Roaming\Microsoft\Templates\Charts\brand_line_chart.crtx" _
)
ActiveChart.SetSourceData Source:=Range("G3:H300" & lastrow)
ActiveChart.Axes(xlCategory).Select
ActiveChart.SeriesCollection(1).XValues = Range("F3:F300" & lastrow)
Any help would be greatly appreciated, thank you!
Delete this line ActiveChart.SeriesCollection(1).XValues = Range("F3:F300" & lastrow). Also since you are getting the lastrow data , change the ("G3:H300" & lastrow) to ("G3:H" & lastrow). Do this everywhere you have set range

Filter to determain cells to be copied, now copies the last found criteria

I'm having troubles with the output of my code. Im using a macro to search for some criteria which are labeled:
Collection = Trim(Range("lblImportCollection").Value)
System = Trim(Range("lblImportSystem").Value)
Tag = Trim(Range("lblImportTag").Value)
My filter does search the right cell values where the input values are found, but I want to copy the matched values to a new sheet. Now it just copies the last correct value that is found. Can someone help me with it? What I want:
If all three criteria match( I want to copy the 3 criteria in a row on the new worksheet)
If two criteria match( I want to copy the 2 criteria in a row(and not the third one)
If one criteria match( I want to copy the 1 criteria in a row(so not the second and the third)
Also: All resulting matches must fill a new row.
I hope I gave enough information, it's a bit hard to explain. If you have questions, let me know :)
Sub FilterButton()
Dim XUsedRange As Range
Dim SourceRange As Range, DestRange As Range
Dim SrcSheet As Worksheet
Dim DestSheet As Worksheet, Lr As Long
Dim firstAddress As String
Dim c As Range
Dim iLastRow As Integer
Dim zLastRow As Integer
Dim test As String
Dim TempRange As Range
Dim Collection As String
Dim System As String
Dim Tag As String
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Collection = Trim(Range("lblImportCollection").Value)
System = Trim(Range("lblImportSystem").Value)
Tag = Trim(Range("lblImportTag").Value)
'fill in the Source Sheet and range
Set XUsedRange = Sheets("Imported Data").UsedRange
Set ZUsedRange = Sheets("Test").Range("A:C")
'Fill in the destination sheet and find the last known cell
Set DestSheet = Sheets("Test")
Set SrcSheet = Sheets("Imported Data")
'With the information on the new sheet
iLastRow = XUsedRange.End(xlDown).Row
zLastRow = ZUsedRange.End(xlUp).Row
Set SourceRange = SrcSheet.Range("A2:A" & CStr(iLastRow))
Set DestRange = DestSheet.Range("A2:C" & CStr(zLastRow))
With SourceRange
Set c = SourceRange.Find(What:=Collection, SearchOrder:=xlByColumns)
If Not c Is Nothing Then
firstAddress = c.Address
Do
MsgBox ("Found " & Collection & " on address:" & c.Address)
c.Copy
DestRange.PasteSpecial
If System = SrcSheet.Range("B" & CStr(c.Row) & ":B" & CStr(c.Row)) Then
MsgBox ("The system is " & SrcSheet.Range("B" & CStr(c.Row) & ":B" & CStr(c.Row)))
'DestSheet.Range ("B" & CStr(c.Row) & ":B" & CStr(c.Row))
SrcSheet.Range("B" & CStr(c.Row) & ":B" & CStr(c.Row)).Copy
DestRange.PasteSpecial
If Tag = SrcSheet.Range("C" & CStr(c.Row) & ":C" & CStr(c.Row)) Then
MsgBox ("The tag is" & SrcSheet.Range("C" & CStr(c.Row) & ":C" & CStr(c.Row)))
'DestSheet.Range ("C" & CStr(c.Row) & ":C" & CStr(c.Row))
SrcSheet.Range("C" & CStr(c.Row) & ":C" & CStr(c.Row)).Copy
DestRange.PasteSpecial
End If
End If
Set c = SourceRange.FindNext(c)
Loop While (Not c Is Nothing) And (c.Address <> firstAddress)
Else
MsgBox (Collection & " is NOT Found ")
End If
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Like I mentioned there are couple of problems with the code
Please use Option Explicit. That will ensure that you define your variables
When you define a variable which is meant to store Excel Row number then instead of Integer, use Long
Avoid the use of UsedRange. Get the Actual range which has "Data". Since you are only concerned with Col A, use that to find the last row. We can always use .Offset() to check for Criteria2 and Criteria3
Comment your code with appropriate "comments". I had a tough time understanding it.
Is this what you are trying?
Code: (UNTESTED)
Option Explicit
Sub FilterButton()
Dim SrcSheet As Worksheet, DestSheet As Worksheet
Dim SourceRange As Range
Dim aCell As Range, bCell As Range
Dim iLastRow As Long, zLastRow As Long
Dim Collection As String, System As String, Tag As String
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'~~> Set your sheet
Set DestSheet = Sheets("Test")
Set SrcSheet = Sheets("Imported Data")
'~~> Find Last Row in Col A in the source sheet
With SrcSheet
iLastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
'~~> Find Last "Available Row for Output" in Col A in the destination sheet
With DestSheet
zLastRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
End With
'~~> Set your ranges
Set SourceRange = SrcSheet.Range("A2:A" & iLastRow)
'~~> Search values
Collection = Trim(Range("lblImportCollection").Value)
System = Trim(Range("lblImportSystem").Value)
Tag = Trim(Range("lblImportTag").Value)
With SourceRange
'~~> Match 1st Criteria
Set aCell = .Find(What:=Collection, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'~~> If found
If Not aCell Is Nothing Then
Set bCell = aCell
'~~> Copy A:C. Then match for Crit B and Crit C and remove what is not required
DestSheet.Range("A" & zLastRow & ":" & "C" & zLastRow).Value = _
SrcSheet.Range("A" & aCell.Row & ":" & "C" & aCell.Row).Value
'~~> Match 2nd Criteria
If aCell.Offset(, 1).Value = System Then
'~~> Match 3rd Criteria
If aCell.Offset(, 2).Value <> Tag Then _
DestSheet.Range("C" & zLastRow).ClearContents
Else
DestSheet.Range("B" & zLastRow).ClearContents
End If
'~~> Increase last row by 1 for output
zLastRow = zLastRow + 1
Do
Set aCell = .FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
'~~> Copy A:C. Then match for Crit B and Crit C
DestSheet.Range("A" & zLastRow & ":" & "C" & zLastRow).Value = _
SrcSheet.Range("A" & aCell.Row & ":" & "C" & aCell.Row).Value
'~~> Match 2nd Criteria
If aCell.Offset(, 1).Value = System Then
'~~> Match 3rd Criteria
If aCell.Offset(, 2).Value <> Tag Then _
DestSheet.Range("C" & zLastRow).ClearContents
Else
DestSheet.Range("B" & zLastRow).ClearContents
End If
'~~> Increase last row by 1 for output
zLastRow = zLastRow + 1
Else
Exit Do
End If
Loop
Else
MsgBox Collection & " not Found"
End If
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
FOLLOWUP (From Comments)
Option Explicit
Sub FilterButton()
Dim SrcSheet As Worksheet, DestSheet As Worksheet
Dim SourceRange As Range
Dim aCell As Range, bCell As Range
Dim iLastRow As Long, zLastRow As Long
Dim Collection As String, System As String, Tag As String
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
'~~> Set your sheet
Set DestSheet = Sheets("Test")
Set SrcSheet = Sheets("Imported Data")
'~~> Find Last Row in Col A in the source sheet
With SrcSheet
iLastRow = .Range("A" & .Rows.Count).End(xlUp).Row
End With
'~~> Find Last "Available Row for Output" in Col A in the destination sheet
With DestSheet
zLastRow = .Range("A" & .Rows.Count).End(xlUp).Row + 1
End With
'~~> Set your ranges
Set SourceRange = SrcSheet.Range("A2:A" & iLastRow)
'~~> Search values
Collection = Trim(Range("lblImportCollection").Value)
System = Trim(Range("lblImportSystem").Value)
Tag = Trim(Range("lblImportTag").Value)
With SourceRange
'~~> Match 1st Criteria
Set aCell = .Find(What:=Collection, LookIn:=xlValues, _
LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
'~~> If found
If Not aCell Is Nothing Then
Set bCell = aCell
'~~> Copy A:C. Then match for Crit B and Crit C and remove what is not required
DestSheet.Range("A" & zLastRow & ":" & "C" & zLastRow).Value = _
SrcSheet.Range("A" & aCell.Row & ":" & "C" & aCell.Row).Value
'~~> Match 2nd Criteria
If Len(Trim(System)) = 0 Or _
aCell.Offset(, 1).Value <> System Then _
DestSheet.Range("B" & zLastRow).ClearContents
'~~> Match 3rd Criteria
If Len(Trim(Tag)) = 0 Or _
aCell.Offset(, 2).Value <> Tag Then _
DestSheet.Range("C" & zLastRow).ClearContents
'~~> Increase last row by 1 for output
zLastRow = zLastRow + 1
Do
Set aCell = .FindNext(After:=aCell)
If Not aCell Is Nothing Then
If aCell.Address = bCell.Address Then Exit Do
'~~> Match 2nd Criteria
If Len(Trim(System)) = 0 Or _
aCell.Offset(, 1).Value <> System Then _
DestSheet.Range("B" & zLastRow).ClearContents
'~~> Match 3rd Criteria
If Len(Trim(Tag)) = 0 Or _
aCell.Offset(, 2).Value <> Tag Then _
DestSheet.Range("C" & zLastRow).ClearContents
'~~> Increase last row by 1 for output
zLastRow = zLastRow + 1
Else
Exit Do
End If
Loop
Else
MsgBox Collection & " not Found"
End If
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub

Resources