Excel VBA Course
Excel VBA Course - From Beginner to Expert

200+ Video Lessons
50+ Hours of Video
200+ Excel Guides

Become a master of VBA and Macros in Excel and learn how to automate all of your tasks in Excel with this online course. (No VBA experience required.)

View Course

Don't understand Object required error in macro

0

Hello,

I am creating a macro to open a file and create a chart automatically. I started by using Record Macro to get the general steps I needed. I then added code at the beginning to have the user select the file (thanks to TeachExcel for showing me how to do that!). Now when I run it, I get an Object required error at a step in the recorded part when I changed the y-axis label. The bolded line is where the error is occuring. Would appreciate some help understanding what I'm doing wrong!

thanks!

Sub GenerateChart()
'
' GenerateChart Macro
'
' First get the filename from the user
 userSelectedFile = Application.GetOpenFilename
    ' Check if the user selected a file.
    ' - False is returned if the user did not select a file.
 If userSelectedFile = False Then
    ' If here, means that no file was selected.
   MsgBox "No file selected."
 Else
    ' If here, a file was selected and it will be contained within the variable that
    ' we used above, userSelectedFile.
    ' Open the file here or do whatever you want with it.
   MsgBox "File selected: " & userSelectedFile
'
   Workbooks.OpenText Filename:=userSelectedFile _
        , Origin:=437, StartRow:=1, DataType:=xlDelimited, TextQualifier:= _
        xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, Semicolon:=False, _
        Comma:=True, Space:=True, Other:=True, OtherChar:="]", FieldInfo:= _
        Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), Array(7 _
        , 1), Array(8, 1), Array(9, 1), Array(10, 1)), TrailingMinusNumbers:=True
    Range("A:A,C:C").Select
    Range("C1").Activate
    ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select
    ActiveChart.SetSourceData Source:=Range("LOG_TDK!$A:$A,LOG_TDK!$C:$C")
    ActiveChart.SetElement (msoElementPrimaryCategoryAxisTitleAdjacentToAxis)
    ActiveChart.SetElement (msoElementPrimaryValueAxisTitleAdjacentToAxis)
    ActiveChart.Axes(xlValue, xlPrimary).AxisTitle.Text = "Seconds"
    Selection.Format.TextFrame2.TextRange.Characters.Text = "Seconds"
    With Selection.Format.TextFrame2.TextRange.Characters(1, 7).ParagraphFormat
        .TextDirection = msoTextDirectionLeftToRight
        .Alignment = msoAlignCenter
    End With
    With Selection.Format.TextFrame2.TextRange.Characters(1, 7).Font
        .BaselineOffset = 0
        .Bold = msoFalse
        .NameComplexScript = "+mn-cs"
        .NameFarEast = "+mn-ea"
        .Fill.Visible = msoTrue
        .Fill.ForeColor.RGB = RGB(89, 89, 89)
        .Fill.Transparency = 0
        .Fill.Solid
        .Size = 10
        .Italic = msoFalse
        .Kerning = 12
        .Name = "+mn-lt"
        .UnderlineStyle = msoNoUnderline
        .Strike = msoNoStrike
    End With
    ActiveChart.Axes(xlCategory).AxisTitle.Select
    ActiveChart.Axes(xlCategory, xlPrimary).AxisTitle.Text = "Days"
    Selection.Format.TextFrame2.TextRange.Characters.Text = "Days"
    With Selection.Format.TextFrame2.TextRange.Characters(1, 4).ParagraphFormat
        .TextDirection = msoTextDirectionLeftToRight
        .Alignment = msoAlignCenter
    End With
    With Selection.Format.TextFrame2.TextRange.Characters(1, 4).Font
        .BaselineOffset = 0
        .Bold = msoFalse
        .NameComplexScript = "+mn-cs"
        .NameFarEast = "+mn-ea"
        .Fill.Visible = msoTrue
        .Fill.ForeColor.RGB = RGB(89, 89, 89)
        .Fill.Transparency = 0
        .Fill.Solid
        .Size = 10
        .Italic = msoFalse
        .Kerning = 12
        .Name = "+mn-lt"
        .UnderlineStyle = msoNoUnderline
        .Strike = msoNoStrike
    End With
    ActiveChart.ChartTitle.Select
    ActiveChart.ChartTitle.Text = "Therapy by Days"
    Selection.Format.TextFrame2.TextRange.Characters.Text = "Therapy by Days"
    With Selection.Format.TextFrame2.TextRange.Characters(1, 15).ParagraphFormat
        .TextDirection = msoTextDirectionLeftToRight
        .Alignment = msoAlignCenter
    End With
    With Selection.Format.TextFrame2.TextRange.Characters(1, 15).Font
        .BaselineOffset = 0
        .Bold = msoFalse
        .NameComplexScript = "+mn-cs"
        .NameFarEast = "+mn-ea"
        .Fill.Visible = msoTrue
        .Fill.ForeColor.RGB = RGB(89, 89, 89)
        .Fill.Transparency = 0
        .Fill.Solid
        .Size = 14
        .Italic = msoFalse
        .Kerning = 12
        .Name = "+mn-lt"
        .UnderlineStyle = msoNoUnderline
        .Spacing = 0
        .Strike = msoNoStrike
    End With
    Range("P21").Select
    ActiveWorkbook.SaveAs Filename:= _
        userSelectedFile, FileFormat:= _
        xlOpenXMLWorkbook, CreateBackup:=False
  End If
End Sub
Post Edited
CODE Tags: You must add [CODE][/CODE] tags around your code! (click the CODE button to do this when creating a post)
Answer
Discuss

Answers

0
Selected Answer

When you record a macro, Excel will not qualify the objects it creates. A range is "qualified" by stating on which worksheet it exists, and a worksheet is "qualified" when the code specifies the workbook that it is in. A range is therefore "fully qualified" when both sheet and book are specified. In the absence of qualification Excel assumes the ActiveSheet which is always in the ActiveWorkbook.

When you let your code open another workbook Excel will make that new workbook the ActiveWorkbook and one of the worksheets in this workbook - by default the first one - will become the ActiveSheet. All your previously recorded code with unqualified ranges will now refer to the new ActiveSheet. Of course, there is no Shape on the substituted ActiveSheet. Therefore no Chart gets extracted from that non-existent Shape, and next time your code refers to the ActiveChart no such object exists, which is why we are here.

Below is the first part of your macro, reformated and comments added. As you see, at the end, I activated ThisWorkbook - the one containing the code - in the assumption that that was the ActiveWorkbook when you created the code. I didn't bother to activate the original worksheet because Excel will remember that sheet when the book is activated. Therefore your code should work again as it did before you added the new workbook. I couldn't test.

Sub GenerateChart()
    ' GenerateChart Macro

    Dim userSelectedFile    As Variant
    Dim NewBook             As Workbook

    ' First get the filename from the user
    userSelectedFile = Application.GetOpenFilename

    ' Check if the user selected a file.
    If userSelectedFile = False Then
        ' - False is returned if the user did not select a file.
        MsgBox "No file selected."
        Exit Sub
    End If          ' moved here from the bottom of the code


'    Else           ' remove this

    ' If here, a file was selected and it will be contained within the variable that
    ' we used above, userSelectedFile.
    ' Open the file here or do whatever you want with it.
    MsgBox "File selected: " & userSelectedFile

    Workbooks.OpenText Filename:=userSelectedFile, _
                       Origin:=437, StartRow:=1, _
                       DataType:=xlDelimited, _
                       TextQualifier:=xlDoubleQuote, _
                       ConsecutiveDelimiter:=True, Tab:=False, Semicolon:=False, _
                       Comma:=True, Space:=True, Other:=True, OtherChar:="]", _
                       FieldInfo:=Array(Array(1, 1), Array(2, 1), Array(3, 1), _
                                  Array(4, 1), Array(5, 1), Array(6, 1), Array(7, 1), _
                                  Array(8, 1), Array(9, 1), Array(10, 1)), _
                                  TrailingMinusNumbers:=True

    ' the newly opened workbook is now the ActiveWorkbook
    ' all following ranges are not qualified (= no sheet specified).
    ' Therefore they are specified for for the ActiveSheet, which,
    ' at this moment, is the first sheet of the new workbook.

    ' However, the next two lines are without purpose: Delete them
    Range("A:A,C:C").Select         ' select columns A and C - Why?
    Range("C1").Activate            ' Activate C1 - Why?

    ' This is the source of your problem:
    ' ====  ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select  ====
    ' the ActivweSheet is in the new workbook.
    ' Therefore:- (2 new lines of code)
    Set NewBook = ActiveWorkbook
    ThisWorkbook.Activate

    ' and continue with your recorded code
    ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select

Of course, now the new workbook exists and is open but no longer visible. I added a spare variable NewBook at the top of my snippet and assigned the newly opened workbook to it. Now you can switch between workbooks using NewBook.Activate and ThisWorkbook.Activate.

Actually, the very next thing you should now learn is not to do that. The macro recorder can't read your mind and therefore reads from your fingers as you type, and that leads to Activate and Select and code like this.

NewBook.Activate
Worksheets("Sheet1").Activate
Range("A:A").Select
Range("A2").Activate
MsgBox "Selected cell's value = " & ActiveCell.Value

The point is that the macro recorder needs to read your fingers but your fingers can express what's on your mind. Therefore you can replace the above with the one line here following.

MsgBox "Designated cell's value = " & NewBook.Worksheets("Sheet1").Range("A2").Value

Any recorded code should therefore be cleansed of all uses of the Selection object and the Select and Activate statements needed to create it. A worksheet doesn't need to be visible (activated) in order to be addressed for reading or writing. Replace the Selection object with Range objects.

Discuss

Discussion

I added in your suggestions and now am getting a new error: "Method 'Range' of object '_Global' failed.
Debug shows it to occur at the line where I SetSourceData and it looks like it's trying to put my chart in the workbook where the code is instead of the new workbook even though I just opened the workbook.
[CODE]
..code deleted due to limit on comment         Workbooks.OpenText Filename:=userSelectedFile _         , Origin:=437, StartRow:=1, DataType:=xlDelimited, TextQualifier:= _         xlDoubleQuote, ConsecutiveDelimiter:=True, Tab:=False, Semicolon:=False, _         Comma:=True, Space:=True, Other:=True, OtherChar:="]", FieldInfo:= _         Array(Array(1, 1), Array(2, 1), Array(3, 1), Array(4, 1), Array(5, 1), Array(6, 1), Array(7 _         , 1), Array(8, 1), Array(9, 1), Array(10, 1)), TrailingMinusNumbers:=True         Set NewBook = ActiveWorkbook     ThisWorkbook.Activate          ActiveSheet.Shapes.AddChart2(201, xlColumnClustered).Select     ActiveChart.SetSourceData Source:=Range("LOG_TDK!$A:$A,LOG_TDK!$C:$C")     ActiveChart.SetElement (msoElementPrimaryCategoryAxisTitleAdjacentToAxis)
....  additional code deleted because of limit on comment  /code
bjgaston (rep: 2) Jul 6, '21 at 2:54 pm
I got it working by removing the line ThisWorkbook.Activate. Now I have a question on my attempt to save the opened file as an Excel workbook. I'm using this 
ActiveWorkbook.SaveAs Filename:= _
        userSpecifiedFile, FileFormat:= _
        xlOpenXMLWorkbook, CreateBackup:=False

..which opens a dialog box and lets me type in the name but in get an .xlsx I have to add that to the name. the Type dropdown only has *.* and if I don't put in the extension it saves it with no type. 
bjgaston (rep: 2) Jul 6, '21 at 3:10 pm
Hi BJ,
I don't do follow-ups. If you have a further question please ask another question. But please also don't forget to deal with this thread properly. If you got an answer that was helpful please mark it as "Selected". This is the way for you to share your experience with other visitors to this forum.
Variatus (rep: 4889) Jul 6, '21 at 8:44 pm
Add to Discussion


Answer the Question

You must create an account to use the forum. Create an Account or Login