why does this line produce a runtime error? - vba

Working with a code to grab specific data from files and this line:
With sht.Range(Cells(1, 1), Range("A1").SpecialCells(xlCellTypeLastCell))
produces: method 'Range' of object '_worksheet' failed.
I have sht dim'd as worksheet and am just trying to select the range as the whole sheet?

You wrote you "dim'd" sht as worksheet. I assume you are talking about
Dim sht As Worksheet
If you did not do the following, there might be the problem:
set sht = ThisWorkbook.Worksheets("insertnamehere") [the ThisWorkbook. part asumes the worksheet is at the same workbook as the code]
If that does not solve your Problem, pls make a debugoutput (I prefere MsgBox, but only personal preference) of the second part, like MsgBox sht.Range("A1").SpecialCells(xlCellTypeLastCell).Address and post the result here (An address? A new error? If so, wich?)
Hope it helps at least one step forward.
PS: If you set sht allready (not only dim'd it <- love that phrase :P ) pls also edit your post and add the code for that (and anything that might relate)

Related

VBA: "Getting run-time 1004: Method 'Range' of object '_Worksheet' failed" when running code on multiple sheets [duplicate]

This script works fine when I'm viewing the "Temp" sheet. But when I'm in another sheet then the copy command fails. It gives an Application-defined or object-defined error:
Sheets("Temp").Range(Cells(1), Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial
I can use this script instead, but then I have problems with pasting it:
Sheets("Temp").Columns(1).Copy
Sheets("Overview").Range("C40").PasteSpecial
I don't want to activate the "Temp" sheet to get this.
What else can I do?
Your issue is that the because the Cell references inside the Range 's are unqualified, they refer to a default sheet, which may not be the sheet you intend.
For standard modules, the ThisWorkbook module, custom classes and user form modules, the defeault is the ActiveSheet. For Worksheet code behind modules, it's that worksheet.
For modules other than worksheet code behind modules, your code is actually saying
Sheets("Temp").Range(ActiveSheet.Cells(1), ActiveSheet.Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial
For worksheet code behind modules, your code is actually saying
Sheets("Temp").Range(Me.Cells(1), Me.Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial
In either case, the solution is the same: fully qualify the range references with the required workbook:
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Set sh1 = ActiveWorkbook.Sheets("Temp")
Set sh2 = ActiveWorkbook.Sheets("Overview")
With sh1
.Range(.Cells(1,1), .Cells(1,1).End(xlDown)).Copy
End With
sh2.Range("C40").PasteSpecial
Note: When using .End(xlDown) there is a danger that this will result in a range extending further than you expect. It's better to use .End(xlUp) if your sheet layout allows. If not, check the referenced cell and the cell below for Empty first.
I encountered a problem like this myself: I was trying to search through a separate worksheet to see if the color of a cell matched the color of a cell in a list and return a string value: if you are using .Cells(row, column), you only need this:
Sheets("sheetname").Cells(row, column)
to reference that range of cells.
I was looping through a block of 500 cells and it works surprisingly quickly for me.
I have not tried this with .Copy, but I would assume it would work the same way.
This will do, I don't like to use (xlDown) in case a cell is empty.
Dim lRow As Long
lRow = Sheets("Temp").Cells(Cells.Rows.Count, "A").End(xlUp).Row
With Sheets("Temp")
.Range("A1:A" & lRow).Copy Sheets("Overview").Range("C40")
End With
Or if you want to just use Columns...
Sheets("Temp").Columns(1).SpecialCells(xlCellTypeConstants).Copy Destination:=Sheets("Overview").Range("C40")

Trying to use boolean logic within Application.WorksheetFunction.MATCH and getting Type Mismatch error

I have a worksheet function that is working perfectly fine in the worksheet, however, when I try to reproduce it in a macro I am receiving a Runtime Error 13 Type Mismatch. The function in the worksheet is:
=INDEX(TBQA[Question],MATCH(TRUE,INDEX(TBQA[Answer]=TBQA[#Answer],0),0))
The table I am drawing the values from is named "TBQA". The two columns I am trying to refer to in part of the macro are "Question" and "Answer". I have a UserForm ComboBox that I am using as the comparison reference source named "TBABox" and when I click a button, I want to index the value in the "Question" column that matches the answer in the "Answer" column (which is the source for the ComboBox dropdown values).
Private Sub ShowMeQues_Click()
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Set ws1 = Sheets("Information")
Set ws2 = Sheets("Resource")
MsgBox Application.WorksheetFunction.Index(ws1.Range("TBQA[Question]"), _
Application.WorksheetFunction.Match("TRUE", _
Application.WorksheetFunction.Index(ws1.Range("TBQA[Answer]") = TBABox.Value, 0), 0))
End Sub
I believe the issue is occurring when I am trying to get a "TRUE" value where the ws1.Range("TBQA[Answer]") = TBABox.Value, but I could be wrong. Please help. I feel like it is a simple fix that I am just overlooking, but I have been searching the internet to find out a resolution to no avail. Any suggestions welcome. THANK YOU!!! :)
I was able to resolve this issue by taking another route! My main goal was to bypass the 255 Character limit set by VBA with the MATCH function. Please see my other post for the resolution that I came up with. Thank you for your help!!!
https://stackoverflow.com/a/72582313/10443879

Excel 2016 VBA: Set Source Data for a Chart to a Named Table

The title is pretty self-explanatory.
I have a named table, Table_Unit_2_Data, which I would like to set as the source data for a chart that will be created using VBA.
During the recording of a macro I selected the entirety of the table, and inserted a chart. This is the code that I got (Build is the name of the Sheet):
Sub Test()
Range("Table_Unit_2_Data[#All]").Select
ActiveSheet.Shapes.AddChart2(240, xlXYScatterSmoothNoMarkers).Select
ActiveChart.SetSourceData Source:= Range("Build!$Y$1:$AD$2")
End Sub
Well, for one thing, as you can see, a specific $A$1 range is passed into the SetSoureData. This will not work because the range of Table_Unit_2_Data will change.
I attempted this:
With Sheet2.Shapes.AddChart2(240, xlXYScatterSmoothNoMarkers)
.Chart.SetSourceData (Sheet2.Range("Table_Unit_2_Data[#All]"))
End With
But then I get the error "Object Required".
I can't seem to phrase my search queries in such a way as to find relevant answers to this specific question on the internet so I apologize for asking what is likely a redundant question. If someone could help me with this problem I would be greatly appreciative and if anyone has a good article or source online for information regarding the nuances of chart creation within VBA that would also be very helpful.
Thank you.
In addition to what Domenic said (which is correct + would cause the "Object Required" error), your code doesn't make it clear what "Sheet2" is, except that it's the codename of some sheet. From the recorded macro, I can infer that the actual table is on a sheet called "Build", so another possibility to consider is that Sheet2 isn't actually the codename of Sheets("Build"). Again, I can't actually tell from the code provided.
While I do like using sheet codenames, I'd strongly recommend against using them if you're not going to make the names descriptive.
FWIW, there's another way to reference table ranges that's a little more flexible, especially if you're going to be referring to the table elsewhere in the code. Just make a ListObject variable:
Dim UnitTable2 As ListObject
Set UnitTable2 = Sheets("Build").ListObjects("Table_Unit_2_Data")
And you'll be able to reference any part of the table really easily:
Dim rng As Range
'Reference the whole table, including headers:
Set rng = UnitTable2.Range
'Reference just the table data (no headers):
Set rng = UnitTable2.DataBodyRange
'Reference just the data in a single column:
Set rng = UnitTable2.ListColumns("Col1").DataBodyRange
'Reference the headers only
Set rng = UnitTable2.HeaderRowRange

VBA Run-time error 1004 - Declaring a data type based on number of rows in particular range [duplicate]

This script works fine when I'm viewing the "Temp" sheet. But when I'm in another sheet then the copy command fails. It gives an Application-defined or object-defined error:
Sheets("Temp").Range(Cells(1), Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial
I can use this script instead, but then I have problems with pasting it:
Sheets("Temp").Columns(1).Copy
Sheets("Overview").Range("C40").PasteSpecial
I don't want to activate the "Temp" sheet to get this.
What else can I do?
Your issue is that the because the Cell references inside the Range 's are unqualified, they refer to a default sheet, which may not be the sheet you intend.
For standard modules, the ThisWorkbook module, custom classes and user form modules, the defeault is the ActiveSheet. For Worksheet code behind modules, it's that worksheet.
For modules other than worksheet code behind modules, your code is actually saying
Sheets("Temp").Range(ActiveSheet.Cells(1), ActiveSheet.Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial
For worksheet code behind modules, your code is actually saying
Sheets("Temp").Range(Me.Cells(1), Me.Cells(1).End(xlDown)).Copy
Sheets("Overview").Range("C40").PasteSpecial
In either case, the solution is the same: fully qualify the range references with the required workbook:
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Set sh1 = ActiveWorkbook.Sheets("Temp")
Set sh2 = ActiveWorkbook.Sheets("Overview")
With sh1
.Range(.Cells(1,1), .Cells(1,1).End(xlDown)).Copy
End With
sh2.Range("C40").PasteSpecial
Note: When using .End(xlDown) there is a danger that this will result in a range extending further than you expect. It's better to use .End(xlUp) if your sheet layout allows. If not, check the referenced cell and the cell below for Empty first.
I encountered a problem like this myself: I was trying to search through a separate worksheet to see if the color of a cell matched the color of a cell in a list and return a string value: if you are using .Cells(row, column), you only need this:
Sheets("sheetname").Cells(row, column)
to reference that range of cells.
I was looping through a block of 500 cells and it works surprisingly quickly for me.
I have not tried this with .Copy, but I would assume it would work the same way.
This will do, I don't like to use (xlDown) in case a cell is empty.
Dim lRow As Long
lRow = Sheets("Temp").Cells(Cells.Rows.Count, "A").End(xlUp).Row
With Sheets("Temp")
.Range("A1:A" & lRow).Copy Sheets("Overview").Range("C40")
End With
Or if you want to just use Columns...
Sheets("Temp").Columns(1).SpecialCells(xlCellTypeConstants).Copy Destination:=Sheets("Overview").Range("C40")

Subscript out of range Error after renaming sheets

I have done a small project, which consists of 5 excel sheet in, code is working fine and I am getting exact result also, but if I rename sheets from sheet1 to some other name I am getting Subscript out of range Error.
What is the reason for this and what needs to be done to overcome this. Please help.
Below is the code
Public Sub amount_final()
Dim Row1Crnt As Long
Dim Row2Crnt As Long
With Sheets("sheet4")
Row1Last = .Cells(Rows.Count, "B").End(xlUp).Row
End With
Row1Crnt = 2
With Sheets("sheet3")
Row2Last = .Cells(Rows.Count, "B").End(xlUp).Row
End With
There is nothing wrong with the code per se. You will get Subscript out of range error if Excel is not able to find a particular sheet which is quite obvious since you renamed it. For example, if you rename your sheet "Sheet3" to "SheetXYZ" then Excel will not be able to find it.
The only way to avoid these kind of errors is to use CODENAME of the sheets. See Snapshot
Here we have a sheet which has a name "Sample Name before Renaming"
So consider this code
Sheets("Sample Name before Renaming").Range("A1").Value = "Blah Blah"
The same code can be written as
Sheet2.Range("A1").Value = "Blah Blah"
Now no matter how many times you rename the sheet, the above code will always work :)
HTH
Sid
The basic issue is that you are referring to sheets using their common names and not their codenames. Whenever you refer to Sheets("sheet4"), you are relying on the sheet having that name in Excel. Codenames are the names assigned in Visual Basic so the end user does not interact with them/as a developer you can change the Excel names any time you like
Using code names is covered at around 9:40 in this Excel help video. You'll note they are quicker to type than the Excel names as do not require the 'Sheets()' qualifier
I couldn't see Sheets("Sheet1") in your code sample but you can switch to codenames for all sheets very quickly by finding/replacing all examples of e.g. 'Sheets("Sheet2").' with 'Sheet2.'
Refer to each sheet by their code names instead. They are set to Sheet1, Sheet2 etc as default, but you can rename them in the Properties window for each sheet if you want. This way you can write your code like below instead, regardless of what you name the sheets.
With Sheet1
Row1Last = .Cells(Rows.Count, "B").End(xlUp).Row
End With
Row1Crnt = 2
With Sheet2
Row2Last = .Cells(Rows.Count, "B").End(xlUp).Row
End With
etc...
I wanted to share my experience battling this problem. Here is the mistake I committed:
Dim DailyWSNameNew As String
lastrow = Sheets("DailyWSNameNew").Range("A65536").End(xlUp).Row + 1 -- This is wrong as I included a placeholder worksheet name in quotes
Correction:
lastrow = Sheets(DailyWSNameNew).Range("A65536").End(xlUp).Row + 1
This solved it.
I encountered this error earlier today but could not use any solution above, I did however eventually managed to solve it myself.
My situation was that I had a list contained in column A. For each cell with a value I stored the value in a variable, created a new sheet and named the sheet according to the value stored in the variable.
A bit later in the code I tried to select the newly created sheet by using the code:
Sheets(ValueVariable).Select
I encountered the "Subscript out of range" error and I couldn't figure out why. I've used similar code before with success.
I did however solve it by casting the variable as a string. Declaring the variable as a string did not seem to work for me.
So, if anyone else encounter this error and want something to try, perhaps this will work for you:
Sheets(Cstr(ValueVariable)).Select