Refer to different sheet and defined variable in VBA vlookup - excel

This is part of the vba code (modified recorded Macro) I currently have:
Dim strSheet1 As String, strSheet2 As String, lngRow as Long
Sheets(strSheet1).Select
lngRow = Cells(Rows.Count, "A").End(xlUp).Row
Range("J2").Select
ActiveCell.FormulaR1C1 = "=IF(ISNA(VLOOKUP(RC[-1],'SFDB'!R2C15:R[47]C15,1,FALSE)),""No"","""")"
I'm trying to:
change the 'SFDB'! to something like strSheet2!, but running this, excel would ask me to select another excel file (strSheet1 and strSheet2 are both from InputBox)
change R[47] to R[lngRow], but this would lead to an error "Method FormulaR1C1 of Object Range Failed"

You need to take the parameter strSheet1 and lngRow outside the " section.
Change:
"=IF(ISNA(VLOOKUP(RC[-1],'SFDB'!R2C15:R[47]C15,1,FALSE)),""No"","""")"
With:
"=IF(ISNA(VLOOKUP(RC[-1],'" & strSheet1 & " '!R2C15:R[" & lngRow & "]C15,1,FALSE)),""No"","""")"
Also, avoid using Select and ActiveCell, instead use fully qualified Range and Worksheet objects.
Look at slightly modified code below:
Dim strSheet1 As String, strSheet2 As String, lngRow As Long
With Sheets(strSheet1)
lngRow = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range("J2").FormulaR1C1 = "=IF(ISNA(VLOOKUP(RC[-1],'" & strSheet1 & " '!R2C15:R[" & lngRow & "]C15,1,FALSE)),""No"","""")"
End With

try :
rows.count = rows + 1
dim wint = rows
lngRow = Cells(Rows.Count, wint).End(xlUp).Row

Related

Error returned while using Index and Match formula

I am trying to use Index and Match to lookup a value on another worksheet within the same workbook, but I keep getting an error returned. (error 2042) I know I can do this using a formula, (see pic) but I'd like to use code. Does anyone mind taking a look?
Dim WorkOrderDashboardCell As Range
Dim ProjectList As Worksheet
Dim ProjectNumber As String
Set ProjectList = Worksheets("Project List")
ProjectList.Activate
'We need to start by initializing values on the project list
With ProjectList
Dim LastRowProjectListSpreadsheet As Long
LastRowProjectListSpreadsheet = .Range("B" & Rows.Count).End(xlUp).Row
Dim ProjectListNumbers As Range
Set ProjectListNumbers = .Range("B2:B" & LastRowProjectListSpreadsheet)
Dim ProjectListProjectNumber As Integer
ProjectListProjectNumber = 2
End With
'Switch back to the Dashboard spreadsheet
DashBoard.Activate
Dim DashboardWorkOrderRange As Range
Set DashboardWorkOrderRange = DashBoard.Range("E17:E" & LastRowProjectListSpreadsheet)
For Each WorkOrderDashboardCell In Range("E17:E" & Rows.Count).End(xlUp).Row
ProjectNumber = Application.Index(ProjectListNumbers, Application.Match(WorkOrderDashboardCell, DashboardWorkOrderRange, 0))
Debug.Print ProjectNumber
Next
To use worksheet functions, use code like:
WorksheetFunction.Index
rather than:
Application.Index
You might also need to use the Address property of your ranges, like:
ProjectListNumbers.Address
I think this line here is incorrect:
For Each WorkOrderDashboardCell In Range("E17:E" & Rows.Count).End(xlUp).Row
You are trying to loop within a range, but this part of the aforementioned line returns a row number not a range of cells:
Range("E17:E" & Rows.Count).End(xlUp).Row
Change it to a range of cells.
Application.Match
In your code you are using
Set DashboardWorkOrderRange = DashBoard.Range("E17:E" & LastRowProjectListSpreadsheet) where LastRowProjectListSpreadsheet is possibly the wrong last row. Also you are using
For Each WorkOrderDashboardCell In Range("E17:E" & Rows.Count).End(xlUp).Row where Range("E17:E" & Rows.Count).End(xlUp).Row is a row (instead of a range). Finally you are using Application.Filter without testing the result of Application.Match. Some other issues are the unnecessary use of Activate and the use of long variable names the latter seriously affecting the readability of the code.
This is your code revised. When running it you will see that it makes little sense (mentioned in the comments).
I'm posting it for you only to maybe easier find out what you really want to do.
It is illustrating how the result of Application.Match should always be tested with IsNumeric (or IsError) and that you don't have to (in this case, should not) use Application.Index, but just the Cells property of the range object with the index returned by Application.Match, to return the desired value.
The Code
Option Explicit
Sub LittleSense()
Dim wb As Workbook: Set wb = ThisWorkbook ' Workbook containing this code.
Dim LastRow As Long
Dim plRng As Range
With wb.Worksheets("Project List")
LastRow = .Range("B" & .Rows.Count).End(xlUp).Row
Set plRng = .Range("B2:B" & LastRow)
End With
Dim dbRng As Range
With wb.Worksheet("Dashboard")
LastRow = .Range("E" & .Rows.Count).End(xlUp).Row
dbRng = .Range("E17:E" & LastRow)
End With
Dim cel As Range
Dim dbIndex As Variant
Dim plValue As Variant
For Each cel In dbRng.Cells
dbIndex = Application.Match(cel, dbRng, 0)
' You might as well do:
'dbIndex = dbIndex + 1
If IsNumeric(dbIndex) Then ' Not necessary: all values will be found.
plValue = plRng.Cells(dbIndex).Value
Debug.Print plValue & " (" & dbIndex & ")"
Else
' Not necessary: all values will be found.
Debug.Print "Not found " & "(""" & cel.Value & """)"
End If
Next cel
End Sub

Select multiple ranges with VBA

I need to select multiple ranges in a worksheet to run various VBA code on them. The ranges will always begin on row 84 but the end depends on how far down the data goes. I've been selecting these ranges separately using code like this:
Sub SelectRange()
Dim LastRow As Integer
LastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
Range("A84:B" & LastRow).Select
End Sub
That works fine, but I can't figure out how to select multiple ranges at once. I've tried everything I can think of:
Range("A84:B", "D84:E", "H84:J" & LastRow).Select
Range("A84:B,D84:E,H84:J" & LastRow).Select
Range("A84:B & LastRow,D84:E & LastRow,H84:J & LastRow").Select
Nothing works. I get a run-time error when running any of those.
Use UNION:
Dim rng as Range
With ActiveSheet
set rng = Union(.Range("A84:B" & LastRow),.Range("D84:E" & LastRow),.Range("H84:J" & LastRow))
End With
rng.select
But if you intend on doing something with that range then skip the .Select and just do what is wanted, ie rng.copy
Put your dis-continued range address in the first argument of Range object.
For example, Range("A:A,D:D").Select will select column A and column D.
In your case, you may try:
Dim str As String, LastRow As Integer
LastRow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
str = "A84:B" & LastRow & ",D84:E" & LastRow & ",H84:J" & LastRow
Range(str).Select
Range("A84:B & LastRow & "," & "D84:E & LastRow & "," & "H84:J & LastRow").Select

Why am I getting the error "application-defined or object defined error"?

Where is the error application-defined or object defined error coming from? It seems to be coming from the formula that I created. Please help. It really should not be this hard to write code in VBA but for some reason it is not working.
Sub get_levels()
Dim Count As Integer
Dim ticker As Variant
Dim lastRow As Long
Dim lastRowC As Long
Dim rng As Range
Dim current_input_position As Long
Dim sheet As String
Dim mula As String
Dim updatedTicker As String
Application.CutCopyMode = False
Count = 0
sheet = "Test_Sheet"
current_input_position = 2
lastRow = Cells(Rows.Count, "A").End(xlUp).row
Label:
Set rng = Range("A" & current_input_position & ":A" & lastRow)
For Each ticker In rng.Cells
lastRowC = Cells(Rows.Count, "C").End(xlUp).row
updatedTicker = ticker & " A" & " Mtge"
MsgBox updatedTicker
mula = "GCBDC 2018-1A A Mtge"
Range("E2").formula = "=BDS(" & mula & ",""MTGE_CMO_GROUP_LIST"",""Headers=N"")"
Next ticker
End Sub
Assuming your Bloomberg Add-In is functional (try calling BDS manually from a regular worksheet to check), I think you may need to change this line:
Range("E2").formula = "=BDS(" & mula & ",""MTGE_CMO_GROUP_LIST"",""Headers=N"")"
to
Range("E2").Formula = "=BDS(""" & mula & """,""MTGE_CMO_GROUP_LIST"",""Headers=N"")"
If your variable mula has spaces in it (and even if it doesn't), it might need to have " on either side.
(Also, most of your Range and Cells references have no worksheet or workbook specified -- meaning they'll refer to whatever workbook and worksheet happens to be active whilst the code is running. Broadly speaking, you don't want this, but that wasn't your question.)

Excel VBA offset function

I have an Excel file with information in column A and column B. Since these columns could vary in the number of rows I would like to use the function offset so that I could print the formula in one time as an array rather than looping over the formula per cell (the dataset contains almost 1 million datapoints).
My code is actually working the way I want it to be I only can't figure out how to print the code in Range(D1:D5). The outcome is now printed in Range(D1:H1). Anybody familiar how to use this offset within a for statement?
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Set example = Range("A1:A1")
For i = 1 To LastRow
example.Offset(0, i + 2).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
End Sub
Using the Offset(Row, Column), you want to offset with the increment of row (i -1), and 3 columns to the right (from column "A" to column "D")
Try the modified code below:
Set example = Range("A1")
For i = 1 To LastRow
example.Offset(i - 1, 3).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
One way of outputting the formula in one step, without looping, to the entire range, is to use the R1C1 notation:
Edit: Code modified to properly qualify worksheet references
Option Explicit
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
With sht
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
Set example = .Range(.Cells(1, 1), .Cells(LastRow, 1))
End With
example.Offset(columnoffset:=3).FormulaR1C1 = "=sum(rc[-3],rc[-2])"
End Sub
You don't need to use VBA for this. Simply type =sum(A1:B1) in cell D1 and then fill it down.
If you're going to use VBA anyway, use this:
Sub checkOffset()
Dim example As Range
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ThisWorkbook.Worksheets("Sheet1")
LastRow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row
Set example = Range("A1:A1")
For i = 1 To LastRow
example.Offset(i - 1, 3).Formula = "=SUM(A" & i & ":B" & i & ")"
Next i
End Sub
The way offset works is with row offset, column offset. You want the column to always be fixed at 3 to the right.

Object doesn't support this property or method for adding in formula

I have the following code that keeps throwing an error:
Object doesn't support this property or method
expectedProjectWS.Range("A" & lastAddress + 1).Offset(1, 3).Formula "=SUM(D11:(OFFSET(" & newrow & ",-1,0)))"
I am trying to add in a formula after the row is pasted in. I have debug printed this and it works prints correctly which is confusing.
What could be causing this error?
Providing expectedProjectWS is a valid reference to a worksheet, lastAddress is a row number and newrow is a cell reference as a string then you've just forgotten to put the = after the word formula.
This will place the formula =SUM(D11:(OFFSET(D18,-1,0))) in cell D7.
Sub test()
Dim expectedProjectWS As Worksheet
Dim lastAddress As Long
Dim newrow As String
Set expectedProjectWS = ThisWorkbook.Worksheets("Sheet1")
lastAddress = 5
newrow = "D18"
expectedProjectWS.Range("A" & lastAddress + 1).Offset(1, 3).Formula = "=SUM(D11:(OFFSET(" & newrow & ",-1,0)))"
End Sub

Resources