Method Range of Object Worksheet failed excel VBA - excel

I have been stuck on a particular problem I am having with an excel visual basic macro.
I have written a script to simply paste a dynamic range of data from one worksheet to the other, The sheet that is being pasted to is a running sheet that updates to the next empty row each time new data is sent to it.
For certain ranges of data my code breaks and gives me the 1004 error.
I have looked at multiple similar questions and they don't seem to have given me any solutions.
I will first post my code then a data set that works and a data set that does not.
Private Sub RunningSheetClick_Click()
Dim lastrow As Long
Dim Vals As Range
Dim copyWS As Worksheet
Dim pasteWS As Worksheet
Set pasteWS = Sheets("Full List")
Set copyWS = Sheets("Macro Test")
Setlastrow = Sheets("Full List").Range("A" & Rows.count).End(xlUp).Row + 1
copyWS.Activate
' the following line is where my error appears
Set Vals = copyWS.Range("B3:S" & copyWS.Range("B3").End(xlDown))
Vals.Select
Vals.Copy _
Destination:=pasteWS.Range("A" & lastrow)
End Sub
This is a data set that works and exports correctly to the sheet "Full List"
This is a data set that does not, I believe it has to do with column B and the strings that are in those cells as compared to the integers in the first data set
Any help would be appreciated, thank you for taking the time

This is bad syntax that should never work. You just cannot concatenate a range object onto a string and expect a valid range object. I suspect it works with numbers since copyWS.Range("B3").End(xlDown) is returning its cell value by default. So if the value at the bottom of column B was 99, you would be resolved to Range("B3:S99").
Set Vals = copyWS.Range("B3:S" & copyWS.Range("B3").End(xlDown))
It should be something like,
with copyWS
Set Vals = .Range(.cells(3, "B"), .cells(rows.count, "B").end(xlup).offset(0, 17))
end with

Related

Vlookup in vba to find values between two worksheets

I'm trying to grab the values from a different worksheet and match them to the their sister data in my main sheet in column A but I'm having issues with getting the right results, I was thinking of going the Vlookup route but I can't quite get it to work properly. I found a funky way of getting it done but I'm trying to save just the values and not the formula itself.
This is what I tried at first
Sub matchID()
'Dim wb As Workbook
'Set wb = ActiveWorkbook
'
'With wb.Sheets("Data")
' .Range("E2:E" & .Range("A" & .Rows.Count).End(xlUp).Row).Formula = "=VLOOKUP(A2,ID!A:B,2,FALSE)"
'End With
'the above works but need to save values and not formula
It kinda works but I need that values and not the formula, my plan is to find the data I need and then save a copy of the file as a csv
I tried using a different method but I'm running into runtime error '1004'
I'm still learning VBA so I feel like I'm spinning my wheels right now.
Can someone show me what I'm doing wrong?
Sub matchID()
'this is what I'm trying to get to work but unsure if I will still end up with formula and not just values
Dim result As String
Dim sheet As Worksheet
Dim lrow As Integer
Dim i As Integer
Set sheet = ActiveWorkbook.Sheets("Data")
lrow = sheet.UsedRange.Rows(sheet.UsedRange.Rows.Count).Row
For i = 2 To lrow
result = Application.WorksheetFunction.VLookup("A2", Sheets("ID").Range("A:B"), 2, False)
Cells(i, 5).Value = result
Next
End Sub
I'm trying to lookup all IDs(in column B) from my second sheet("ID") using the values in column A from my primary sheet("Data") and then populate the all results in column E in my primary sheet to their match.
My first try kinda worked but instead of leaving just the value it leaves the formula in the cell e.g. =VLOOKUP(A2,ID!A:B,2,FALSE) when really I'm looking for just the value 8447 that it shows before clicking on the cell.
If you want to get rid of the formula, just paste as values:
Sub matchID()
Dim wb As Workbook
Set wb = ActiveWorkbook
With wb.Sheets("Data")
.Range("E2:E" & .Range("A" & .Rows.Count).End(xlUp).Row).Formula = "=VLOOKUP(A2,ID!A:B,2,FALSE)"
.Range("E2:E" & .Range("A" & .Rows.Count).End(xlUp).Row).Value = .Range("E2:E" & .Range("A" & .Rows.Count).End(xlUp).Row).Value
End With
End Sub

Copy a named range and paste it in another sheet without overwriting data

I am trying to copy specific cells in a range from sheet1 to specific cells in sheet2.
However, when I simply use .PasteSpecial data gets overwritten. This is because the range from sheet1 is not always the same size and could cause it to overwrite data on sheet2. I want to paste the data from sheet1 on sheet2 but if the range is bigger on sheet1 than on sheet2 it has to first insert rows on sheet2 so it does not overwrite other data.
Here is some some example code for what I've tried (I am not experienced in VBA so excuse me for any weird code):
Sub ResizeNamedRange()
Dim xWb As Workbook
Dim xNameString As String
Dim xName As Name
Dim row_count As Integer
Set xWb = Application.ActiveWorkbook
xNameString = "Destination_A"
Set xName = xWb.Names.Item(xNameString)
Set row_count = xWb.Names.Item(xNameString).Rows.Count
If row_count <= 1 Then
Sheets("Hours").range("A9:E14").PasteSpecial xlPasteValues
End If
End Sub
However I keep getting errors like Object required and others. Does anyone know how to do this? I appreciate all the help I can get!
Two initial tips - use Set statement only when assigning value to a variable or a property. See:
https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/set-statement
Additionally, you cannot use Rows.Count on Names.Item. Instead, you can replace it with:
xNameString = "Destination_A"
Set xName = xWb.Names.Item(xNameString)
row_count = Range(xName.RefersTo).Rows.Count

Named range giving Error 1004 'Method 'Range' Of Object 'Worksheet' Failed'

This code was working just fine, but I did a bunch of other code that manipulates and reads the same area of the sheet and now this section does not work.
I have tried a bunch of stuff with syntax but none worked. It may be that I need to resize my array but since im setting it equal to a range I didnt think that I had to. Also It says the problem is the range but I dont know. I would rather not have to resize as its taking from a larger table whose line items will be dynamic but I can do that and make it dynamic if I need to. I did try deleting the range and renaming it and it did not work.
Private Sub UserForm_Initialize()
Dim codes()
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
codes = ws.Range("cCodes")
CostCode1.List = codes ''these are combo boxes
CostCode2.List = codes
CostCode3.List = codes
CostCode4.List = codes
CostCode5.List = codes
CostCode6.List = codes
'' ADD UNITS
End Sub
you don't need to declare the sheet for the named range.
named ranges are stored as an external address including the sheet's Name.
codes = Range("cCodes")
should be sufficient.
As far as I can tell the error comes because you don't have the named range "cCodes").
Go to Formulas -> Name Manager and check your names. Alternatively, use a range directly in the code, i.e.: codes = ws.Range("A1:A100")
To answer your question in the comment:
Is there a way for me to directly reference the three columns of the table that I want to set to the array
Here are a few ways to manipulate the range from your table into the array (specific rows/columns), and back on the sheet (see comments in code). Hope this helps.
Option Explicit
Sub test()
Dim rngData As Range
Dim arrData As Variant
With Range("Table1") 'this is only the content of the table, does not include the headers
Set rngData = Range(.Cells(1, 1), .Cells(.Rows.Count, 3)) 'Set the range starting at cell row 1, col 1 - until total number of rows in table, col 3
'Set rngData = rngData.Offset(-1).Resize(.Rows.Count + 1) 'if you want to include headers as well
Debug.Print rngData.Address
End With
arrData = rngData 'allocate the data from the range to the array
rngData.Offset(0, Range("Table1").Columns.Count + 1) = arrData 'put the array back on the sheet, 1 column to the right of the table
Dim ws As Worksheet: Set ws = ThisWorkbook.Sheets("Sheet1")
ws.Range("N1").Resize(UBound(arrData), UBound(arrData, 2)) = arrData 'put the array back on the sheet in a specific range
End Sub

Can't Select a Cell - Very Strange

Please help!
The last line of my code
'Sheets("Original Data from Server").Cells(4, 2).Select
Will not work! Keep getting error "Select method of range class failed'
Whenever I only run that one line, it works perfect.
But whenever I run the rest of the code, I get the error.
NO ONE can seem to help me figure this out!
Sub FormatAdjacencyReport()
Dim iLastRow As Integer '<-- Interger for Counting Number of Rows
Dim iLastColumn As Integer '<-- Interger for Counting Number of Columns
Dim OriginalOutput As Worksheet '<-- Sheet Containing Orignal Report
Dim AdjacencyData As Worksheet '<-- Sheet Crated for Final Output
Set OriginalOutput = ActiveWorkbook.Worksheets(1)
OriginalOutput.Name = "Original Data from Server"
'Determines how many different rows we have in original output
iLastRow = Range("B1").Rows.End(xlDown).Row
'Txt to Columns for Each Row
For i = 2 To iLastRow
Sheets("Original Data from Server").Cells(i, 5).TextToColumns DataType:=xlDelimited, _
ConsecutiveDelimiter:=True, Space:=True
Next i
'Create a new sheet for our output
Set AdjacencyData = Sheets.Add
AdjacencyData.Name = "Adjacency Data Output"
'Need to Paste the Entire List of Store Numbers into a New Tab
iLastColumn = Sheets("Original Data from Server").Cells(2, 1).Columns.End(xlToRight).Column
'Sheets("Original Data from Server").Cells(4, 2).Select
End Sub
You need to set focus back on Sheets("Original Data from Server") before calling a select on that sheet. So put line 'Sheets("Original Data from Server").Select before the last line. When the line throwing error is being executed, the focus is on another sheet.
To avoid this kind of errors I suggest you stop working with select and/or activate generally, and only use it when absolutely necessary.
Your code could look like this:
Sub FormatAdjacencyReport()
Dim iLastRow As Long '<-- for Counting Number of Rows
Dim iLastColumn As Long '<-- for Counting Number of Columns
Dim OriginalOutput As Worksheet '<-- Sheet Containing Orignal Report
Dim AdjacencyData As Worksheet '<-- Sheet Crated for Final Output
Set OriginalOutput = ActiveWorkbook.Worksheets(1)
OriginalOutput.Name = "Original Data from Server"
'Determines how many different rows we have in original output
iLastRow = OriginalOutput.Range("B1").End(xlDown).Row ' changed
iLastColumn = OriginalOutput.Range("A2").End(xlToRight).Column ' changed
'Txt to Columns for Each Row
For i = 2 To iLastRow
OriginalOutput.Cells(i, 5).TextToColumns DataType:=xlDelimited, _
ConsecutiveDelimiter:=True, Space:=True
Next i
'Create a new sheet for our output
Set AdjacencyData = Sheets.Add
AdjacencyData.Name = "Adjacency Data Output"
'Need to Paste the Entire List of Store Numbers into a New Tab
' OriginalOutput.Activate -- not needed
' OriginalOutput.Cells(4, 2).Select -- not needed
OriginalOutput.Range("B4:B17").Value = AdjacencyData.Range("A10:A23") ' direct copy!
End Sub
1- work with qualified ranges/cells whenever you work on more than one sheet or workbook. See the line where iLastRow is determined.
2- keep table limit calculation in one place (as soon as the limits are fixed)
3- avoid an explict qualifier (Sheets("Original Data from Server").) in favor of the assigned variable (OrignalOutput). This way you can fully qualify (with workbook name and sheet name) in just one place. Imagine you'd change the sheet name later...
4- use direct assignment from range to range for copying. This circumvents the reference problem (if using qualifiers!), and the clipboard contents are kept intact.

Problems trying to set RefersToRange property in Excel VBA

I was helping a friend work out a problem with VBA in Excel 2007 today, and we ran into an issue I think I'd encountered and worked around in the past. It's an issue with changing the range to which a name refers.
On my friend's main worksheet, in B7, she has data validation from a List where the Source is a named range, CAT_LOOKUP. She wanted to run a sub that would filter a table on another worksheet to show only rows that correspond to the value in B7 and then use those rows as the source for validation in another cell on that worksheet.
Here's the relevant part of the VBA we were using:
Dim strCAT As String
Dim strACT As String
Dim sh As Worksheet
Dim rng As Range
Dim rngDest As Range
If Cells(7, 2) <> "" Then
strCAT = Cells(7, 2).Value
Sheets("CAT LOOKUP").Range("$A2:$C393").AutoFilter Field:=1, _
Criteria1:=strCAT
Set sh = Sheets("CAT LOOKUP")
Set rng = sh.Range("B34:B56")
rng.ClearContents
Set rng = sh.Range(sh.Range("B1"), sh.Range("B1").End(xlDown))
rng.Copy
Set rngDest = sh.Range("B34")
rngDest.PasteSpecial
ActiveWorkbook.Names("CAT_LOOKUP").RefersToRange = _
sh.Range(sh.Range("B35"), sh.Range("B35").End(xlDown))
Else
Set sh = Sheets("CAT LOOKUP")
Set rng = sh.Range("B34:B56")
rng.ClearContents
Sheets("Ad Hoc Request").Select
End If
CAT_LOOKUP is already defined. When this code is run, the CAT_LOOKUP range is cleared, and the definition of the range is unchanged.
I found in my notes from an old project that I'd used RefersToR1C1 instead of RefersToRange, so I changed that line to this:
ActiveWorkbook.Names("CAT_LOOKUP").RefersToR1C1 = _
"='CAT LOOKUP'!R35C2:R" & sh.Range("B35").End(xlDown).Row & "C2"
and the code worked as desired, resetting the named range so that the corresponding data validation works properly.
Is this simply a bug in the implementation of RefersToRange, or is there a problem with the way we were using it?
RefersToRange is read-only, at least in XL 2003 and probably in 2007.

Resources