Position a shape in Excel based on its center point - excel

Is it possible to position a shape by its center point?
I'm trying to overlay shapes onto a picture of a map in Excel and adjust the size of the shapes based on the value in a cell.
I have the sizing portion figured out, but every time my shapes size increases it slowly starts to move to the right and bottom due to the positioning of its left and top. I would like it if the positioning of my circles would not moved once the data gets refreshed. I only want the size of the shape to be altered.
Any thoughts?

If you know the X/Y (really Left/Top, since {0,0} is upper left) where you want to put it, it is as simple as subtracting off half the size of the shape to get the center to be there.
Here is some simple code which puts the center of a circle at the corner of cell E8. I assume you have some way of selecting the shape based on your question.
Sub PositionByCenter()
Dim dbl_x As Double
Dim dbl_y As Double
'select a cell just to put it somewhere
dbl_x = Range("E8").Left
dbl_y = Range("E8").Top
'grab a reference to a shape
Dim shp As Shape
Set shp = Selection.ShapeRange.Item(1)
'position by the center
shp.Top = dbl_y - shp.Height / 2
shp.Left = dbl_x - shp.Width / 2
End Sub
Here is what you get after running that with a circle selected.

Related

Excel 2016 and newer VBA: how to maximize a chart within/to the worksheet size?

In https://i.stack.imgur.com/s6gII.png and How to get the size (width and height) of the area with excel vsto c# excluding the ribbon area? a similar question has already been put.
Excluding all GUI elements outside/around the "inner/client" worksheet area, e.g. without the ribbon, "X/ok/fx" + cell contents, Sheet menu, "Ready + Record Macro" footer line + frame heights, left + right border + frame widths, etc.
And together with How to get the screen position of an active workbook? neither of these links has answered my needs yet. Or their instructions do not work for me, because neither of the .PageSetup.*Margin values corresponds to my worksheet "inner/client" OR "outside/GUI" borders + frames + overhead sizes.
I know, by writing
With ActiveChart.Parent 'access the chart container = the Shape
.Left = 0
.Top = 0
.Width = 4 * 72 'fixed size example
.Height = 3 * 72 'fixed size example
End With
I can set the chart position + size, in this example to a fixed size of 3 * 4 inches.
But HOW TO GET/fetch the whole currently visible dynamic worksheet "inner/client" size (at least once a method call) ?
In order to set the chart size, so that it covers/uses the whole currently visible dynamic worksheet "inner/client" size (at least once a method call). Hopefully: nothing more (no scrollbars shifting needed to see the whole chart), nothing less (no unneccessary "tiny" chart) ?
[I know, that size assignment will work for me only "for a moment" until a workbook resize happens. So I'll have to adjust the chart size again (and again (and again ...)), e.g. by using a timer (or a system timer). Or is there some "anchor/chain/nail" chart property, so that it ALWAYS keeps up with the "inner/client" worksheet size (within the workbook) ?]
Thanks for your help
This is about as good as you can do.
Sub SizeChartToWindow()
Dim VisibleRange As Range
Set VisibleRange = ActiveWindow.VisibleRange
Dim UsableRange As Range
Set UsableRange = VisibleRange.Resize(VisibleRange.Rows.Count - 1, _
VisibleRange.Columns.Count - 1)
With ActiveChart.Parent
.Left = UsableRange.Left
.Top = UsableRange.Top
.Width = UsableRange.Width
.Height = UsableRange.Height
End With
End Sub
Many thanks, that helped me a lot.
This also takes care of the worksheet scrollbars "scrolled away", wonderful.
And the right + bottom remainder of 0.00 .. 0.99 * cell sizes is "good enough" (and I have reduced the cell width to match the cell height = 20 pixels in order to reduce that remainder effect).
:)))

Resize Chart Right to Left

I need help please in resizing Excel charts to expan right versus the standard expanding left.
I input the vba code below to each chart to resize and it works fine, except for the charts of the right side of the workbook, it expands off the screen and I don't want to have to scroll right.
How can I modify the code so that it expands left versus rt?
Thanks!
Sub Chart140_Click()
With ActiveSheet.ChartObjects(Application.Caller)
If .Height = (ThisWorkbook.Sheets("configuration").Range("chrtrngzoominh")) Then
.Height = Format(ThisWorkbook.Sheets("configuration").Range("chrtrngzoomouth"))
.Width = Format(ThisWorkbook.Sheets("configuration").Range("chrtrngzoomoutw"))
Else
.Height = Format(ThisWorkbook.Sheets("configuration").Range("chrtrngzoominh"))
.Width = Format(ThisWorkbook.Sheets("configuration").Range("chrtrngzoominw"))
End If
End With
End Sub
Excel charts are positioned with the top left corner. If you want to change the size of a chart and and anchor the right hand side, you will need to use a workaround along these lines:
save the initial chart position of the top left into variables
save the initial chart width into a variable
increase the chart width
calculate the width difference between initial and the new width
adjust the top left position by the width difference

Various transparent step in a line in a chart

I am using VBA with Excel 2013. I am developing a Macro with a chart, inside the chart there is a line made with a serie if points. I need apply a transparency shape to the steps between 2 point.
example
1 to 2 solid
2 to 3 transparent
3 to 4 solid
With .transparency = 0 and 1 the shape is applied to the whole line. I tryed to apply .trasnparency various time but it is applied to the whole line.
How do I apply transparency to have the behauvior described above?
The easiest way to get a gap is to insert a blank row between segments you want to be visible. In the top view below the data range is continuous, and so is the chart. In the bottom view, I've inserted blank rows between the X-Y values for the horizontal segments, and the chart rewards me with gaps in the plot, so the verticals don't show up.
You can't get these gaps if your code is inserting arrays into the chart series source data, but you can use code like this to make them disappear (by using No Line instead of Transparency, personal preference):
Sub TransparentVerticals()
Dim srs As Series
Dim iPt As Long
Set srs = ActiveChart.SeriesCollection(1)
For iPt = 1 To srs.Points.Count Step 2
With srs.Points(iPt)
.Format.Line.Visible = msoFalse
End With
Next
End Sub

Shape adjustment in excel 2010

I insert a shape of type rounded rectangular callout at run time and initially its pointer's direction is downward.If i check its value using
shp.Adjustments.Item(1)
code then it shows its value -0.20833
I want to change its direction to upward.I recorded a macro to adjust that and got this code
Selection.ShapeRange.Adjustments.Item(1) = -0.20223
But still its direction is downward.
Please help to set its direction to upward.
I would suggest just rotating the shape 180 degrees on the y axis. This rotates the shape, but as you note it also rotates the text which may not be desirable.
shp.ShapeRange.ThreeD.RotationY = -180
If you simply want to adjust the pointer from the callout, this is Item(2). When I create a shape, it has a value like:
shp.Adjustments.Item(2) = 0.625
To reverse its location, so that it is on the top of the rectangle, change it to:
shp.Adjustments.Item(2) = -0.625

How to plot chart values outside axis maximum?

In previous versions of Excel there was a registry entry that you could create to allow Excel to display values/labels that would be positioned outside the axis min/max using QFE_Bonn dword=1. This is what I have used for Excel 2003: Plot lines that contain labels disappear ...)
I have not been able to find a similar patch or native functionality in Excel 2010 (Office Pro Plus). Any ideas how this can be accomplished, or did MS remove this functionality altogether?
Here are screenshots of examples in Excel 2003. I create a series of data which uniformly exceeds the y-axis maximum. This series' color fill has been removed already
To finish the look, remove the series' border so that it appears invisible. Then replace the series' value labels with the relevant data.
There is a workaround using the DataLabels.Left property which positions the DataLabel relative to the ChartArea.
Here is an example VB solution:
sub FakeLabels()
Dim sF As Double
Dim lOff As Double
Dim p As Double
ActiveSheet.ChartObjects(1).Activate
With ActiveChart
For sF = 1 To .SeriesCollection.Count
If .SeriesCollection(sF).Name = "FakeSeries" Then
'Define the lOff variable by adding 100, or some other value
lOff = .SeriesCollection(sF).Points(1).DataLabel.Left + 100
For p = 1 To .SeriesCollection(sF).Points.Count
.SeriesCollection(sF).Points(p).DataLabel.Left = lOff
Next p
End If
Next sF
End With
It yields the same results, the only new requirement is to keep the values for the "dummy" series within the axis min/max values for the chart.
A pleasant surprise is that re-sizing the chart doesn’t appear to affect the relative placement of the labels.
UPDATED 9-25-2013
I have used the "textbox" approach since first asking this question. But it is extremely clunky to manage the interplay between the labels' position and the textbox positions, their relative position of the PlotArea i.e., when to use .InsideWidth vs. .Width or .InsideLeft vs. .Left and whether there needs to be any sort of hedonic "adjustments" to the points values, as always seem to be the case, they are never quite perfectly aligned.
While perusing the PPT object model reference for some other chart-related inquiries, I stumbled upon this property which appears to replicate the functionality of the previous hotfix/registry hack.
.ShowDataLabelsOverMaximum

Resources