I vainly try to set the AxisBetweenCategories property to False in a Userform ChartSpace. It is a clusteredBarChart. I did the same manually in a normal chart and it worked. Recording a Marco generated the code with the AxisBetweenCategories property. Why can't I use it in the Userform ChartSpace.
me.ChartSpace1.Charts(0).Axes(0).AxisBetweenCategories = False 'doesn't work
What do I miss?
Thanks
The "Chart" inside a ChartSpace object is of type ChChart and the same properties and methods you use on a Chart (worksheet, or chartsheet) do not translate directly so unfortunately the macro recorder won't be of much help, you will have to turn to good old fashioned debugging, trial & error.
I use the Locals window to examine the objects for a hint at the object model (that's how I observe the type is ChChart, etc.)
You can then look at the available properties and Google usually can point you in the right direction, like this example. Exploring the intellisense, I see that there are really limited options that are not the same as the Chart objects on a worksheet.
After all of that, this is probably not the answer you want to hear, but it can't be done the way you want it to be done.
This seems to verify that observation and suggests that while some things are the same, others can simply not be rendered the same way.
[Chartspace Charts do] not have the refined axis crossing as Excel
does. Features between the two will be similar in certain area and
not in others
And a similar example from Microsoft:
This example sets the category axis to cross the value axis at value zero (0) in the chart workspace.
Sub SetCrossingValue()
Dim chConstants
Dim axValueAxis
Dim axCategoryAxis
Set chtContants = ChartSpace1.Constants
Set axValueAxis = ChartSpace1.Charts(0).Axes(chConstants.chAxisPositionValue)
Set axCategoryAxis = ChartSpace1.Charts(0).Axes(chConstants.chAxisPositionCategory)
axValueAxis.CrossingAxis = axCategoryAxis
axCategoryAxis.CrossesAtValue = 0
End Sub
Related
When I create a line chart in Excel and change line style to double, I can see something similar to the image below:
As you can see the beggining and ending are rounded. I want to get rid of that, so it looks like this:
It can be done by changing line "cap type". I have tried exploring Series.Format.Line methods and properties but all I can do is modify beggining/ending arrows, there is no property/method for cap. I have also tried to use excel macro recorder to try and somehow expose this property/method but I have not been successful. I have also tried to search through various Excel/VBA forums but nothing helped.
Anyone able to help with my issue? I am looking for solution in VBA and VB.NET.
It seems that this property is not exposed in VBA, so probably you are out of luck.
According to https://social.msdn.microsoft.com/Forums/en-US/577b74db-9f9d-400c-a419-1999809922da/change-chart-data-series-line-format-cap-type-in-vba:
The cap type and join type are not exposed in the VBA object model in Excel 2007 and 2010 (I don't know about Excel 2013), so the only way to set them in VBA is using the notoriously flaky SendKeys to control the Format Data Series dialog.
The article talks about office 2010, but I coudn't find any clues that this changed later.
The object that should have this information is the Format.Line-property of a data series or data point (class is LineFormat), but it shows no cap-property.
The (not so) funny thing is that the enumeration for the possible values is available in VBA:
Try this sequence of formatting (example of formatting the first series):
Dim testSeries As Series
Set testSeries = ActiveChart.SeriesCollection(1)
With testSeries.Format.Line
.DashStyle = msoLineSquareDot
.DashStyle = msoLineSolid
.Style = msoLineThinThin
End With
I am looking for a way to reference active/selected chart data point in Excel using VBA.
Imagine I have a line chart, which I would like to add an error bar to. But, I do not want to add error bars to the whole series, but only to ONE, selected point. See the screen below:
What I want to do is to add a vertical error bar that would point down to the X-axis, something like this:
I KNOW how to do it in Excel, there are multiple ways, for example, adding a new one-point series and then adding an error bar. There are other ways. The issue I have is HOW to reference active/selected data point.
If I would choose to create a new, one point series, I need to know the point number to do that. I know (I used it) that you can reference points with Points object/method. Sadly, I do not know how to extract the selected point number, coordinates, whatever, so I can work with it later on in my project.
I cannot add any code, as everything I have done is formatting and playing with error bars, as well as iterating through existing, ALL data points (the code would have no use in this case). What I am looking for is THE selected point information, so I could refer to it as .Point(x) with x being my previously extracted point number, without being forced to reference point number right away like .Point(8) (I do not know the specific number, as I just clicked on it).
I have seen the way to extract it using chart events, but this is a an overkill for what I want to do in my little simple project (especially how to reference the "extracted" point in other macros, outside the class module).
Any ideas? All help is greatly appreciated, as I am lost after 3 days of trying to find the way to reference it.
To get the index, you can parse the point's Name, which is in the format:
S<series number>P<point number>
Sub Test()
If TypeOf Selection Is Point Then
Dim p as Point
Set p = Selection
Debug.Print CLng(Split(p.Name, "P")(1)) ' this is p's index
End If
End Sub
To get more information about that point, such as the x and y values, perhaps you could do the following:
Sub Test()
If TypeOf Selection Is Point Then
Dim p As Point
Set p = Selection
Dim i As Long
i = CLng(Split(p.Name, "P")(1))
Dim s As Series
Set s = p.Parent
Debug.Print s.Values(i) ' Values is a one-based array so you can use the point index to get its corresponding value
Debug.Print s.XValues(i)
End If
End Sub
I am trying to copy some charts (embedded) in different worksheets of an excel workbook using vbscript into different slides of a powerpoint. I would like to keep the link between the excel sheet and the powerpoint while doing so and therefore I used the below piece of code that allows me to keep formatting and link (instead of a simple paste or PasteSpeical. Is there any other way?) :
For i = 1 to TotalNumWorkSheets 'I iterated with indices.
Set pptSlide = pptPres.Slides.Add(i, 11) 'There is one opening slide before this.
set ws = wb.Worksheets(i)
ws.ChartObjects(1).Chart.ChartArea.Copy
pptApp.CommandBars.ExecuteMso("PasteExcelChartSourceFormatting")
pptApp.CommandBars.ReleaseFocus
With pptSlide
.Shapes.Title.TextFrame.TextRange.Text = objCurSheet.Name
'Adding some more textboxes here. Working fine. Position checks out in PPT.
.Shapes(.Shapes.Count).Left = 20 'Doesn't work for all slides.
End With
Next
The code works and copies all the charts, creates titles, adds new text as expected, but I am not able to position the charts on individual slides because after the ExecuteMso command, I don't know how to access the reference to the chart. I read in one of the SO posts that pasting using this method looses the chart selection but you can access the last .Shapes object since pasting always adds the object to the end of the list. Is that always the case? I tried accessing and positioning my chart by accessing the last object but it only works for the first slide of the loop (i.e. the first chart pasted is shifted to Left=20). The rest all charts in other slides are centered. Can someone explain where and how to add the formatting chart options? I ran into an even weirder problem. If I increase the number of worksheets, even the first plot looses it's Left formatting. The above code is the only place where I add formatting so I don't know what is happening. I am sure I am not formatting it correctly.
Many thanks for your suggestions.
Edit: One additional thing which I tested. I am using
WScript.Sleep 500
code before the For loop ends since it gives enough time for earlier operations to finish (at least that's what I understood from many other google searches).
So after some more searching and testing, I found a solution (for my case at least).
Moved the WScript.Sleep 1000 (500 didn't work for me) statement just below CommandBars.ReleaseFocus.
It makes some sense now since it is the Chart copying, pasting and linking from excel that needs time. Especially with source formatting. After that there is only text generation which I believe is not so heavy.
Cleared all the set Object variables when not used. Especially the ones associated with the "With" keyword.
set obj = CreateObject()
With obj
'Do something here.
End With
set obj = Nothing
Not clearing them, apparently, can also prevent you from closing the applications even after you use the .Close and .Quit method. At least that's what I observed. I found PowerPoint.exe running in the task manager when nothing was opened.
After doing the above, I am able to copy with format the charts and also able to set the position of the charts. The weird problem of larger number of worksheets also disappeared. Hopefully, it might help others. If someone thinks the observations are incorrect or troublesome, please correct.
I'm using VBA to generate an Excel sheet which includes ActiveX form controls. However the documentation available for the object properties is rather sketchy. I notice that when I create, for example, an OptionButton control, the object includes a solid white border. I can manually go into Design Mode; right-click; "Format Object", then under the "Colors and Lines" tab in the dialogue box, change Fill (Automatic) to "No Fill". See the following example:
However I have yet to work out how to do this through code. Please see the following:
Dim sht as Sheet
Set sht = [WorkbookObject].Sheets(1)
With sht
.OLEObjects.Add(ClassType:="Forms.OptionButton.1", Left:=4.5, Top:=34.5, Width:=105, Height:=15).Name = "RadioB_1"
With .OLEObjects("RadioB_1").Object
.Caption = "First Option"
.GroupName = "ColumnFilter"
.BackColor = RGB (128, 128, 128)
.BackStyle = 1
End With
' The above all works fine, however I can't find the correct property
' for the border fill. I have tried various properties for
' .OLEObjects("RadioB_1") and for .OLEObjects("RadioB_1").Object
' however I can't find the correct property.
End With
Excel's Object Browser doesn't give me much of a clue.
I have also looked at
MSDN's Article on OLE Object Properties, however there doesn't appear to be anything to address what I need.
Aha..! A lot more searching and I found the answer to my own question:
sht.OLEObjects("RadioB_1").ShapeRange.Fill.Transparency = 1
ShapeRange was listed on that MS page, however the name of it is misleading, and there is still nowhere in official documentation which actually lists all the properties and what they do! Anyway - I decided to post the answer to my own question for the benefit of anyone looking for this in future.
I know that using Activate and Select in Excel VBA is not best practice. I've seen references on how to avoid them when dealing with Ranges (example: LINK). How can I avoid them when dealing with ChartObjects (or anything other than Ranges, in general)?
For instance, a way to modify the maximum value on the y-axis using Activate and Select would look something like this (which works):
ActiveSheet.ChartObjects("MyChart").Activate
ActiveChart.Axes(xlValue).Select
ActiveChart.Axes(xlValue).MaximumScale = Range("MaxVal").Value
In order to avoid using Activate and Select, I tired to declare variables, and work with those, but that does not work:
Dim ws As Worksheet
Set ws = Worksheets("Chart")
With ws.ChartObjects("MyChart").Axes(xlValue)
.MaximumScale = Range("MaxVal").Value
End With
The code above runs (i.e. does not throw an error), but the scale on the axis does not change. What am I missing?
EDIT: Got it to work with this "longwinded" version:
With Worksheets("Chart").ChartObjects("MyChart").Chart.Axes(xlValue)
.MaximumScale = Range("MaxVal").Value
End With
As for your question #1: How can I avoid them when dealing with ChartObjects (or anything other than Ranges, in general)?, the method you use is correct. Your conclusion that does not work is brought about by the other error.
As for your question #2: What am I missing?, a ChartObject does not have a method Axes.
What you called the "longwinded" version is actually the way to do it.
PS: The only reason I can think about for the non-working code to run with no error is an error handler that ignores the error.
I get the expected "Run-time error '438': Object doesn't support this property or method".
This finally worked:
With Worksheets("Chart").ChartObjects("MyChart").Chart.Axes(xlValue)
.MaximumScale = Range("MaxVal").Value
End With