Creating an IFERROR using INDEX/MATCH formula in VBA Code - excel

I have a VBA tool I'm trying to update by inputting an IFERROR formula into column B on Sheet2 using INDEX/MATCH to pull the data from column F in Sheet 1. The matching criteria is looking at column D in the active row of Sheet 2 and matching it to Column J in Sheet 1.
The resulting formula should look like this
=IFERROR(INDEX(Sheet1!$F:$F,MATCH('Sheet2'!$D2,Sheet1!$J:$J,0)),"")
This is the code I wrote but I'm getting the "Unable to set formulaaray property of the range class" error.
Range("B2").FormulaArray = "=IFERROR(INDEX(Sheet1,C6,MATCH(RC2,Sheet1,RC10,0)),"""")"
I'm still rather new to VBA and in my research I haven't found anything to help. Appreciate any help anyone can give me in solving this error.
I'm trying to adapt/change the current formula coded in the tool to the above. This code was working it's just the user has made some changes to the file and now wants to grab the data as described in my original post.
Range("B2").FormulaArray = "=IFERROR(INDEX(C6,MATCH(RC1&R1C2,C1&C5,0)),"""")": Range("B2:B" & LastRow).FillDown
Range("B:b").EntireColumn.Select
Selection.Copy
Selection.PasteSpecial xlPasteValues

A VBA Lookup (INDEX/MATCH formula)
Adjust the values in the constants section.
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Returns the results of an 'INDEX/MATCH' formula as values.
' Formula: '=IFERROR(INDEX(Sheet1!$F:$F,MATCH(D2,Sheet1!$J:$J,0)),"")'
' Remarks: 'VLOOKUP' doesn't work because 'F' is to the left of 'J':
' wrong '=VLOOKUP(D2,Sheet1!$J:$F,-5,0)' wrong.
' Calls: 'RefColumn'.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub VBALookupFormula()
' Source
Const sName As String = "Sheet1"
Const slCol As String = "J" ' 2. lookup (compare (match))
Const svCol As String = "F" ' 3. value (return)
Const sfRow As Long = 2
' Destination
Const dName As String = "Sheet2"
Const dlCol As String = "D" ' 1. lookup (read)
Const dvCol As String = "B" ' 4. value (write)
Const dfRow As Long = 2
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim slrg As Range: Set slrg = RefColumn(sws.Cells(sfRow, slCol))
If slrg Is Nothing Then Exit Sub ' no data
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Dim dlrg As Range: Set dlrg = RefColumn(dws.Cells(dfRow, dlCol))
If dlrg Is Nothing Then Exit Sub ' no data
Dim slAddress As String: slAddress = slrg.Address
Dim svAddress As String: svAddress = slrg.EntireRow.Columns(svCol).Address
Dim dlAddress As String: dlAddress = dlrg.Cells(1).Address(0, 0)
Dim dvrg As Range: Set dvrg = dlrg.EntireRow.Columns(dvCol)
Dim dFormula As String
' Note the 4 single quotes (necessary when a worksheet name contains spaces)
' and the 4 consecutive double quotes (basically one double quote
' in the formula is two double quotes in VBA).
dFormula = "=IFERROR(INDEX('" _
& sName & "'!" & svAddress & ",MATCH(" & dlAddress & ",'" _
& sName & "'!" & slAddress & ",0)),"""")"
dvrg.Formula = dFormula
dvrg.Value = dvrg.Value
MsgBox "The lookup finished successfully.", vbInformation
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Creates a reference to the one-column range from the first cell
' of a range ('FirstCell') to the bottom-most non-empty cell
' of the first cell's worksheet column.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function RefColumn( _
ByVal FirstCell As Range) _
As Range
If FirstCell Is Nothing Then Exit Function
With FirstCell.Cells(1)
Dim lCell As Range
Set lCell = .Resize(.Worksheet.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If lCell Is Nothing Then Exit Function
Set RefColumn = .Resize(lCell.Row - .Row + 1)
End With
End Function

Related

VBA cannot AutoFilter a Range for a certain criteria

I am trying to make a Range object of all entrys and than apply a filter, which searches for a number in there.
I want the Range to hold only the matching entrys afterwards, but I always get the error 1004...
Here the code:
Dim rSearch As Range
Dim rResult As Range
Set rSearch = wbMe.Sheets(iCurSheet).Range("F2:F1000")
rSearch.AutoFilter Field:=iColKey, Criteria1:="=" & wbMe.Sheets(iCurSheet).Cells(iLine, iColKey).Value
The last line throws the exception. I found out that the AutoFilter has to be applied to the first line, so .Range("A1:K1"), but I still don't get why I am not able to Filter on a Range, maybe i get the Object wrong?
Thanks in advance!
Edit:
So I tried some stuff:
Set rSearch = wbMe.Sheets(iCurSheet).Range("A2:K1000")
rSearch.AutoFilter Field:=11, Criteria1:="=" & wbMe.Sheets(iCurSheet).Cells(iLine, iColKey).Value
MsgBox "Count Rows rSearch:" & rSearch.Rows.Count
I expected the MsgBox to say smth less, but I get 999, so it hasn't filtered anything.
My guess that I was filtering the wrong column, but I wanna filter on Col K (I need Col F afterwards to search once more, sry for mixing stuff up).
Now I don't get the AutoFilter exception anymore. But for some reason my rSearch range does not shrink.
How do I shrink my Range?
Count Visible Data Cells (Criteria Cells)
A quick fix could be something like
MsgBox "Count Rows rSearch:" & rSearch.Columns(11).SpecialCells(xlCellTypeVisible).Cells.Count - 1
Note that the headers need to be included in the range for AutoFilter to work correctly.
Using SpecialCells
Sub CountVisibleDataCells()
' Define constants.
Const CriteriaIndex As Long = 11
' Reference the workbook ('wb').
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the worksheet ('ws').
Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
' Turn off AutoFilter.
If ws.AutoFilterMode Then ws.AutoFilterMode = False
' Reference the range ('rg').
Dim rg As Range: Set rg = ws.Range("A1:K21")
' Store the criteria value from the cell, converted to a string ('CStr'),
' in a string variable ('Criteria'). AutoFilter 'prefers' this.
Dim Criteria As String: Criteria = CStr(ws.Range("M1").Value)
' Filter the range.
rg.AutoFilter Field:=CriteriaIndex, Criteria1:=Criteria
' Reference the visible cells in the criteria column ('vrg').
Dim vrg As Range
Set vrg = rg.Columns(CriteriaIndex).SpecialCells(xlCellTypeVisible)
' Turn off the worksheet auto filter.
ws.AutoFilterMode = False
' Store the number of visible cells of the criteria column
' in a long variable (subtract 1 to not count the header).
Dim CriteriaCount As Long: CriteriaCount = vrg.Cells.Count - 1
' Inform.
MsgBox "Count of '" & Criteria & "': " & CriteriaCount
End Sub
Using Application Count
Sub CountCriteriaCells()
' Define constants.
Const CriteriaIndex As Long = 11
' Reference the workbook ('wb').
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the worksheet ('ws').
Dim ws As Worksheet: Set ws = wb.Worksheets("Sheet1")
' Turn off AutoFilter.
If ws.AutoFilterMode Then ws.AutoFilterMode = False
' Reference the range ('rg').
Dim rg As Range: Set rg = ws.Range("A1:K21")
' Store the criteria value from the cell, converted to a string ('CStr'),
' in a string variable ('Criteria').
Dim Criteria As String: Criteria = CStr(ws.Range("M1").Value)
' You may need to modify this because 'CountIf' works differently.
' Reference the criteria data range ('cdrg') (no headers).
Dim cdrg As Range
With rg.Columns(CriteriaIndex)
Set cdrg = .Resize(.Rows.Count - 1).Offset(1)
End With
' Store the number of cells containing the criteria ('CriteriaCount')
' in a long variable.
Dim CriteriaCount As Long
CriteriaCount = Application.CountIf(cdrg, Criteria)
' Inform.
MsgBox "Count of '" & Criteria & "': " & CriteriaCount
End Sub

Is it possible to fill cells in a range with "x" if the number of filled cells in that column can't be divided by 4 using VBA?

In a sheet of my workbook I have range C8:C104 filled with values from another sheet of my workbook. These number of values can vary from 2 to 96 with no blank cells in between.
Before copying these values to a txt-file I need to auto fill blank cells in this column until the number of non blank cells in the range can be divided by 4.
Example:
C8:C12 contain data => no cells need to be auto filled
C8:C10 contain data => Cells C11 and C12 need to be filled with the text "x" (the rest of the cells in the range stay blank)
Normally Google is my best friend in situations like this, but unfortunately I could not find any Q&A similar to this. I got the part running to copy the cells and sending them as a txt.file by outlook mail, but have no clue how to get the auto fill part up and running yet.
Is there anyone who can help me get started, am not very experienced and a bit rusty with my VBA skills?
The following will pad the cells with x until there are a multiple of 4 cells populated:
Sub pad_to_mod_4()
Dim myrange As Range
Dim ws As Worksheet
padding = "x"
Set ws = ActiveSheet 'set this to your worksheet
Set myrange = ws.Range("C8:C104")
Do Until myrange.Cells.SpecialCells(xlCellTypeConstants).Count Mod 4 = 0
myrange(myrange.Count).End(xlUp).Offset(1, 0).Value = padding
Loop
End Sub
Return a Column in a String Conditionally
Adjust the values in the constants section.
Reference the worksheet more safely.
Option Explicit
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Tests the 'StrFilledColumnRange' function.
' Calls: StrFilledColumnRange, TextString.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub StrFilledColumnRangeTEST()
' Define constants.
Const FilePath As String = "C:\Test\Test.txt"
Const crgAddress As String = "C8:C104"
Const FillString As String = "x"
Const ModNonBlank As Long = 4
Const HasHeader As Boolean = True
' Reference the worksheet ('ws').
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
' Reference the (one-column) range ('crg').
Dim crg As Range: Set crg = ws.Range(crgAddress)
' Using the function, return the required values in a string ('rString').
Dim rString As String
rString = StrFilledColumnRange(crg, FillString, ModNonBlank, True)
' Check if the string is empty.
If Len(rString) = 0 Then
MsgBox "The resulting string is empty.", vbExclamation
Exit Sub
End If
' Display the result.
Debug.Print rString
'MsgBox rString, vbInformation
' Write the string to a text file.
'TextString FilePath, rString
End Sub
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: From a given one-column range, returns a string that...
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function StrFilledColumnRange( _
ByVal ColumnRange As Range, _
ByVal FillString As String, _
Optional ByVal ModNonBlank As Long = 1, _
Optional ByVal HasHeader As Boolean = False) _
As String
Const ProcName As String = "StrFilledColumnRange"
On Error GoTo ClearError
' Reference the first cell ('fCell') of the range.
Dim fCell As Range: Set fCell = ColumnRange.Cells(1)
' Reference the column data range ('cdrg')(no headers).
Dim hrOffset As Long
If HasHeader Then hrOffset = 1
Dim cdrg As Range: Set cdrg = ColumnRange _
.Resize(ColumnRange.Rows.Count - hrOffset).Offset(hrOffset)
' Make sure that all rows and columns are visible, or the following
' use of the Find method will fail.
' Reference the bottom-most non-blank cell ('lCell')
' of the column data range ('xlValues' - non-blanks).
Dim lCell As Range: Set lCell = cdrg.Find("*", , xlValues, , , xlPrevious)
If lCell Is Nothing Then
MsgBox "No data in '" & cdrg.Address(0, 0) & "'.", vbCritical
Exit Function
End If
' Retrieve the current number of rows ('crCount') of the column data range.
Dim crCount As Long: crCount = lCell.Row - fCell.Row - hrOffset + 1
' Calculate the remainder ('Remainder'), the number of how many
' fill strings to be 'appended'.
Dim Remainder As Long: Remainder = crCount Mod ModNonBlank
If Remainder > 0 Then Remainder = ModNonBlank - Remainder
' Write the source number of rows to a variable ('srCount').
Dim srCount As Long: srCount = ColumnRange.Rows.Count
' Calculate the destination number of rows ('drCount')
' and correct 'Remainder'.
Dim drCount As Long: drCount = hrOffset + crCount + Remainder
If drCount > srCount Then
Remainder = Remainder + srCount - drCount
drCount = srCount
End If
' Declare a variable for the resulting string ('rString').
Dim rString As String
If drCount = 1 Then ' one cell only; unlikely yet theoretically possible
rString = ColumnRange.Value
Else ' multiple cells
' Reference the last (offsetted) cell.
Set lCell = lCell.Offset(Remainder)
' Reference the range ('crg').
Dim crg As Range: Set crg = ColumnRange.Worksheet.Range(fCell, lCell)
' Write the values from the range to a 2D one-based array ('cData').
Dim cData() As Variant: cData = crg.Value
' Write the fill string(s) to the array.
Dim dr As Long ' Current Destination Row
For dr = drCount To drCount - Remainder + 1 Step -1
cData(dr, 1) = FillString
Next dr
' Write the values from the array to the resulting string.
rString = cData(1, 1)
For dr = 2 To drCount
rString = rString & vbLf & cData(dr, 1)
Next dr
End If
' Return the string as the result of the function.
StrFilledColumnRange = rString
ProcExit:
Exit Function
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume ProcExit
End Function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Purpose: Writes a string to a file.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub TextString( _
ByVal FilePath As String, _
ByVal WriteString As String)
Const ProcName As String = "TextString"
On Error GoTo ClearError
Dim TextFile As Long: TextFile = FreeFile
Open FilePath For Output Access Write As #TextFile
Print #TextFile, WriteString
Close TextFile
ProcExit:
Exit Sub
ClearError:
Debug.Print "'" & ProcName & "' Run-time error '" _
& Err.Number & "':" & vbLf & " " & Err.Description
Resume ProcExit
End Sub

Incompatibility type when using range

I'm trying to to run a command if these arguments checks , but it's giving me incompatibily type on that block, what am I doing wrong?
Dim rn as range
For Each rg In Columns("X")
If rg.Value Like "?*#?*.?*" And _
LCase(Cells(rg.Row, "U").Value) = "Demande de création d'intervention" _
And LCase(Cells(rg.Row, "V").Value) <> "envoyé" Then
Comparing Strings
If you loop through the cells of the whole column, it will take forever. Calculate the last row, the row of the last non-empty cell in the column, instead.
LCase(Something) will never be equal to Demande.... Use demande... instead.
If you use CStr to convert a value to a string, you won't have to worry about the value being incompatible when comparing it to another string.
The Code
Option Explicit
Sub Test()
Const FirstRow As Long = 2
Dim ws As Worksheet: Set ws = ActiveSheet ' improve!
Dim LastRow As Long: LastRow = ws.Cells(ws.Rows.Count, "X").End(xlUp).Row
' If LastRow < FirstRow Then
' MsgBox "No data in column.", vbCritical
' Exit Sub
' End If
' Reference the column range ('rg').
Dim rg As Range
Set rg = ws.Range(ws.Cells(FirstRow, "X"), ws.Cells(LastRow, "X"))
' Reference the other column ranges ('rg2', 'rg3')
Dim rg2 As Range: Set rg2 = rg.EntireRow.Columns("U")
Dim rg3 As Range: Set rg3 = rg.EntireRow.Columns("V")
' Note that all three ranges are of the same size.
' Declare additional variables to be use in the loop.
Dim Cell As Range ' Current cell in the first range
Dim cString As String ' String Representation of the Current Cell's Value
Dim r As Long ' Index of the Current Cell
' Use 'CStr' to convert the values to strings to avoid an error occurring
' if the cell contains an error value.
For Each Cell In rg.Cells ' note '.Cells'
r = r + 1 ' count the cells (in this case rows)
cString = CStr(Cell.Value)
If cString Like "?*#?*.?*" _
And LCase(CStr(rg2.Cells(r).Value)) _
= "demande de création d'intervention" _
And LCase(CStr(rg3.Cells(r).Value)) <> "envoyé" Then
' Do your thing, e.g.
Debug.Print r, cString
End If
Next Cell
End Sub
Results in the Immediate window (Ctrl+G).
8 FY#I.NV
11 MF#X.UT
14 EU#X.IF

Copy and Paste the Unique Values from Filtered Column

I'm trying to get the Unique values from the Filtered Range and trying to paste the same into specific worksheet. But I'm facing a Run-Time Error 1004 (Database or Table Range is not Valid).
Set DataSet = MainSht.Range(Cells(1, 1), Cells(Lrows, Lcols))
With DataSet
.AutoFilter field:=3, Criteria1:=Array("Corporate Treasury - US", "F&A"), Operator:=xlFilterValues
Set DataRng = .Offset(1, 10).Resize(.Rows.Count - 1, 1).SpecialCells(xlCellTypeVisible)
.AutoFilter
With DataRng
.AdvancedFilter Action:=xlFilterCopy, copytorange:=Wb.Sheets("Corporate Treasury - US").Range("A2"), Unique:=True 'Getting Error Here
End With
End With
Appreciate your help in advance!!
Copy Filtered Unique Data
Basically
'Remove' previous filters.
Create accurate range references before applying AutoFilter.
The filter is applied on the Table Range (headers included).
Use error handling with SpecialCells (think no cells found).
Apply SpecialCells to the Data Range (no headers).
It is usually safe to 'remove' the filter after the reference to the SpecialCells range is created.
Copy/paste and only then apply RemoveDuplicates (xlNo when Data Range).
Optionally, apply Sort (xlNo when Data Range) to the not necessarily exact destination range (ducdrg i.e. no empty cells (due to RemoveDuplicates)).
(xlYes when Table Range.)
A Study
Adjust the values in the constants section (the worksheets are off).
Option Explicit
Sub CopyFilteredUniqueData()
' Source
Const sName As String = "Sheet1"
' Copy
Const sCol As Variant = "K" ' or 11
' Filter
Const sfField As Long = 3
Dim sfCriteria1 As Variant
sfCriteria1 = Array("Corporate Treasury - US", "F&A")
Dim sfOperator As XlAutoFilterOperator: sfOperator = xlFilterValues
' Destination
Const dName As String = "Sheet2"
' Paste
Const dFirst As String = "A2"
' Workbook
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Source
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Debug.Print vbLf & "Source (""" & sws.Name & """)"
' Remove possble previous filters.
If sws.AutoFilterMode Then
sws.AutoFilterMode = False
End If
' Source Table Range
Dim strg As Range: Set strg = sws.Range("A1").CurrentRegion
Debug.Print strg.Address(0, 0)
' Source Column Data Range (No Headers)
Dim scdrg As Range
With strg.Columns(sCol)
Set scdrg = .Resize(.Rows.Count - 1).Offset(1)
End With
Debug.Print scdrg.Address(0, 0) & " (No Headers)"
' Filter.
strg.AutoFilter sfField, sfCriteria1, sfOperator
' Source Filtered Column Data Range (No Headers)
On Error Resume Next
Dim sfcdrg As Range: Set sfcdrg = scdrg.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
sws.AutoFilterMode = False ' no need for the filter anymore
If sfcdrg Is Nothing Then Exit Sub ' no matching cells
Debug.Print sfcdrg.Address(0, 0) & " (No Headers)"
' Destination
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
Debug.Print vbLf & "Destination (""" & dws.Name & """)"
' Destination First Cell
Dim dfCell As Range: Set dfCell = dws.Range(dFirst)
' Destination Column Data Range (No Headers)
Dim dcdrg As Range: Set dcdrg = dfCell.Resize(sfcdrg.Cells.Count)
Debug.Print dcdrg.Address(0, 0) & " (No Headers)"
' Copy.
sfcdrg.Copy dcdrg
' Remove duplicates.
dcdrg.RemoveDuplicates 1, xlNo
Debug.Print dcdrg.Address(0, 0) & " (No Headers, Empty Cells Included)"
' Destination Last Cell
Dim dlCell As Range
Set dlCell = dcdrg.Find("*", , xlFormulas, , , xlPrevious)
' Destination Unique Column Data Range (No Headers)
Dim ducdrg As Range
With dcdrg
Set ducdrg = .Resize(dlCell.Row - .Row + 1)
End With
Debug.Print ducdrg.Address(0, 0) & " (No Headers, Empty Cells Excluded)"
' Sort ascending.
ducdrg.Sort ducdrg, , Header:=xlNo
End Sub
I believe the error is because it cannot past a range of non-contiguous cells within a column.
I got round this by simply using the .copy command, but this will paste your unique list with the underlying formatting. See my solution below -
> Set DataSet = MainSht.Range(Cells(1, 1), Cells(Lrows, Lcols))
>
> With DataSet
> .AutoFilter field:=3, Criteria1:=Array("Corporate Treasury - US", "F&A"), Operator:=xlFilterValues
> Set DataRng = .Offset(1, 10).Resize(.Rows.Count - 1, 1).SpecialCells(xlCellTypeVisible)
> DataRng.Copy Destination:=Wb.Sheets("Corporate Treasury - US").Range("A2:A" & (DataRng.Rows.Count + 2))
>
> End With
If you do not want to bring across cell properties/formatting from the original worksheet, you could combine the .copy command with a .pastespecial to only paste in values, formulas or whatever details you need.

Assigning range of cells results in Type Mismatch (Run-time Error 13)

I am trying to automate the population of a Vlookup formula, looking up values from one worksheet in another. There are two worksheets in the workbook, Suppliers and Products. The product code is looked up from the Products worksheet in the Suppliers worksheet.
This is the code:
Dim lastrow As Long
Sheets("Suppliers").Select
lastrow = ActiveSheet.UsedRange.Rows.Count
Dim SuppliersRnge As Range
Set SuppliersRnge = Range(Cells(2, 2), Cells(lastrow, 3))
' This next try was by declaring the first and last rows and columns in Suppliers sheet as variables and passing values to them (passing values not shown here)
' Set SuppliersRnge = .Range(.Cells(SupplierFirstRow, SupplierFirstColumn), .Cells(SupplierLastRow, SupplierLastColumn))
' This next try was by declaring the range as a static set of cells rather than using lastrow
' Set SuppliersRnge = Range("B2:C23")
' This next try was to pick cell references from currently active worksheet
' Set SuppliersRnge = .Range(.Cells(2, 2), .Cells(lastrow, 3))
' This next try was by fully qualifying the name of the worksheet from which the cell reference is drawn
' Set SuppliersRnge = Worksheets(Suppliers).Range(Cells(2, 2), Cells(lastrow, 3))
' Now switching to product sheet
Sheets("Products").Select
' Selecting cell in which vlookup will be added
Range("A4").Select
ActiveCell.FormulaR1C1 = "=VLOOKUP(RC[1],SuppliersRnge,2,FALSE)"
I am declaring SuppliersRnge as a range and using Set to pass to it the range of cells that need to be looked up.
I have tried to do it in five different ways (you will find four of the ways commented out above) with the same result, which is that the string SuppliersRnge literally gets used in the vlookup, resulting in a >#NAME? value where the result of the Vlookup should be.
When I run ?SuppliersRnge in the Immediate window, I get the Type Mismatch (Run-time Error 13).
If I run a Watch on the SuppliersRnge variable, it starts with a "Nothing" value then changes to a blank.
Any idea on where I might be going wrong? Thanks!
Formulas in VBA
Note the single quotes (around the worksheet name) which are only necessary if the worksheet name contains spaces, but it is good practice to use them always.
Option Explicit
Sub writeVLookupFormula()
Const sName As String = "Suppliers" ' Source
Const dName As String = "Products" ' Destination
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
Dim sws As Worksheet: Set sws = wb.Worksheets(sName)
Dim sLast As Long: sLast = sws.UsedRange.Rows.Count
Dim srg As Range: Set srg = sws.Range(sws.Cells(2, 2), sws.Cells(sLast, 3))
Dim dws As Worksheet: Set dws = wb.Worksheets(dName)
' R1C1-style
Dim dFormula As String: dFormula = "=VLOOKUP(RC[1],'" & sName & "'!" _
& srg.Address(, , xlR1C1) & ",2,FALSE)"
dws.Range("A4").FormulaR1C1 = dFormula
' Or:
' ' A1-style
' Dim dFormula As String: dFormula = "=VLOOKUP(B4,'" & sName & "'!" _
' & srg.Address & ",2,FALSE)"
' dws.Range("A4").Formula = dFormula
End Sub

Resources