I have this piece of c# code in my Excel 2003 add-in:
var leafPoint = m_worksheet.Shapes.Item("aPoint").Duplicate();
leafPoint.Name = "Shape" + (m_shapesNameIndex++).ToString();
leafPoint.OnAction = m_worksheet.CodeName + ".PointClicked";
leafPoint.AlternativeText =
string.Format("Correlation Value: {0}",
item.PointData.Correlation.ToString("0.0000;-0.0000"));
leafPoint.Top = item.LeftChildNode.Top +
((item.RightChildNode.Top - item.LeftChildNode.Top) / 2) +
(leafPoint.Height / 2);
When I run it in Excel 2003, it works perfectly. However, when I run it in Excel 2007, the shape's Top value is off... It always ends up a few pixels above the intended location!
When I looked at the logs, in Excel 2003 the shapes were consistently placed in the correct position, but in Excel 2007, when the code attempts to place the shape's Top position, Excel 2007 seems to be overriding the value for some reason (I think).
For instance, in one case the leafPoint.Top value resolved to 206.25. In Excel 2003, that was indeed the result. However, in Excel 2007, this value ends up becoming 204.2954...
Does anyone have some insight into this issue?
It's the .Duplicate function that does this. It doesn't duplicate the same .Top or .Left. My guess is the change is a result from customer feedback about not being able to find their duplicated shapes (you can duplicate manually as well be selecting the shape and click Ctrl+D.
You can just sent those to the original shape's .Top and.Left. . Here's an example in VBA:
Sub AddShapeAndDuplicate()
Dim sh As Shape
Set mysheet = Worksheets(1)
With mysheet.Shapes
Set sh = .AddShape(msoShapeRectangle, 144, 144, 72, 72)
With sh
.Name = "Red Square"
.Fill.ForeColor.RGB = RGB(255, 0, 0)
End With
End With
Dim sh2 As Shape
Set sh2 = sh.Duplicate
With sh2
.Top = sh.Top
.Left = sh.Left
End With
End Sub
I finally figured it out. Based on this link Excel 2007 Service Pack 2 – the official fix list, it mentions among the fixed bugs:
The value of the Top property of the
Line object is affected by Zoom level.
This leads to incorrect placement of
line shapes when this value is set
programmatically to lines on a sheet
that is zoomed to anything other than
100%.
I figured if the Line object was affected, possibly could there have been a problem with the Shape object as well?
So I checked my template, and indeed, it was set to 80%. (Line objects work fine, by the way, since my Excel version has SP2 installed). As soon as I set the zoom level to 100%, the shape objects suddenly rendered to the position they were expected to.
Another note: this problem only occurs during rendering. Once all the shapes have been drawn, I can set the zoom level to whatever I want, and the shapes position themselves properly.
Conclusion: whenever drawing shapes in Excel, always set the zoom level to 100%. After all the drawing is done, you can set the zoom level back to the original desired zoom.
Related
We are developing a Powerpoint VSTO Addin and need to programmatically calculate the real width and height of an Arrowhead in Powerpoint.
Our code may look like below:
freeFormShape.Line.EndArrowheadStyle = MsoArrowheadStyle.msoArrowheadTriangle;
freeFormShape.Line.EndArrowheadLength = MsoArrowheadLength.msoArrowheadShort;
freeFormShape.Line.EndArrowheadWidth = MsoArrowheadWidth.msoArrowheadNarrow;
Is there any way to know the size of End arrowhead triangle in points?
Thank you
Try using the LineFormat.Weight property which returns or sets the thickness of the specified line, in points.
Is it possible to use Excel's Camera Tool with EPPlus? that is: programatically copy a range of cells from one sheet and paste them as a drawing object into another sheet?
Update:
I noticed that Excel's Camera Tool simply creates a picture with a formula. The formula is the range of cells to be watched/observed by Excel. If any of these cells change the picture is updated by Excel.
But with EPPlus is not possible to inject a formula to a Picture object, eg:
var picture = worksheet.Drawings.AddPicture("picture", (FileInfo)null);
picture.SetPosition(1, 0, 1, 0);
picture.Formula = "A1:D9"; // ...there is no "Formula" property for ExcelPicture object
Any workaround?
Bad news when I record a VBA Macro and replay it, it doesn't work. This is the syntax thats generated:
Range("A2").Select
Selection.Copy
ActiveSheet.Shapes.AddShape(, 355.5, 32.25, 72#, 72#).Select
ActiveSheet.Shapes.Range(Array("Picture 3")).Select
Application.CutCopyMode = False
Working with Images in Excel via automation is limited. You are pretty much limited to Shapes (or shudder - clipboard):
Set shp = ws.Shapes.AddPicture("C:\You.png", msoFalse, msoTrue, l, t, w, h)
shp.Name = strPic
shp.ScaleHeight Factor:=1, RelativeToOriginalSize:=msoTrue
shp.ScaleWidth Factor:=1, RelativeToOriginalSize:=msoTrue
What I am suggesting is create a screenshot of the selected cell and workaround it that way.
'Select the cells you want to copy to image
Range("A2").Select
'Copy selected cells contents to clipboard as image
Selection.CopyPicture Appearance:=xlScreen, Format:=xlPicture
'Choose destination
Range("B3").Select
'Paste
ActiveSheet.Paste
'Restore previous clipboard to memory
Hopefully the above will be enough to help you get it working in EPPPlus.
ps Converting VBA to C# is really easy, and it should be
trivial converting the above to EPPPlus: https://stackoverflow.com/a/34055947/495455
How can one access the last-used colour in PowerPoint from within a C# VSTO Add-In?
In the example below, I am referring to the orange colour indicated by the bucket fill tool.
For Posterity
Here is the C# version of the accepted answer:
var shape = Globals.ThisAddIn.Application.ActivePresentation.Slides[1]
.Shapes.AddShape(MsoAutoShapeType.msoShapeRectangle, 0, 0, 100, 100);
shape.Select();
Globals.ThisAddIn.Application.CommandBars.ExecuteMso("ShapeFillColorPicker");
var color = shape.Fill.ForeColor.RGB;
shape.Delete();
Other than prowling the XML, which may or may not disgorge anything useful, I don't know of any way to do this via the object model, but you could draw a rectangle, invoke the button's action to color it, grab the color then delete the rectangle. Here's how you could do it in VBA:
Function GetColorBucketColor() As Long
Dim oSh As Shape
Set oSh = ActivePresentation.Slides(1).Shapes.AddShape(msoShapeRectangle, 0, 0, 100, 100)
oSh.Select
Application.CommandBars.ExecuteMso ("ShapeFillColorPicker")
GetColorBucketColor = oSh.Fill.ForeColor.RGB
oSh.Delete
End Function
In real life it's a bit more complicated than that; the color in the ShapeFill button might be a theme color or it might be a standard RGB color; this will return the RGB value. Setting other shapes to this color would produce the same appearance, but the shapes would no longer follow the theme. Sometimes that matters, sometimes not.
Another potential drawback is that for this to work, something must be selected. That means that you won't be able to do it in an invisible window, and that there'll be a bit of a blip when PPT selects the newly drawn shape.
I've got code to configure a "Freeze Pane" on my spreadsheet:
private void FreezePane(int rowNum, int colNum)
{
Excel.Range cellToFreeze = (Excel.Range)_xlSheet.Cells[rowNum, colNum];
cellToFreeze.Activate();
cellToFreeze.Application.ActiveWindow.FreezePanes = true;
}
...which I call like so:
FreezePane(DATA_STARTING_ROW, MONTH1_COL);
It works as expected; however, I find the lines Excel adds that spread from the freeze point outward a bit distracting/uglifying. Here's what the vertical one looks like, sticking out the top of the freeze point and going, probably, all the way through the stratosphere:
A horizontal line (not shown) also proceeds past the furthest column, beyond the furthest city light (to say the least).
Here's more or less what I'd like the sheet to look like (how it looks without the Freeze pane functionality):
So how can I have my freeze pane without the vertical and horizontal lines scoring the sheet with their to-infinity-and-beyond effect? Or is this a "feature" that I should learn to love, or at least live with?
Did you try using the ScrollArea properties instead^
Option Explicit
Private Sub Workbook_Open()
Worksheets("Sheet1").Activate 'Change the sheet name to whatever your sheet name is
Sheet1.ScrollArea = "A1:R28" 'Set your range to where you want the user to be able to navigate
End Sub
Let me know if that help!
I made a prototype of a module in PowerPoint 2010. The module drew some lines and shape on a PowerPoint Chart. I used PowerPoint.Point (the Data Point of a series). According to the MSDN article, Point Interface has the a Point.Left, Point.Top, Point.Height and Point.Width property. I used these properties to calculate the corner points of the each Point.
This worked fine in PowerPoint 2010.
But now due to some change in requirements I have to develop this in PowerPoint 2007 SP3. Microsoft updated the PowerPoint 2007 object model with the release of SP3 and introduced some new objects and interfaces, such as Chart, Series, Point etc. But the Point interface does not have Point.Left, Point.Top, Point.Height and Point.Width property.
I am really stuck at the moment. Is there a way I can get these properties by some other object or some other way? Can I use some other version of Office Interop Assembly dll?
You can get Top value from
powerpoint.DataLable.Top
After moving it to top with orientation property. You can do the same for the height by placing the orientation to bottom and then getting the top value. You can get the left value from
powerpoint.DataLable.Left
after moving its orientation to left. You can then calculate the right value from moving the orientation
It isn't trivial to make a demo sample from scratch to try. But have you tried to use
Point.Select()
and then get Left, Top, Width and Height of the selection (object returned by the call or ActiveWindow.Selection.ShapeRange http://msdn.microsoft.com/en-us/library/bb251483(v=office.12).aspx)?