Using named ranges with embedded formulas for excel chart data - vba

I have two drop-down menus that list a range of dates. One date identifies the beginning of the range and the other the end. I also created two named ranges as follows:
chart_Dates=INDEX(Dates,MATCH(Home!$A$7,Dates,0)):INDEX(Dates,MATCH(Home!$A$9,Dates,0))
chart_Frequency=INDEX(Frequency,MATCH(Home!$A$7,Dates,0)):INDEX(Frequency,MATCH(Home!$A$9,Dates,0))
Dates, and Frequency from those formulas are named ranges with set boundaries. If I manually enter the y-values as "Home!chart_Frequency" and the horizontal values as Home!chart_Dates the macro works just fine. I can adjust the start and end dates using the drop-down menus and the graph updates accordingly.
However, the macro recorder doesn't translate those action into code. I've attempted the following code without success (there is no error generated but the graph only references the first cell in my range).
ActiveChart.SeriesCollection(1).Values = Range("chart_Frequency")
ActiveChart.SeriesCollection(1).XValues = Range("chart_Dates")
How do I get the code to replicate what I can do manually? Any advice is greatly appreciated!

Try this:
Sub testing()
Dim freqRange As String
Dim datesRange As String
Dim Name As Variant
For Each Name In ThisWorkbook.Names
If Name.Name = "chart_Frequency" Then
freqRange = Name.Value
ElseIf Name.Name = "chart_Dates" Then
datesRange = Name.Value
End If
Next Name
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection.NewSeries
ActiveChart.FullSeriesCollection(1).Name = "=Sheet1!$B$1"
ActiveChart.FullSeriesCollection(1).Values = datesRange
ActiveChart.FullSeriesCollection(1).XValues = freqRange
End Sub
My chart didnt have any series so it adds a new series and it updates the Name, Values and XValues with no issues.

Here is the code I have right now. After it runs when I check the y-values and horizontal values on the graph itself and they are both blank.
'Create chart
Dim rng As Range
Dim cht As ChartObject
'Data range for the chart
Set rng = ActiveSheet.Range("$E$7:$F$501")
'Designates which cell to place the top left corner of the graph in
ActiveSheet.Range("N5").Select
'Create a chart
Set cht = ActiveSheet.ChartObjects.Add( _
Left:=ActiveCell.Left, _
Width:=360, _
Top:=ActiveCell.Top, _
Height:=216)
'Give chart some data
'I was using the line below to set the range but comment blocked it out and entered the suggested code
' cht.Chart.SetSourceData Source:=rng
Dim freqRange As String
Dim datesRange As String
Dim Name As Variant
For Each Name In ThisWorkbook.Names
If Name.Name = "chart_Frequency" Then
freqRange = Name.Value
ElseIf Name.Name = "chart_Dates" Then
datesRange = Name.Value
End If
Next Name
ActiveSheet.ChartObjects("Chart 1").Activate
ActiveChart.SeriesCollection.NewSeries
ActiveChart.FullSeriesCollection(1).Name = "=Home!$A$5"
ActiveChart.FullSeriesCollection(1).Values = datesRange
ActiveChart.FullSeriesCollection(1).XValues = freqRange
'Determine the chart type
cht.Chart.ChartType = xlLineMarkersStacked
'Remove Major Gridlines
cht.Chart.Axes(xlValue).MajorGridlines.Delete
'Sets the legend to the bottom of the graph
cht.Chart.SetElement (msoElementLegendBottom)
cht.Name = "Frequency_Chart"
'Add title and reference A5 for name
ActiveSheet.ChartObjects("Frequency_Chart").Activate
ActiveChart.SetElement (msoElementChartTitleAboveChart)
Application.CutCopyMode = False
Selection.Caption = "=Home!R5C1"

Related

mulit plot from different sheets in one chart with VBA

My problem is that I want to make many graph in one chart but the data is from different sheets.
At the moment my code can only take multi data from one sheet, meaning I can plot 2 graph from one sheet.
My code at the moment is:
Sub ChartSheet()
Dim ChartSheet1 As Chart
Set ChartSheet1 = Charts.Add
With ChartSheet1
.SetSourceData Source:=Sheets("Sheet1").Range("E12:E6232, Y12:Y6232")
.ChartType = xlLine
.HasTitle = True
.ChartTitle.Characters.Text = "Test Chart"
.Axes(xlCategory, xlPrimary).HasTitle = True
.Axes(xlCategory, xlPrimary).AxisTitle.Characters.Text = "x"
.Axes(xlValue, xlPrimary).HasTitle = True
.Axes(xlValue, xlPrimary).AxisTitle.Characters.Text = "y"
End With
End Sub
What I want is to say:
.SetSourceData Source:=Sheets("Sheet1").Range("E12:E6232, Y12:Y6232")
.SetSourceData Source:=Sheets("Sheet2").Range("D12:E23")
.SetSourceData Source:=Sheets("Sheet3").Range("Y12:Y6232, G27:G496, H3:5977")
and so on..
But when I do this my code it only print the last line from .SetSoureData
Hope some of you can help me work around this, Many thank in advarnce :)
Update:
I found abit of a work around by looping but this is not my total answer
But here is my other code:
Sub MultiSheetPlot()
Dim cht As Chart, s As Series, xRng As Range
Dim i As Long, chartName As String
Set cht = Charts.Add
cht.ChartType = xlLine
For i = 1 To 3
chartName = "Sheet" & i
Set xRng = Sheets("Sheet1").Range("A1:A20, C1:C20")
With cht.SeriesCollection.NewSeries()
.Values = xRng
.Name = chartName
End With
Next i
End Sub
the problem in this code is that it ignores the last range I define like the C10:C20
Responding to your latest update, I have a Sub that creates a series each time it's called from MultiSheetPlot Sub.
You can actually add more parameters to this Sub (as long as you remeber to pass them in the Calling).
Option Explicit
Dim cht As Chart
Sub MultiSheetPlot()
Set cht = Charts.Add
cht.ChartType = xlLine
' call the series creation chart function (each time for each series you want to add to the existing chart
Call Create_SeriesChart("Sheet1", Sheets("Sheet1").Range("E12:E6232"), 1, True, msoThemeColorText1)
Call Create_SeriesChart("Sheet1", Sheets("Sheet1").Range("Y12:Y6232"), 1, True, msoThemeColorText1)
End Sub
' ------ this Sub creates a series to the chart, it receives the following parameters: ------
' 1. seriesName - String
' 2. serValues - Range
' 3. lineWeight - Double (the weight of the line)
' 4. lineVis - Boolean (if you want to hide a certail series)
' 5. lineColor - MsoColorType (using the current's PC Theme colors
Sub Create_SeriesChart(seriesName As String, serValues As Range, lineWeight As Double, lineVis As Boolean, lineColor As MsoColorType)
Dim Ser As Series
Set Ser = cht.SeriesCollection.NewSeries
With Ser
.Name = seriesName
.Values = serValues
.Format.Line.Weight = lineWeight
If lineVis = True Then
.Format.Line.Visible = msoTrue
Else
.Format.Line.Visible = msoFalse
End If
.Format.Line.ForeColor.ObjectThemeColor = lineColor ' Line color Black
End With
End Sub
My solution is use Name of plage, you can give a name of your range
Like in my photo :
Everytime when you want to use these datas you just need call them
Like this plage i gived them name Poste_EtatDeLaDemande
When i want to use these elements i just call it like Range("Poste_EtatDeLaDemande") Excel will find it you don't need tell them where it is anymore ; )

Creating Charts using VBA and Sub Routines

I am creating charts using data from a tabs called Team1-Team8. I am creating the charts for each team ok but I can't get the charts into each team tab called "Team a - Charts". Below is the code i have so far for just Team A.My Parameter sheet, Column B has the names of the tabs for the charts and Column A is the Team names. Any pointers would help.
Sub LooproutineCharts()
Dim TeamName As String
Dim TeamNameCharts As String
For i = 4 To 12
TeamName = Sheets("Parameter").Range("A" & i).Value 'identify the location
TeamNameCharts = Sheets("Parameter").Range("B" & i).Value 'identify the location
Call Charts(TeamName) ' Call subroutine
Call Charts(TeamNameCharts) ' Call subroutine
Next i
End Sub
Sub Charts(TeamName As String)
'Create a Line Chart for Healthy Start Docu'
Dim lastRow As Long
Dim ws As Worksheet
Set ws = Sheets(TeamName)
With Sheets(TeamName)
lastRow = .Range("U" & Rows.count).End(xlUp).Row
With ws
ActiveSheet.Shapes.AddChart.Select
ActiveChart.ChartType = xlLineMarkers
ActiveChart.Parent.Name = "Variable A"
ActiveChart.SetSourceData Source:=.Range("S3:U" & lastRow)
ActiveSheet.Shapes("Variable A").Top = 20
ActiveSheet.Shapes("Variable A").Left = 20
ActiveSheet.Shapes("Variable A").Height = 300
ActiveSheet.Shapes("Variable A").Width = 700
ActiveChart.HasTitle = True
ActiveChart.ChartTitle.Text = "Variable A" TeamName"
End With
End With
End Sub
I would suggest updating the Charts Sub to make use of Worksheet.ChartObjects
Using the ChartObject, you can set it and won't have to reference a shape by name. It would look like this:
Sub Charts(TeamName As String)
'Create a Line Chart for Healthy Start Docu'
Dim theChart As ChartObject
Dim lastRow As Long
Dim ws As Worksheet
Set ws = Sheets(TeamName)
With ws
lastRow = .Range("U" & Rows.Count).End(xlUp).Row
Set theChart = .ChartObjects.Add(Left:=20, Top:=20, Width:=700, Height:=300)
With theChart.Chart
.ChartType = xlLineMarkers
.SeriesCollection.Add Source:=ws.Range("S3:U" & lastRow)
'.SeriesCollection(1).XValues = ws.Range("S2:U2") 'I have no idea where your xaxis is placed, or if it exist
.HasTitle = True
.ChartTitle.Text = TeamName
End With
End With
End Sub
I've taken the liberty to assume that the chart title should match the TeamName argument. I've also made it ready for the xAxis, but I have no oidea if it is relevant, or where it is placed

Excel failling to recognize type of chart

I have following code to copy all charts on one sheet into another.
Problem is that in spite of the fact that my charts have numeric(timeseries) data for horizontal axis Excel treats it as categorical. I can tell that is does that because it tries to display every single date on the axis( in spite of my code swtiching it to once a month), and once select "Format Axis" I only see fields for Categorical data( I am missing fields like Maximim, Major Unit etc.).
This is the code I am using, to be hones I copeid most of it of some forum but I cannot recall where if I do find it again I'll post a link:
Sub CopyCharts(Source As Worksheet, Target As Worksheet)
Dim SChart As ChartObject
Dim NChart As ChartObject
Dim NewSheetNChart As ChartObjects
Dim ChartTop As Single
Dim ChartLeft As Single
Dim ChartIndex As Integer
Dim ChartSeries As Series
Dim XAxis As Axis
For Each SChart In Source.ChartObjects
'Save chart's current position
ChartTop = SChart.Top
ChartLeft = SChart.Left
'Copy and paste the chart
SChart.Copy
Target.Paste
'Find the chart in a new spreadsheet
ChartIndex = ChartIndex + 1
Set NewSheetNChart = Target.ChartObjects
Set NChart = NewSheetNChart(ChartIndex)
'Align the charts
NChart.Top = ChartTop
NChart.Left = ChartLeft
'Delink sereis from source
For Each ChartSeries In NChart.Chart.SeriesCollection
ChartSeries.XValues = ChartSeries.XValues
ChartSeries.Values = ChartSeries.Values
ChartSeries.Name = ChartSeries.Name
Next ChartSeries
'Set the X axis to correct values
Set XAxis = NChart.Chart.Axes(xlCategory, xlPrimary)
With XAxis
.CategoryType = xlTimeScale
.BaseUnit = xlMonths
.MajorUnit = 1
End With
Next SChart
End Sub

out of memory error while naming chart

I am getting an "out of memory" error while trying to name a chart. I need to be able to reference this chart later in another sub program. Any help appreciated.
Sub CreateChart()
' Creates chart for the Quality sheet
Dim sBusiness As String
Dim charttype As String
Dim shChart As Worksheet
Dim num_iss As Integer
Dim i As Integer
Dim endrng As Integer
Dim currentChart As Chart
Set shChart = ThisWorkbook.Sheets("Chart Tool")
sBusiness = ThisWorkbook.Worksheets("Chart Tool").Range("select_bu").value
charttype = ThisWorkbook.Worksheets("Chart Tool").Range("select_chart").value
num_iss = ThisWorkbook.Sheets("Chart Tool").Range("num_issues").value
endrng = 31 + num_iss
' Chart Placement
shChart.Shapes.AddChart(xlColumnClustered, _
Left:=8, Top:=110, _
Width:=428, Height:=240).Select
If charttype = "Cost" Then
ActiveChart.SetSourceData Source:=shChart.Range(shChart.Cells(2, 32), shChart.Cells(3, endrng)) ' souce range
End If
If charttype = "DPM" Then
ActiveChart.SetSourceData Source:=shChart.Range(shChart.Cells(7, 32), shChart.Cells(8, endrng)) ' souce range
End If
ActiveChart.SetElement msoElementCategoryAxisShow
ActiveChart.SetElement msoElementChartTitleAboveChart ' sets chart title above
ActiveChart.SetElement msoElementLegendNone ' removes legend
ActiveChart.SetElement msoElementPrimaryCategoryAxisTitleBelowAxis ' horizontal axis
ActiveChart.SetElement msoElementPrimaryValueAxisTitleRotated ' Vertical axis
ActiveChart.ChartTitle.Caption = "Top Issues for " & sBusiness & " by " & charttype ' adds title name
ActiveChart.Axes(xlCategory, xlPrimary).AxisTitle.Caption = "Issue" ' adds x-axis title name
ActiveChart.Axes(xlValue, xlPrimary).AxisTitle.Caption = charttype ' adds y-axis title name
ActiveChart.Name = "ParetoChart"
End Sub
The chart's .Name property is Read-Only for embedded chart objects. You should be able to assign a name to the chart's parent .ChartObject.
Since the ChartObject is parent of .Chart, try:
ActiveChart.Parent.Name = "ParetoChart"

Displaying only a determined range of data

I want to display to the user certain information that exists on a separated worksheet, whenever he clicks a button.
I can set Excel to "go" to this worksheet at the starting line of the range , but I could not find a way to hide everything else.
Is there some method for this, or do I have to hide all rows and columns?
Insert a UserForm in the Workbook's VB Project.
Add a ListBox control to the userform.
Then do something like this code in the UserForm_Activate event code:
Private Sub UserForm_Activate()
Dim tbl As Range
Set tbl = Range("B2:E7") '## Change this to capture the rang you need '
Me.Caption = "Displaying data from " & _
ActiveSheet.Name & "!" & tbl.Address
With ListBox1
.ColumnHeads = False
.ColumnCount = tbl.Columns.Count
.RowSource = tbl.Address
End With
End Sub
Which gives unformatted data from the range:
To export the range as an image, you could create an Image in the UserForm instead of a Listbox. Then this should be enough to get you started.
As you can see from this screenshot, the image might not always come out very clearly. Also, if you are working with a large range of cells, the image might not fit on your userform, etc. I will leave figuring that part out up to you :)
Private Sub UserForm_Activate()
Dim tbl As Range
Dim imgPath As String
Set tbl = Range("B2:E7") '## Change this to capture the rang you need '
imgPath = Export_Range_Images(tbl)
Caption = "Displaying data from " & _
ActiveSheet.Name & "!" & tbl.Address
With Image1
If Not imgPath = vbNullString Then
.Picture = LoadPicture(imgPath)
.PictureSizeMode = fmPictureSizeModeClip
.PictureAlignment = 2 'Center
.PictureTiling = False
.SpecialEffect = 2 'Sunken
End If
End With
End Sub
Function Export_Range_Images(rng As Range) As String
'## Modified by David Zemens with
' credit to: _
' http://vbadud.blogspot.com/2010/06/how-to-save-excel-range-as-image-using.html ##'
Dim ocht As Object
Dim srs As Series
rng.CopyPicture xlScreen, xlPicture
ActiveSheet.Paste
Set ocht = ActiveSheet.Shapes.AddChart
For Each srs In ocht.Chart.SeriesCollection
srs.Delete
Next
'## Modify this line as needed ##'
fname = "C:\users\david_zemens\desktop\picture.jpg"
On Error Resume Next
Kill fname
On Error GoTo 0
ocht.Width = rng.Width
ocht.Height = rng.Height
ocht.Chart.Paste
ocht.Chart.Export Filename:=fname, FilterName:="JPG"
Application.DisplayAlerts = False
ocht.Delete
Application.DisplayAlerts = True
Set ocht = Nothing
Export_Range_Images = fname
End Function
If you record a macro and hide some columns and rows manually, the code will be produced for you, and you will see how it's done.