Trying to copy a formula down an entire column to the last row of data in an adjacent column - vba

I am a new VBA user, and I am trying to create a VBA code to copy a single Vlookup formula down an entire column to the last row of data in an adjacent column. I don't want to specify a specific range, because I intend to use this macro with multiple different files that have different row ranges, so I am looking for a code that will simply copy down to the last value in an adjacent column.
I have tried looking at other similar questions and answers on this website, but none of the solutions that I have found have been working, and I would really appreciate some help!
Here is my code that I currently have:
' Section5 Macro
ActiveCell.FormulaR1C1 = _
"=VLOOKUP(RC[6],'[PERSONAL.XLSB]Task and Sections'!R2C1:R254C2,2,FALSE)"
Range("C2").Select
Selection.Copy 'Copy Vlookup Formula
Dim lastRow As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
Range("C3").AutoFill destination:=Range("C3:C" & lastRow) 'Specify range for Column C based off of row count in Column B
Application.CutCopyMode = False
Selection.Copy
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=False 'Paste Vlookup equation down the column
End Sub
The formula I want to copy is "=VLOOKUP(RC[6],'[PERSONAL.XLSB]Task and Sections'!R2C1:R254C2,2,FALSE". The column that I want to copy this formula down is column C (in all rows except C1 which is the Header). The column that I want to refer to for row length is the adjacent column B.
Currently I am getting an error that says "Compile error: Named argument not found".
Any help would be greatly appreciated!
Thank you,

As pointed in the comment, you had a simple typo ("desination")... Nevertheless, your code doesn't seem to work even when this is fixed.
There's a much simpler approach. Try this:
Sub FillWithFormula()
Dim lastRow As Long
lastRow = Range("B" & Rows.Count).End(xlUp).Row
Range("C2:C" & lastRow).FormulaLocal = "=B2*2"
End Sub
Notice that I replaced your formula with a simpler one (independent of external data) so I could verify that the routine works.

Here.
Sub thing()
Dim lastRow As Long
lastRow = Cells(Rows.Count, 2).End(xlUp).Row
Range("C3:C" & lastRow).FormulaR1C1 = "=VLOOKUP(RC[6],'[PERSONAL.XLSB]Task and Sections'!R2C1:R254C2,2,FALSE)"
Range("C3:C" & lastRow).Value = Range("C3:C" & lastRow).Value
End Sub
Simpler, more elegant. Hasn't this kind of thing been solved like a million times all around the internet? Anyway, copy-paste is the slowest thing you can do in a macro. Avoid it. Just set the values of a range to be the values of the range. :)
Also, you can assign a formula to a whole range.

Related

Loop through first row of each named range in one code block

So I've had to write two almost identical code blocks to loop through my two named ranges. However, I know that the named ranges will always be the same size and shape as each other and even start in the same column (different rows) and they also need to be pasted into two columns next to each other so I feel like this should be possible in one code block but can't even think how to start attacking it. E.g. Cash Payments Monthly is in array A10:D20 and P&L Payments Monthly is in array A40:D50.
Anyone got any ideas, please and thank you?
For Each Row In Range(Names("Cash_Payments_Monthly")).Rows
LastRow = wsDashData.Cells(Rows.Count, 14).End(xlUp).Row
Row.Copy
wsDashData.Range("n" & LastRow + 1).PasteSpecial _
Paste:=xlPasteValues, _
Transpose:=True
Next Row
For Each Row In Range(Names("PL_Payments_Monthly")).Rows
LastRow = wsDashData.Cells(Rows.Count, 15).End(xlUp).Row
Row.Copy
wsDashData.Range("o" & LastRow + 1).PasteSpecial _
Paste:=xlPasteValues, _
Transpose:=True
Next Row
Assuming you have other named ranges in your workbook, you should start by creating a whitelist array of named ranges that you WOULD like to search, then iterate through that array, embedding a single copy of your existing code in that loop...
Dim myranges()
Dim c As Integer 'counter
myranges = Array("Cash_Payments_Monthly", "PL_Payments_Monthly")
For c = 0 To UBound(myranges)
For Each Row In Range(myranges(c)).Rows
...the rest of your code, but just one instance of it :-) ...
Next c

Copying several filtered columns' worth of non blank cells to second sheet

I have a table that I need to autofilter itself according to criteria in column "AS", then copy multiple discrete columns' worth of resulting non-blank cells to specific cells in the next sheet.
What is the most efficient way of doing this? I'm aware that I may have to copy/paste specialvalues instead of direct reference
I'm not entirely sure what you're asking. But, imagine Column A is filled with names of fruits and Column B is filled with numbers. The following code filters Column A with the criteria "Apples" and copies the corresponding numbers to a new worksheet. This might start you off on the right track.
Sub selectApples()
' Find last row in column A
Dim LastRow As Integer
LastRow = Cells(Rows.Count, 1).End(xlUp).Row
' Select data in column A and filter
Range("A1:A" & LastRow).Select
Selection.AutoFilter Field:=1, Criteria1:="Apples"
'Find new last row
Dim newLastRow As Integer
newLastRow = Cells(Rows.Count, 1).End(xlUp).Row
'Copy and paste special into new worksheet
Range("B2:B" & newLastRow).Select
Selection.Copy
Sheets.Add After:=ActiveSheet
Selection.PasteSpecial Paste:=xlPasteValues
End Sub

ClearContents for constants but not formulas

I've got a range (N1:N12) on a sheet1 and I've got a code that copy and paste me the values of that range on a secondary sheet2. Everything is working, anyway i didn't consider that i want another button that clear only values in range N1:N12 once i have copied them in sheet2. I don't know how to keep formulas on that range when i want to delete values. Do you have an idea ? I've already tried a normal macro that deletes everything but it is not what i want.
Sub Cancella()
Sheets("Foglio1").select
Range("N1:N12").clearcontents
End Sub
The code i use for copying
Dim lastRow As Long
Sheets("Training Analysis").Range("P1:R13").Copy
lastRow = Sheets("Foglio1").Range("a65536").End(xlUp).Row
Sheets("Foglio1").Range("A" & lastRow + 1).PasteSpecial Paste:=xlPasteValues, Transpose:=True
Replace:
Range("N1:N12").clearcontents
with:
For i = 1 To 12
If Not Cells(i, "N").HasFormula Then Cells(i, "N").ClearContents
Next i
There is a subset of the Range.SpecialCells method that targets xlCellTypeConstants. This can be further broken down to xlNumbers, xlTextValues, xlErrors , xlLogical or a combination of same.
With WorkSheets("Foglio1")
.Range("N1:N12").SpecialCells(xlCellTypeConstants, xlNumbers).ClearContents
End With
Conversely, cells containing formulas can be similarly targeted with the xlCellTypeFormulas subset.

VBA query: using clipboard data to filter

I'm using multiple worksheets in Excel to create a database of candidates undergoing some technical training. Each time a candidate is added to the 'database' they are assigned a unique number, for example "2015-0001". When they call to pay their deposit, I'm using a data input table for the telephone operator to note down the details, and it looks up the unique number for the candidate. I then want to filter the main database for the candidate by their number and paste in the confirmed details of the deposit.
My query is this: how do I write the code that copies the candidate number data from the cell on worksheet 1 and then uses that data (irrespective of its value) to filter worksheet 2?
I'm new to macros and have been using "record macro" to generate code which I then edit and learn as I go. So, apologies if this looks extremely clunky. Using record, the filter command simply takes the example text I'm using (in this case 2015-0011), not replacing it with the revised value when the Deposit input table is changed and the macro is run. Am I right to think that I need to use a String?
Thanks in advance. RLC
Sub Confirm_Deposit()
'
' Confirm_Deposit Macro
'
'
Sheets("Take Deposit").Select
Range("C5").Select
Selection.Copy
Sheets("CIP Candidates").Select
ActiveSheet.Range("$A$6:$AK$2507").AutoFilter Field:=1, Criteria1:= _
"2015-0011" <---------------- ISSUE
Sheets("Take Deposit").Select
Range("C6:C8").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("CIP Candidates").Select
Range("A6").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Offset(0, 20).Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
Application.Run _
"'CIP Spreadsheet RLC (with Macros).xlsm'!ThisWorkbook.Clear_Filters"
etc.
This is a different approach that is less "Macro" based and more just simple cell manipulation using loops. It's very flexible. See what you think of the idea, then we can modify to your specific needs.
The part of this code that I would change immediately is selecting where the lookup value comes from. In this example, since I don't know your specifics, I saw you are using "C5" in the example above.
Sub Confirm_Deposit()
Dim source As String
Dim target As String
Dim lookupVal As String
Dim row As Long
Dim searchRow As Long
source = "Take Deposit" 'In case you have similar projects, you can just replace these lines.
target = "CIP Candidates"
lastSourceRow = Sheets(source).Range("A" & Rows.Count).End(xlUp).row
lastTargetRow = Sheets(target).Range("A" & Rows.Count).End(xlUp).row
lastTargetCol = Sheets(target).Cells(1, Columns.Count).End(xlToLeft).Column
lookupVal = TextBox1.Text 'Set the lookupVal from whatever source you choose. I like ComboBoxes when I can.
For searchRow = 2 To lastSourceRow
If Sheets(source).Cells(searchRow, 3).Text = lookupVal Then 'Searching through Source Sheet on Col "C"
Exit For
End If
Next searchRow
'This way, at the end of the search, you have the row number of the original source to be copied, instead of hard coding.
For row = 6 To lastTargetRow 'Loop through the Target Sheet
If Sheets(target).Cells(row, 3).Text = lookupVal Then 'Compare lookupVal to the Range being looped.
For col = 2 To lastTargetCol
Sheets(target).Cells(row, 3) = Sheets(source).Cells(searchRow, col) 'Copies contents from Row 5 of source sheet.
Next col
End If
Next row
End Sub
EDIT: Made lookup Row dynamic instead of hard coded to row 5
Been a while but will this do the trick?
ActiveSheet.Range("$A$6:$AK$2507").AutoFilter Field:=1, Criteria1:= _
Sheets("Take Deposit").Cells(5,3).Value
or
ActiveSheet.Range("$A$6:$AK$2507").AutoFilter Field:=1, Criteria1:= _
Sheets("Take Deposit").Range("C5").Value
theres no need to select and copy the value. You can just reference the Cells Value.

How to use formular1c1 without defining the range in vba excel?

My code is:
Range("M1").Select
ActiveCell.FormulaR1c1 = "SUM(R[2]C:R[4157]C)"
My problem is what if I have more than 4157 rows. How do I ensure all rows for that column will be added up?
Thanks!
Try with:
Range("M1").Select
ActiveCell.FormulaR1c1 = "=SUM(R[2]C:R[" & ActiveSheet.UsedRange.Rows.Count & "]C)"
EDIT:
Added the = to the formula, so that Excel understands it is a formula. Otherwise it would just put the text in the cell.
As per Jaycal's comment try this:
dim rowNum as integer
Range("M1").Select
rowNum=activesheet.cells(rows.Count,activecell.Column).end(xlUp).row
ActiveCell.FormulaR1c1 = "=SUM(R[2]C:R[" & rowNum & "]C)"
where using the cells notation means we can refer to row then column, row is taken as the max rows in worksheet, column is the active cell - which makes this a bit more reusable than referrring to range("M" & rows.count) given you've selected the cell anyway.