Why need to specify activesheet for chartobjects.add - vba

Sub smarterway()
Dim chartfirst As ChartObject
Dim rngChart As Range
Set rngChart = Range("D3:J20")
Set chartfirst = ActiveSheet.ChartObjects.Add(Left:=rngChart.Left, Top:=rngChart.Top, Width:=rngChart.Width, Height:=rngChart.Height)
[....]
For this line:
Set chartfirst = ActiveSheet.ChartObjects.Add(..)
if I dont add in Activesheet in. I get a Object Required error.
I don't understand why though. Isnt it assumed it is Activesheet, cause I usually don't put Activesheet in my codes and it works as long as I have the required sheet opened and activated.
I'm clearly missing and misunderstanding something very fundamental in vba, please advice

Related

VBA RBG - "Wrong number of arguments or invalid property argument"

I know there are other questions which deal with the "Wrong number of arguments or invalid property assignment", but none which deal with this error being generated on a basic line assigning an RGB colour to a cell interior.
This error is generating on line 6 of the below. I don't understand how this is possible, as RGB clearly has three arguments.
The only thing I can think of is that, earlier today, I wrote a macro in a different (now closed spreadsheet), where I used the initials "rgb" as a variant name. I know that, in R, it's possible to redefine a base function accidentally by replacing it with a UDF, and I'm wondering whether perhaps I've now unwittingly changed "rgb" to be something other than the function in the VBA base code. But that doesn't sound plausible - I've never heard of that happening in VBA, and it's more of a "for dummies" type language which I wouldn't have thought would give users that optionality.
EDIT Yes - this issue is resolved by changing the name of the macro, which is a stupid error. However, I would point out that this error is also happening in a different subroutine, which I have not named in such a stupid fashion. I will need to investigate why it's happening in that sub too.
Option Explicit
Sub RGB()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = Sheets("Sheet1")
ws.Range("G20").Interior.Color = RGB(255, 51, 204)
End Sub
In case the comments haven't explained it fully.. you state in your question:
earlier today, I wrote a macro in a different (now closed
spreadsheet), where I used the initials "rgb" as a variant name.
However, in the example you provide, you've actually called the Subroutine you're calling RGB as well. This is the cause of the issue. Renaming it would fix it but while I'm here I can share with you some other points:
This would work:
Option Explicit
Sub Set_G20_RGB()
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = Sheets("Sheet1") ' should really be Set ws = wb.Sheets("Sheet1")
ws.Range("G20").Interior.Color = RGB(255, 51, 204)
End Sub
However, to make it a little more useful, you might want to use something like:
Option Explicit
Sub Set_RGB(clr_rng As Range, red_value As Integer, grn_value As Integer, blu_value As Integer)
clr_rng.Interior.Color = RGB(red_value, grn_value, blu_value)
End Sub
Which could be called like so:
Set_RGB ThisWorkbook.Sheets("Sheet1").Range("G20"), 255, 51, 204
or..
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Sheets("Sheet1")
Set_RGB ws.Range("G20"), 255, 51, 204

Excel VBA macro to copy certain columns to another Workbook

I need to copy certain columns of one spreadsheet to another spreadsheet.
In order to do so, I have a macro:
Sub Submit()
Dim sourceColumn As Range, targetColumn As Range
Set sourceColumn =
Workbooks("Submission_Form.xlsm").Worksheets("RGSheet").Columns("A")
Set myData = Workbooks.Open("I:\Projects\...\Macros\RG.csv")
Worksheets(1).Select
Worksheets(1).Range("A1").Select
Set targetColumn = Workbooks("RG.csv").Worksheets(1).Columns("A")
sourceColumn.Copy Destination:=targetColumn
End Sub
However, when the cursor hits targetColumn, it gives error:
Run-time error '9':
Subscript out of range
For the sake of simplicity, I have put RG.csv in the same folder as Submission_Form.xlsm. So I am really confused why is it giving error.
I would also like to know how to handle if the RG.csv is located in another directory.
The error is probably because Submission_Form.xlsm isn't opened(?). Your code looks a little inconsistent. Maybe just open both source and destination, and copy the column. Something like this?
Option Explicit
Sub Submit()
Dim vSourceWorkbook As Workbook
Dim vDestinationWorkbook As Workbook
Set vSourceWorkbook = Workbooks.Open("Submission_Form.xlsm")
Set vDestinationWorkbook = Workbooks.Open("I:\Projects\...\Macros\RG.csv")
vSourceWorkbook.Worksheets("RGSheet").Range("A:A").Copy Destination:=vDestinationWorkbook.Worksheets(1).Range("A:A")
End Sub

Why doesn't Intellisense appear after typing Worksheets("Sheet1").?

I understand why it wouldn't pop up for ActiveSheet since it can return a worksheet or chart sheet so it wouldn't know which set of properties/methods to list, but if I'm explicitly referencing a worksheet within the Worksheets collection, why doesn't Intellisense get triggered?
I also want to extend this question to predefined constants. Sometimes a list of the predefined constants pops up for a property but sometimes it doesn't. Why is that? For example:
Application.Calculation=
will trigger a list of the predefined constants.
Worksheets("Sheet1").PageSetup.Orientation=
will NOT trigger a list of predefined constants.
Thanks for your answers, folks! :)
The Intellisense needs to know what is returned to give you the proper selection.
Have a look at the Object-Browser:
Application.Calulation returns XlCalculation. You get the selection by Intellisense
Worksheets("Sheet1") returns an unspecified Object, because it can be a Worksheet, but doesn't has to. That's why the Intellisense breaks at this level.
the Intellisense works if Excel know exactly what you want.
If you do this in your Sub or Function it works.
Dim sh As Excel.Worksheet
Set sh = ThisWorkbook.Worksheets("DUMMY")
sh.PageSetup.Orientation = here comes the Intellisense
Set sh = Nothing
If you declare each object as a variable and clarify the kind of object to the program, Intellisense will work normally.
See examples below.
Intellisense does not work for Charts (1), Worksheets ("Sheet1"), Cells (1, 1).
But Ws, rng, myChart work.
Sub test()
Dim Ws As Worksheet
Dim rng As Range
Dim myChart As Chart
Set myChart = Charts(1)
Set Ws = Worksheets("Sheet1")
Set rng = Cells(1, 1)
End Sub

Application-Defined or Object-defined error - Qualifying References Excel

Trying to hammer out bugs in my code. Currently trying to do some very simple, open worksheet, copy and paste data over. Trying to do it all without using .Select or .Activate. Hitting "Application-defined or Object defined error", which, from reading the other threads on the matter, probably means that my statements aren't fully qualified. However, I can't figure out how they're not fully qualified - other posts on the topic seem to be missing a "." somewhere in the code, but my attempts to fix it haven't gotten anywhere. Heavily truncated code as follows (If you don't see it dimmed/defined, it's elsewhere)
Sub CopyPaste()
Dim CitiReportEUR As Workbook
Dim CitiReportPathEUR As String
CitiReportPathEUR = Range("CitiReportPathEUR")
Workbooks.Open Filename:=CitiReportPathEUR
Set CitiReportEUR = ActiveWorkbook
LastRowCiti = CitiReportEUR.Sheets(1).Range("I" & Rows.Count).End(xlUp).Row
Set RngCitiEUR = CitiReportEUR.Sheets(1).Range("A1:CT" & LastRowCiti).SpecialCells(xlCellTypeVisible)
Set CabReport.Sheets("CITI").Range("C1").Resize(RngCitiEUR.Rows.Count).Value = RngCitiEUR.Value
End Sub
Currently the error is occurring when I define the range. I've had problems historically with pasting into the range as well... but that's an issue for when I can actually get the code to run that far!
Rows.Count is implicitly working with the ActiveSheet.
The use of Set when assigning values to the Value property of a Range is inappropriate. Set should only be used when assigning a reference to an object.
The Resize probably needs to cater for the number of columns in the source as well as rows.
This code is more explicit:
Sub CopyPaste()
Dim CitiReportEUR As Workbook
Dim CitiReportPathEUR As String
CitiReportPathEUR = Range("CitiReportPathEUR")
Set CitiReportEUR = Workbooks.Open(Filename:=CitiReportPathEUR)
With CitiReportEUR.Sheets(1)
LastRowCiti = .Range("I" & .Rows.Count).End(xlUp).Row
Set RngCitiEUR = .Range("A1:CT" & LastRowCiti).SpecialCells(xlCellTypeVisible)
End With
CabReport.Sheets("CITI").Range("C1").Resize(RngCitiEUR.Rows.Count, RngCitiEUR.Columns.Count).Value = RngCitiEUR.Value
End Sub

Store COPY of a worksheet in worksheet variable

What I want to achieve:
I want to assign copy of a worksheet to variable, for later use.
What I tried and results
First : The code below works fine. Something like this I would like to achieve, but using worksheet.copy.
Sub DuplicateSheetRenameFirst()
Dim wsDuplicate As Worksheet
Set wsDuplicate = Worksheets.Add
wsDuplicate.Name = "Duplicate"
End Sub
Second : Using the copy method, creates a worksheet in current workbook, but generates a Runtime error 424 - Object required.
Sub DuplicateSheetRenameSecond()
Dim wsDuplicate As Worksheet
Set wsDuplicate = Worksheets("Sheet1").Copy(after:=Worksheets(Worksheets.Count))
'above line : runtime error 424 object required, but the sheet is created
wsDuplicate.Name = "Duplicate"
End Sub
Third : Creates a worksheet in new workbook (so creates book, then sheet), but still generates the same Runtime error 424 - Object required.
Sub DuplicateSheetRenameThird()
Dim wsDuplicate As Worksheet
Set wsDuplicate = Worksheets("Sheet1").Copy
'above line : runtime error 424 object required, but the sheet is created in new workbook
wsDuplicate.Name = "Duplicate"
End Sub
Workaround : I can modify any of the second or third way to at first copy the sheet and then set the variable to activesheet, but I was wandering if there is a one step way of doing this. I'm not sure if this would work all the time, since the activesheet may not be the one just copied, maybe.
The Question:
Is there a simple (one step) way to store the copy of a worksheet in a variable? Preferably without errors or without filtering the error with error handler.
This is maybe ok?
Sub copySheet()
Dim ws As Excel.Worksheet
Excel.ThisWorkbook.Sheets("Sheet1").Copy After:=Sheets(1)
Set ws = Excel.ThisWorkbook.ActiveSheet
End Sub
It is unfortunate that in this case you need to use an Active... object. Generally it is good practice to avoid Active... objects.
You cannot do this though as the method .copy is not returning an object of the worksheet class:
Sub copySheet()
Dim ws As Excel.Worksheet
Set ws = Excel.ThisWorkbook.Sheets("Sheet1").Copy(After:=Sheets(1))
End Sub
Some further explanation is in this previous post:
Why does Worksheet.Copy not return a reference to the new workbook created
In MSDN it is not altogether obvious that the method returns nothing:
https://msdn.microsoft.com/EN-US/library/office/ff837784.aspx
...but in your friend Excel's Object Explorer it is more obvious. If it returned a worksheet object then by the arrow would read:
Sub Copy([Before], [After]) as Worksheet