I'm an IT noob and have been tasked with creating an Excel macro that will cross-reference an employee number from one sheet to another. After finding a matching employee number it needs to copy the info from that employee (Name,etc) and finally take it to the result page and paste the info.
This is my first time making a VBA macro, or programming in general so bear with me.
Sub Macro2()
'
' Macro2 Macro
' 1st attempt
'
Dim DataObj As New MSForms.DataObject
Dim S As String
DataObj.GetFromClipboard
S = DataObj.GetText
For x = 1 To 10
Sheets("ad").Select
Cells(11 + x, 7).Select
Selection.Copy
Sheets("sp").Select
Cells.Find(What:=S, After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ActiveCell.Offset(0, -1).Range("Table_GetJobs4[#Headers]").Select
ActiveCell.Offset(0, 1).Range("Table_GetJobs4[[#Headers],[Company_Code]]"). _
Activate
Application.CutCopyMode = False
Selection.Copy
Sheets("adtospresult").Select
ActiveCell.Offset(0, -2).Range("A1").Select
Cells.Find(What:="33620", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
False, SearchFormat:=False).Activate
ActiveCell.Offset(0 + x, -9).Range("A1").Select
ActiveSheet.Paste
ActiveCell.Offset(0, 2).Range("A1").Select
Next x
End Sub
Quite simply, I haven't been able to get the clipboard to find function to work. Any help/directions would be much appreciated, thanks.
Instead of trying to pass the clipboard information to s you could just pass the value of the range to S like this:
s = Cells(11 + x, 7).Value
and when you copy it to the other worksheet reverse it.
some_range = s
Also you don't need to select any worksheets or cells this would be completely valid:
Sheets("sp").found_range = Sheets("ad").Cells(11 + x, 7).Value
Found range would be the range in the other sheet that you want to paste the first sheet's value.
FYI, http://www.techrepublic.com/blog/software-engineer/train-users-to-follow-best-practices-when-writing-vba-code/ This would be helpful to read over to learn best practices for writing code. It'll save you in the future when you have to go back and try to decipher what you were doing in you code later down the road.
Related
VBA noob. Script to search input data, match criteria, go into existing spreadsheet, copy to latest row, and then go back to original input workbook to repeat.
I can get everything working with absolute paths (ie "Book1.csv") but I will have to replace these every time I run the macro with a new input data workbook. Pretty sure I have the dim/set part figured out but every time I call the Windows().Activate I always get subscript out of range. Code:
Dim wb1 As Workbook
Set wb1 = ThisWorkbook
' Search Title column (B) for match
Cells.Find(What:="A154L-T031-#1590", After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
' Select date and copy
ActiveCell.Offset(0, 1).Range("A1:Q1").Copy
' Activate and select correct sheet in NCRP spreadsheet and then select row after latest data
Windows("Approach_North.xlsx").Activate
Worksheets("T031").Activate
Range("T1048576").End(xlUp).Select
' Select row below it and paste
ActiveCell.Offset(1, 0).Range("A1").Select
ActiveSheet.Paste
' To repeat have to go back to the original data sheet
Windows(wb1).Activate
ActiveCell.Select
Selection.Font.Bold = True
The debugger lands on Windows(wb1).Activate.
Any help what doing wrong?
No need for select/activate:
Dim f As Range
Set f = Cells.Find(What:="A154L-T031-#1590", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
If Not f Is Nothing Then
f.Copy Workbooks("Approach_North.xlsx").Worksheets("T031").Cells(Rows.Count, "T").End(xlUp).Offset(1, 0)
f.Bold = True
End If
New to forum and vba but want to learn more.
Got two tables of large data and want to look for a cell value equal to the cell value to the left of my active cell in table 1 and then find that value in the 2nd table. When value is found I want to return the cell value found in the 5th column to the right of column A in the 2nd table.
The macro I have created works well - if it hadn't been that it always looks for the same value "10.136.32.10" i.e. this value does not change as the active cell moves down table 1. I would like the value to change depending on what is actually copied from the cell to the left. Is there a way to do this? I use Ctrl+f function and then paste in the cell value copied from table 1
Have the following macro:
Sub Makro2()
'
' Makro2 Makro
'
'
ActiveCell.Offset(0, -1).Range("A1").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("SKF-NOV-6-2017").Select
Cells.Find(What:="10.136.32.10", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Selection.End(xlToLeft).Select
ActiveCell.Offset(0, 4).Range("A1").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("All Equipment").Select
ActiveCell.Offset(0, 1).Range("A1").Select
ActiveSheet.Paste
ActiveCell.Offset(1, 0).Range("A1").Select
End Sub
Here is the code by which you can do your job. This macro searches immediately on all rows. If you only need to search for an active cell, then you need to remove the loop.
Sub macro2()
Dim lr As Long, r As Long, c As Long
Dim str As String
lr = Cells(Rows.Count, 1).End(xlUp).Row
For r = 1 To lr
str = Cells(r, c).Offset(0, -1)
Sheets("SKF-NOV-6-2017").Select
Cells.Find(What:=str, After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
Selection.End(xlToLeft).Select
ActiveCell.Offset(0, 4).Select
Application.CutCopyMode = False
Selection.Copy
Sheets("All Equipment").Select
Cells(r, c + 1).past
Next r
End Sub
Want to write a Macro that would search for a particular word in a range of cells (or after a cell), let's say "hello" in our case. Suppose my spreadsheet looks like this:
Hello user
Hello Nancy
Hello count 2
The content of the spread sheet change daily, so that I may have different number of 'Hello's everyday. I want to copy the number (2) beside the last 'Hello' to another cell. If the word count of hello doesn't exits, it will put 0 in that cell(Note that even if the word count is 0, there might still be 'hello' in this spread sheet). The location of the last Hello will always be after Cell A17.
I was thinking about setting the parameter After to cell A17, and change SearchOrder to xlByColumns, but When the search reaches the end of the search range, it wraps around to the beginning of the range.
How should I stop the search when this wraparound occurs?
I also try to use the Find method within With to search within range A17 to B22:
With Sheets("Data").Range("A17:B22")
Set hello = Cells.Find(What:="hello", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False)
End With
If Not hello Is Nothing Then
With Sheets("Data").Range("A17:B22")
Cells.Find(What:="Hello", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Offset(0, 1).Range("A1").Select
Application.CutCopyMode = False
Selection.Copy
Range("B17").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False
End With
Else
Range("B17").Select
ActiveCell.FormulaR1C1 = "0"
End If
But it will still locate the search to the first 'Hello' in the spreadsheet.
Try This:
Function GetLastNumber(TheRange As Range, TheWord As String) As Variant
Dim Finder
'You can add LookAt:=xlWhole if you want entire word only
Set Finder = TheRange.Find(TheWord, SearchDirection:=xlPrevious)
If Finder Is Nothing Then
GetLastNumber = CVErr(xlErrNA)
Else
'Return the value of the cell one column to the right of our search word
GetLastNumber = Finder.Offset(0, 1).Value
End If
End Function
You can use it like this:
Sub Test()
Range("D1") = GetLastNumber(Range("A1:A11"), "Hello")
End Sub
You can also use it as a formula:
=GetLastNumber(A1:A11,"Hello")
Results:
I am trying to create a VBA macro for post processing data, and it currently has a "Raw Data" sheet for the first sheet, and my post processing tools on the second sheet. What I have so far is a button that will search the data and create plots for the desired variables, but it pulls data for all of the test points. What I want to do is to be able to filter by test point from the data review sheet. What would be ideal would be to have an autofilter type dropdown menu on my post processing sheet where the test point can be selected, and the data on the previous sheet would be filtered.
Here's the search function I've been using:
Dim TestPt As Long
Dim rows As Long
rows = Sheets(1).UsedRange.rows.Count
'
Sheets(1).Select
Cells.Find(What:="TargetTestPointNumber", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate
TestPt = ActiveCell.Column
Any help would be appreciated!
I'm not 100% sure what you needed exactly. But this code does a comparison between the value you want and the data sheet. If its = it will copy it to Row D so if you have stuff there you will need to change it. Also it assumes the data is in row 1.
Dim i As Long, lastRowD As Long, lastRowA As Long
With Sheets("datasheetname")
lastRowA = .Range("A" & .Rows.count).End(xlUp).Row
For i = 1 To lastRowA
lastRowD = .Range("D" & .Rows.count).End(xlUp).Row
If .Cells(i, 1).Value = "testvalue" Then
.Cells(lastRowD, 4).Value = "testvalue"
End If
Next i
.Range("D1", "D" & lastRowD).Select
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlXYScatter
ActiveChart.SetSourceData Source:=Range("'datasheetname'!$D$1:$D" & lastRowD)
End With
note youll need to change test value and datasheetnames. As well as any of the column info. I tried it and it works. I just have no idea if this is what you need. If you need to copy more than 1 row, you would change in the if how many to do.
.cells(lastRowD,5).value= .cells(i,2).value etc
Sorry for the messy code, but I found this to work for me. Basically I copied the unique test point value to the other sheet, linked them to a ComboBox, and linked a macro to run with the ComboBox to autofilter the data on the other sheet. I'm sure there has to be a better way, but it works for me.
Sub ValueSelectionData()
'
Dim TestPt As Long
Dim rows As Long
Dim Value As Long 'used to select test point
rows = Sheets(1).UsedRange.rows.Count 'Row count on data sheet
Value = Sheets(2).Cells(2, 6).Value 'value linked to ComboBox selection
'
Sheets(2).Columns("A:A").ClearContents
Sheets(1).Select
Cells.Find(What:="TargetTestPointNumber", After:=ActiveCell, LookIn:=xlFormulas, LookAt:= _
xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False _
, SearchFormat:=False).Activate 'searches for test point column in data
TestPt = ActiveCell.Column
Range(Sheets(1).Cells(2, TestPt), Sheets(1).Cells(rows, TestPt)).AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range(Sheets(2).Cells(1, 1), Sheets(2).Cells(1, 1)), Unique:=True
If Value > 0 Then
Sheets(1).Select
Cells.Find(What:="TargetTestPointNumber", After:=ActiveCell, LookIn:=xlFormulas, LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:=False, SearchFormat:=False).Activate
TestPt = ActiveCell.Column
Value = Sheets(2).Cells(2, 6).Value 'desired test point to filter for
Sheets(1).Range(Sheets(1).Cells(1, TestPt), Sheets(1).Cells(rows, TestPt)).AutoFilter Field:=1, Criteria1:=Value 'autofilters data for desired test point
Else
'Clear all auto filters
If Sheets(1).AutoFilterMode Then
Sheets(1).ShowAllData
End If
End If
End Sub
I want a macro that will copy all rows in one sheet that have a certain name in them to a separate sheet.
My plan is to do it as a loop that stops when it can not find any more of the name. The problem is I can't figure out how to make the loop stop when the search fails when it has found all the occurrences.
Here is my code that loops 10 times. It works just fine except that I want to fix it so that it loops however many it takes and then stops. This could be anywhere from 0 times to 500 times.
By the way, the values I search for are in 3 different columns side by side.
I would really like to change the code as little as possible as I don't know VBA well and would like to avoid doing a lot of learning that I will be unlikely to use again.
Dim Counter As Integer
Range("A1").Select
' Start the loop that I want changed to stop automatically:
Do While Counter < 10
Cells.Find(What:="matt johnson", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
' go to destination sheet:
Sheets("Matt").Select
ActiveCell.SpecialCells(xlLastCell).Select
ActiveCell.Offset(1, 2).Range("A1").Select
Selection.End(xlToLeft).Select
ActiveSheet.Paste
' go back to source sheet:
ActiveCell.Offset(1, 0).Range("A1").Select
Sheets("Upcoming Deadlines").Select
ActiveCell.Offset(0, 1).Range("A1").Select
Selection.End(xlToRight).Select
ActiveCell.Offset(0, 26).Range("A1").Select
Application.CutCopyMode = False
Counter = Counter + 1
Loop
End Sub
I think this will solve your problem with minimal changes:
Sub test()
Dim Counter As Integer
Range("A1").Select
' Start the loop that I want changed to stop automatically:
Do Until Cells.Find(What:="matt johnson", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False) Is Nothing
Cells.Find(What:="matt johnson", After:=ActiveCell, LookIn:=xlFormulas, _
LookAt:=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
MatchCase:=False, SearchFormat:=False).Activate
ActiveCell.Rows("1:1").EntireRow.Select
Selection.Copy
' go to destination sheet:
Sheets("Matt").Select
ActiveCell.SpecialCells(xlLastCell).Select
ActiveCell.Offset(1, 2).Range("A1").Select
Selection.End(xlToLeft).Select
ActiveSheet.Paste
' go back to source sheet:
ActiveCell.Offset(1, 0).Range("A1").Select
Sheets("Upcoming Deadlines").Select
ActiveCell.Offset(0, 1).Range("A1").Select
Selection.End(xlToRight).Select
ActiveCell.Offset(0, 26).Range("A1").Select
Application.CutCopyMode = False
Counter = Counter + 1
Loop
End Sub
Explanation
This will continue to loop until the search finds nothing.