I'm trying to make a macro that seems pretty simple, but it's proven to be harder than I thought. I started making it using the "point and click" method, but it hasn't been as dynamic as I had thought. Basically I'm using vlookup to look up the names in cell A2 from another worksheet, then copy numbers in column D over to the current sheet. When looking at the code, it looks something like this for this part:
Range("D2").Select
ActiveCell.FormulaR1C1 = _
"=VLOOKUP(RC[-3],'Downstairs'!R[-1]C[-3]:R[200]C[14],4,0)"
Range("D2").Select
Selection.AutoFill Destination:=Range("D2:D" & lastrow&)
After I find the first number, I'm trying to autofill the rest. It works when you run it but I think it's just because the names are in order. However, if the names aren't in order it won't find the correct number, partly because all the numbers inside the R[] and C[] keep changing as you go down the rows. I don't think it will work if I add more names to the list, which is something I need for it to do. I changed the number inside the R[] from 93 to 200 because I don't really know how to incorporate the lastrow object I had made before, and I don't know of another way to make this dynamic. Is there a better way to do this?
Like I mentioned in my comment above, you do not need VBA for this. You can directly type the formula in Excel and do a manual Autofill. Having said that if you still want to do VBA then simply use this code where you do not need to use AutoFill. This code will fill all the relevant cells with formulas.
Your formula was also not giving you the right results as your table array was not constant and it was changing as you moved down. To prevent that from happening, simply use $ sign.
Another Tip: R1C1 format is very confusing if you are not good with it. Stick to the normal A1 formatting.
Here is the most simple way to achieve what you want. Please amend the code to suit your needs
Sub Sample()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim lastrow As Long
'~~> Change this to the releavnt sheet name
'~~> This is the sheet where the formula will go
Set ws1 = ThisWorkbook.Sheets("Sheet1")
Set ws2 = ThisWorkbook.Sheets("Downstairs")
With ws1
'~~> Get the last row
lastrow = .Range("A" & .Rows.Count).End(xlUp).Row
'~~> Fill formula in all the relevant cells in one go
'~~> replace my formula within quotes with your formula
'~~> Do not forget to put the $ sign like I have done
.Range("D1:D" & lastrow).Formula = "=VLOOKUP(A1,Downstairs!$C$1:$N$200,4,0)"
End With
End Sub
Related
Looking for a solution to probably a very simple problem but somehow I can not seem to find an answer.
I am looking for a way to copy the first cell of each column. I want to use the copied value to filter it in another workbook. I want to paste the filtered cells below and then repeat the process until all columns have been gone through.
Thus what kind of loop would I use to copy every first cell at a time, store it, then do something with it and then copy the next first cell of a column for all columns?
Could someone please me with this? Your help is much appreciated.
For i = 1 To 207
Columns(i).Select
ActiveCell.Offset(0, 0).Range("A1").Select
Selection.Copy
'How do I store the copied value to use it in an autofilter?
Next i
End Sub
Instead of selecting – and you should avoid using select –
You can set the value to a variable varname = Cells(1,i) for later use,
or better yet, apply directly to your filter.
Dim i As Long
Dim wb2 As Workbook
Set wb2 = Workbooks("Book2") 'the "Other" workbook name here
For i = 1 To wb2.Worksheets.Count 'looping each sheet
wb2.Worksheets(i).Range("A1").AutoFilter Field:=1, Criteria1:= _
ThisWorkbook.Sheets(1).Cells(1, i)
Next i
This is just an example which makes a lot of assumptions that more than likely does not fit with your reality, these has to be changed to fit your scenario, ofc.
But it would go through the specified amount of worksheets in the specified workbook, and filter the first column with the value obtained from the first workbook.
Then, there are quite a few questions on how to copy a filtered range that might give a hint.
I am trying to define a range starting at B2 (constant) to the last cell with data which will change month to month. I want to take the same range length and define another range for column A which will also start at A2 (constant) but will extend only down as far as column B goes. I'm trying to identify them as range and use the dimmed range in a formula in vba but it doesn't like it...any ideas?
Dim Data As range
Dim Time As range
range("b2").Select
'Select Range
Set Data = range("B2", range("B2").End(xlDown))
Set Time("A2", range("A2").End(xlDown))
ActiveCell.Offset(1, 1).Select
ActiveCell.FormulaR1C1 = _
"=FORECAST.ETS([#Timeline],.address(data),.address(time):R[-1]C[-2],1,0)"
You need to close the formula string, add the address, and then continue:
"=FORECAST.ETS([#Timeline],.address(" & data.address & "),.address(" &
time.address & "):R[-1]C[-2],1,0)"
Note since you're using R1C1 style, you might have to do this on both .address parts,
time.address(ReferenceStyle:=xlR1C1)
so:
"=FORECAST.ETS([#Timeline],.address(" & data.address(ReferenceStyle:=xlR1C1) & "),.address(" &
time.address(ReferenceStyle:=xlR1C1) & "):R[-1]C[-2],1,0)"
Edit: Also, I would change the keyword Time, as I think that's a reserved word. Perhaps Dim timeRng as Range?
In addition to #BruceWayne's answer, to address the first part of your question:
If I have a range B2:B50, and I want the corresponding A column, then I can use the Offset function:
Set time = data.Offset(columnOffset:=-1)
Alternatively you can construct the column like this:
Set time = Sheet1.Range("A2").Resize(Rows(data), 1) 'nrows, 1 column
Then you could put A2 anywhere
FWIW:
range("b2").Select is unnecessary and will really slow down your code if you get into this habit (it's just because the macro recorder doesn't know what you want exactly). You could use Range("B2").Offset(1,1).FormulaR1C1 with no selecting
You can name cells in excel and refer to the names: Range("myNamedCell")
Always best practice to prepend the sheet name and fully qualify references (e.g. Sheet1.Range("A1")) since that will always refer to the same cell, whereas Range("A1") refers to A1 on whichever sheet happens to be selected when you run the macro
The macro accesses the last sheet in the workbook (always the same format) and adds a column D, with a header. Until here all is well; the final step is where I get issues.
I want the new column filled with the formula:
=VLOOKUP(C2;'Output'!$A:$B;2;FALSE).
Note that the current sheet is different from where the formula looks (sheet Output).
I have tried various codes that I found here and there... but I cannot manage to make it work correctly right.
Here how my code looks currently:
Sub ColumnInsert()
Dim rws As Long
rws = Cells(Rows.Count, "D").End(xlUp).Row
Sheets(Sheets.Count).Select
Range("D:D").EntireColumn.Insert
Range("D1").Value = "BOX Number"
Range("D2:D" & rws).Formula = "=VLOOKUP(C2;'Output'!$A:$B;2;FALSE)"
End Sub
the last row of code is what does not work... could you please help me?
The problem is in your language settings. If you write your formula in a worksheet you use ";" to separate the variables. In Vba you have to use "," so your formula would be:
"=VLOOKUP(C2,'Output'!$A:$B,2,FALSE)"
I am having an issue with a formula being placed onto my worksheet via vba. The formula interacts with data on a pivot table. When placed in cell Y8 on the worksheet the following formula functions as desired (non vba):
=IF(OR(L8="(blank)",L8=""),IF((K8-$A$2)/(365/12)<0,0,(K8-$A$2)/(365/12)),IF((L8-$A$2)/(365/12)<0,0,(L8-$A$2)/(365/12)))
The idea is to check if L8 is either null or (blank), if it is then use this formula: IF((K8-$A$2)/(365/12)<0,0,(K8-$A$2)/(365/12)). If L8 has a value (will be a date) then I want to use this slightly differnt formula: IF((L8-$A$2)/(365/12)<0,0,(L8-$A$2)/(365/12))).
Columns L and K are in a pivot table.
I used activecell.formulaR1C1 to translate my on sheet formula to R1C1. The only change I made was adding a set of quotation marks around "(blank)" --> ""(blank)"".
I am still getting a run-time 1004 message on my formula line of vba.
My VBA Code is here:
Sub PerformFormulas()
Dim LastRow As Long
LastRow = Worksheets("Calculator").Range("C" & Rows.Count).End(xlUp).Row
Worksheets("Calculator").Range("Y8:Y" & LastRow - 1).FormulaR1C1 = "=IF(OR(RC[-13]=""(blank)"",RC[-13]=""),IF((RC[-14]-R2C1)/(365/12)<0,0,(RC[-14]-R2C1)/(365/12)),IF((RC[-13]-R2C1)/(365/12)<0,0,(RC[-13]-R2C1)/(365/12)))"
End Sub
I checked that LastRow and Calculator are being recognized correctly and they are (I changed to a simple .select formula and that portion of the code works alright).
Thanks in advance for any help!
You didn't escape the other pair of quotes:
"=IF(OR(RC[-13]=""(blank)"",RC[-13]=""), ...
should be
"=IF(OR(RC[-13]=""(blank)"",RC[-13]=""""), ...
I want to know how exactly to incorporate a VLOOKUP function into my Excel worksheet via VBA; I am completely comfortable with the VLOOKUP function when entering it directly into a cell, but I am completely new to VBA.
A little info:
I have ~5500 rows of data;
I have a number of named ranges (such as catNo, catNoRange, to name but two);
I want to use VBA to check catNo against catNoRange and return the value of the sixth (6th) column in catNoRange;
I also want to know how - and where - to display the result once I have it; ideally I would like it to appear in cell J4 (and the corresponding cells down to J5500).
How can I achieve this?
Additional Info:
For those of you wondering why I don't just use a regular VLOOKUP to achieve this: I want to use VBA because I have written a script which checks to see if certain cells are empty, and if at least one of them is populated, then the VLOOKUP will execute, taking the value of the populated cell for the main search critera.
Code Update:
Following some advice, I have opted to attempt to use the Find function instead of VLOOKUP. It doesn't work; here is what I have:
Sub findCode()
Result = WorksheetFunction.Find("ABI0010P", "5012616173004", "33787")
Range("J4").Value
End Sub
For the find function you want to have something like this
Dim ws As Worksheet
Set ws = Worksheets(2)
Rowz = ws.Cells(rows.Count, 1).End(xlUp).Row
k = 2
searchvalue= ws.Cells(k, 2)
Set SEARCHRANGE= ws.Range("A2:A" & Rowz)
Set Findx = SEARCHRANGE.find(searchvalue, LookIn:=xlValues)
If Not Findx Is Nothing Then ws.Cells(k, 4) = "what ever you want"