Using Excel VBA Combo Box to Draw A Chart From Different Sheets - excel

Okay so what I am trying to do is have a userform with a combobox that displays each sheet as an option. I got that down. I want to be able to select a sheet and draw a chart from certain ranges on said sheet on my userform. I hope that makes sense.... Here is what I have got so far. It works with the first combobox selection, but once I change sheets and try to draw a chart from a different worksheet I get an error, "Method 'Values' of object 'series' failed. Any help would be greatly appreciated. Thanks in advance =)
Private Sub ComboBox1_Change()
End Sub
Private Sub CommandButton1_Click()
If ComboBox1.Text = "Select A Client" Then
MsgBox "You Must Select a Name to Continue.", , "ERROR:Select A Name"
ComboBox1.SetFocus
Exit Sub
End If
Dim MyChart As Chart
Dim ChartData As Range
Dim chartIndex As Integer
Dim ChartName As String
chartIndex = ComboBox1.ListIndex
Select Case chartIndex
Case 1
Set ChartData = ActiveSheet.Range("L4:L103")
ChartName = ActiveSheet.Range("A1")
End Select
Application.ScreenUpdating = False
Set MyChart = ActiveSheet.Shapes.AddChart(xlXYScatterLines).Chart
MyChart.SeriesCollection.NewSeries
MyChart.SeriesCollection(1).Name = ChartName
MyChart.SeriesCollection(1).Values = ChartData
MyChart.SeriesCollection(1).XValues = ActiveSheet.Range("J4:J103")
Dim imageName As String
imageName = Application.DefaultFilePath & Application.PathSeparator & "TempChart.gif"
MyChart.Export Filename:=imageName
ActiveSheet.ChartObjects(1).Delete
Application.ScreenUpdating = True
UserForm1.Image1.Picture = LoadPicture(imageName)
End Sub
Private Sub UserForm_Click()
End Sub
Private Sub UserForm_Initialize()
Dim sht As Worksheet, txt As String
For Each sht In ActiveWorkbook.Sheets
Me.ComboBox1.AddItem sht.Name
Next sht
End Sub

The only time you are defining ChartData is if the ComboBox ListIndex is 1. Any other selection and the ChartData object will remain Nothing. Therefore when you try to set your chart values to ChartData you'll receive an error.
It's difficult to tell what you're trying to do with the Ranges. If you want to define the Range on whichever sheet is selected in the ComboBox then you're code would need to look like this:
Dim ws as Worksheet
Set ws = ThisWorkbook.Worksheets(ComboBox1.Text)
And delete your Select block.
All of your code is referencing the ActiveSheet which is probably not what you want, so you would need to replace all references to that with this new variable ws.

Related

How to Make Destination Workbook Dynamic When Moving Data From Another User Selected File Using A VBA Macro in Excel

I'm attempting to have a user select a file, then through a UserForm select the worksheet they want to copy from.
The issue is on this line: ReportWbk.Sheets(ws).Cells.Copy Destination:=TargetWbk.Sheets("Test Import").Cells(1, 1)
I have confirmed that the file, worksheet selection, and copy function all work as expected. I get a run-time error '9': Subscript out of range. which to me means that the code is looking for the destination sheet in the workbook that the user selected (the 'target' file). Since it doesn't exist there, it errors out.
I'm wondering how to fix this dynamically so that the code will work without naming the workbook specifically. I might run this with other workbooks open and in different workbooks.
I verified that workbooks("WorkbookName").Sheets("Test Import").Cells(1, 1) works as I want but I'm looking to make the "WorkbookName" part dynamic / automatically select the workbook that the macro was run from.
The main code is directly below and the userform code is below that in case that's part of the issue:
Private Sub GetRange()
Dim ReportWbk As Workbook 'workbook with report data
Dim Report As Integer 'name of file with report data
Dim FD As FileDialog
Dim TargetWbk As Workbook 'this workbook
Dim ws As Variant
Set TargetWbk = ThisWorkbook
Set FD = Application.FileDialog(msoFileDialogFilePicker)
Report = FD.Show
'cancel pressed
If Report <> -1 Then Exit Sub
'open selected workbook
Set ReportWbk = Workbooks.Open(FD.SelectedItems(1))
ws = SelectSheet.Selection(ReportWbk)
'cancel pressed
If ws = vbCancel Then GoTo exitsub
ReportWbk.Sheets(ws).Cells.Copy Destination:=TargetWbk.Sheets("Test Import").Cells(1, 1)
exitsub:
ReportWbk.Close False
'changes the color of the destination worksheet tab
Worksheets("Test Import").Tab.Color = RGB(25, 25, 25)
End Sub
UserForm Code:
Private Sub cmdOK_Click()
Me.Tag = Me.ListBox1.Value
Me.Hide
End Sub
Private Sub cmdCancel_Click()
Me.Tag = vbCancel
Me.Hide
End Sub
Function Selection(ByVal wb As Object) As Variant
Dim ws As Worksheet
For Each ws In wb.Worksheets
'add all sheets to listbox
Me.ListBox1.AddItem ws.Name
Next ws
'default - select first sheet in list
With Me.ListBox1
.ListIndex = 0
.MultiSelect = fmMultiSelectSingle
End With
Me.Show
'return result
Selection = Me.Tag
Unload Me
End Function
Private Sub UserForm_Initialize()
Me.Caption = "Select Sheet"
Me.CmdOK.Caption = "OK"
Me.cmdCancel.Caption = "Cancel"
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'disable X closing form
Cancel = CBool(CloseMode = 0)
If Cancel = -1 Then Me.Tag = vbCancel: Me.Hide
End Sub
I know this is a simple thing but I've been away from VBA for a few years and rusty as heck. Many thanks in advance!

Trying to create a excel worksheet using data from a VBA form then adding it to end of workbook

Trying to create a excel worksheet using data from a VBA form then adding it to end of workbook. Please help to activate the code
Private Sub Add_Tab_Click()
Dim txtNameSur As Worksheet
Set txtNameSur = Worksheets("Me.Textbox1")
ThisWorkbook.Sheets(1).Copy after:=Sheets(Sheets.Count)
Newname = Worksheets.Add.Name = Userform1.txtNameSur.Value
ActiveSheet.Name = Newname
End Sub
The goal in your question is a bit unclear, but I guess you meant to do something like below:
Private Sub Add_Tab_Click()
'copy first worksheet to the end of the workbook
ThisWorkbook.Worksheets(1).Copy After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)
'set the copied worksheet to a variable `NewWorksheet`
Dim NewWorksheet As Worksheet
Set NewWorksheet = ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count) 'last one is the copied one
'give it a new name (use the text in Textbox1 as name)
NewWorksheet.Name = Me.Textbox1.Text
End Sub

Combobox event not firing

I have a combobox (drop down list) that is populated with the names of all the sheets in the workbook. When I select one of them, it activates the selected sheet.
This was working until I copied it in another workbook and did some changes.
Here's the code I use to populate the combobox (which still works):
Sub fillAllCombos()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
If ws.Name <> PVTSHEET Then Call fillCombobox(ws.Name)
Next
End Sub
Sub fillCombobox(wsName As String)
Dim ws As Worksheet
Dim oCmbBox As Object
Set oCmbBox = ThisWorkbook.Sheets(wsName).Shapes("cmbSheet")
oCmbBox.ControlFormat.RemoveAllItems
For Each ws In ThisWorkbook.Sheets
oCmbBox.ControlFormat.AddItem ws.Name
Next
End Sub
Here's how I capture the event:
Sub CmbSheet_Change()
Dim oCmbBox As Object
Set oCmbBox = ActiveSheet.Shapes("cmbSheet")
With oCmbBox.ControlFormat
If .Value <> "" Then
ActiveWorkbook.Sheets(.Value).Activate
.ListIndex = 0
End If
End With
End Sub
The event-capture macros are in the sheet where the combobox is located.
In my search for answers I have also tried CmbSheet_Click()but same result.
I've named the combobox as in the image:
**Edit: Application.EnableEvents = True
It looks as if you have a Form Control Combobox. You can assign any parameter-less public sub to it, but you have to do this assignment manually. Just right-click on the control and select "Assign Macro...".
It's different for an ActiveX Control where the assignment is done via its name.

How to show excel sheet chart in excel VBA userform

I have a userform with two controls. One combobox called ComboBox1 and an image called image1. I am trying to show a chart on a sheet to this image1 during ComboBox1 change event as below
Private Sub ComboBox1_Change()
Call UpdateChart
End Sub
Private Sub UpdateChart()
Dim sTempFile As String
Dim oChart As Chart
sTempFile = Environ("temp") & "\temp.gif"
Set oChart = Worksheets(UserForm1.ComboBox1.Value).ChartObjects("Chart 1").Chart
oChart.Export Filename:=sTempFile, FilterName:="GIF"
UserForm1.Image1.Picture = LoadPicture(sTempFile)
Kill sTempFile
End Sub
This is working perfectly fine. But once I clicked on the image, ComboBox1 change event is not working anymore. In other words, the chart is not changing according to combobox change if I clicked on the image. Does anyone know why?
PS: I took the above code from some other site and modified to suit my needs.
Edit 1
ComboBox1 populating as below during Userform initialization.
Private Sub UserForm_Initialize()
With UserForm1.ComboBox1
Dim ws As Worksheet
For Each ws In Worksheets
Select Case ws.Name
Case "MainPage", "Raw Data"
Case Else
.AddItem ws.Name
End Select
Next ws
End With
End Sub
ComboBox1 values are the sheet names
Try this - adding Me.Repaint fixed it for me
Private Sub UpdateChart()
Dim sTempFile As String
Dim oChart As Chart
sTempFile = Environ("temp") & "\temp.gif"
Set oChart = Worksheets(Me.ComboBox1.Value).ChartObjects("Chart 1").Chart
oChart.Export Filename:=sTempFile, FilterName:="GIF"
Me.Image1.Picture = LoadPicture(sTempFile)
Me.Repaint '<<<<<
Kill sTempFile
End Sub
FYI within a form's code it's better to use Me instead of (eg) UserForm1 - that way you can rename the form if you need without having to edit all the code.

Prompt to close on new sheet from pivot table

I often find that with pivot tables i end up with tons of worksheets from new sheets being created via pivot table drill downs. I thought a great macro would be to display a small userform in the upper right corner of all new sheets created from pivot tables allowing the user to easily delete the sheet and return to the pivot table. However, I cant figure out how to trigger the macro. Any ideas? Basically the macro would need to be automatically triggered anytime a new sheet is created from drilling down in a pivot table.
With out getting too complex, you are probably looking for something like this...
Under "ThisWorkbook" add the following code:
EDITED
This was working for me:
Private Sub Workbook_NewSheet(ByVal Sh As Object)
If Detect_Pivot(Sh) Then
Sh.Activate
frmSheetOptions.Show
End If
End Sub
Function Detect_Pivot(wsNew As Worksheet) As Boolean
Dim wb As Workbook
Dim pvt As PivotTable
Dim bNew As Boolean
Dim i As Integer
i = 0
bNew = True
Set wb = ThisWorkbook
For Each pvt In wsNew.PivotTables
i = i + 1
s = Split(pvt.SourceData, "!")
sName = s(0)
If wsNew.Name = sName Then
bNew = False
Exit For
End If
Next
If i > 0 Then Detect_Pivot = bNew
End Function
Inside the frm you want to display:
Private Sub cmdHide_Click()
frmSheetOptions.Hide
End Sub
Private Sub cmdDelete_Click()
ActiveSheet.Delete
frmSheetOptions.Hide
End Sub
Private Sub UserForm_Initialize()
frmSheetOptions.lblSheetName = ActiveSheet.Name
End Sub
To start an event whenever a new sheet is created, you can use the following example (an answer from Tim Williams). However, I'm not sure how to tell if the new sheet was created from a pivot table. The drill-down might be an event triggered by the pivot table, in which case, maybe you can apply this method to find it. It would take some investigation.
Private WithEvents app As Excel.Application
Sub Init()
Set app = Application 'start capturing events
End Sub
Private Sub app_NewWorkbook(ByVal Wb As Workbook)
Debug.Print "New"
End Sub
Private Sub app_WorkbookBeforeClose(ByVal Wb As Workbook, Cancel As Boolean)
Debug.Print "Before close: " & Wb.Name
End Sub
Private Sub app_WorkbookOpen(ByVal Wb As Workbook)
Debug.Print "Open: " & Wb.Name
End Sub

Resources