Resize plot area in embedded chart object - excel

I have problem resizing plot area in an embedded chart in excel
Dim myChart As Chart
maxPie = ThisWorkbook.Sheets(sheetName).Range("A1048576").End(xlUp).Row
Set myChart = ThisWorkbook.Sheets(sheetName).Shapes.AddChart.Chart
myChart.ChartType = xlBarClustered
myChart.SetSourceData Source:=Range(sheetName & "!$A$5:$C$" & maxPie)
With myChart.Parent
.Top = 10
.Left = 500
.Width = 500
.Height = 500
End With
With myChart.PlotArea
.Top = 70
.Height = 420
End With
if i press debug and then F5 then it resizes it, do I need to add a delay in my code because its not finished generating the plot area before I try to resize it

The comment Rory made about reading the value solved the issue, strange that this is needed though..
Dim temp As Integer
With myChart.PlotArea
temp = .Top
temp = .Height
.Top = 70
.Height = 420
End With

I think the problem why your code return error because PlotArea properies can only be modify after the Chart object if fully loaded. So yes, you need to complete Chart Object loading process and modify any PlotArea properties.
The code below will work. Try it..!
Option Explicit
Public Sub Demo()
Dim maxPie As Long
Dim myChart As Chart
'I assume that your chart is on Sheet1
maxPie = Sheet1.Range("A1048576").End(xlUp).Row
Set myChart = Sheet1.Shapes.AddChart2.Chart
With myChart
.ChartType = xlBarClustered
.SetSourceData Source:=Range("Sheet1!$B$2:$C$" & maxPie)
End With
With myChart.Parent
.Top = 10
.Left = 500
.Width = 500
.Height = 500
End With
'Delay the SetPlotArea code execution using OnTime function
Application.OnTime Now, "SetPlotArea", Now + TimeValue("0:0:5")
End Sub
Public Sub SetPlotArea()
Dim ch As Chart
Set ch = Sheet1.ChartObjects(1).Chart
ch.PlotArea.Top = 70
ch.PlotArea.Height = 420
End Sub

Related

Mac - Copy/paste charts from Excel to Powerpoint via VBA (Excel/PPT V.16.35)

Hi I am trying to copy Charts from an Excel Sheet and paste them in an Powerpoint Slide.
I've tried two ways of implementing it in VBA.
1.Option:
failed - doesn't support property or method > PasteSpecial.
For i = 1 To 10
ppFile.Slides(i + 1).Select
Worksheets("Darstellung").ChartObjects(i).CopyPicture
Set objShape = ppFile.Slides(i + 1).Shapes.PasteSpecial(Datatype:=ppPasteDefault)'<<< problem in this line
With objShape
.LockAspectRatio = msoFalse
.ScaleWidth 1.5, msoTrue
.ScaleHeight 1.9, msoFalse
.Top = 100
.Height = 350
.Width = 700
.Left = 150
End With
Set objShape = Nothing
Next
2.Option:
semi failed - works but needs 1 and half minute to paste one chart and throws exception: "excel is waiting for another application to complete an ole action" after every chart. Clicking ok lets the VBA run and paste the next chart.
For i = 1 To 10
ppFile.Slides(i + 1).Select
Worksheets("Darstellung").ChartObjects(i).CopyPicture
Set objShape = ppFile.Slides(i + 1).Shapes.Paste '<<< problem in this line
With objShape
.LockAspectRatio = msoFalse
.ScaleWidth 1.5, msoTrue
.ScaleHeight 1.9, msoFalse
.Top = 100
.Height = 350
.Width = 700
.Left = 150
End With
Set objShape = Nothing
Next
Is there any way to implement it on Mac, so it runs properly and efficient?

Edit legend using VBA

I copied chart (this chart with legend I prepared in excel) from excel to .ppt (below code). How can I change/edit legend.Top and legend.size?
My code is not working...
Sub pptfromexcel()
Dim pptapp As PowerPoint.Application
Dim pptppt As PowerPoint.Presentation
Dim pptsld As PowerPoint.Slide
Dim shp As Object
Set chart1 = ActiveSheet.ChartObjects("Chart 1")
'Dane do wykresów
Set d5 = Sheets("Wykresy").Range("Q32:S40")
Set d6 = Sheets("Wykresy").Range("Q47:S51")
Set v1PK = Sheets("Wykresy").Range("G7:G7")
Set v1PM = Sheets("Wykresy").Range("G8:G8")
Set pptapp = New PowerPoint.Application
Set pptppt = pptapp.Presentations.Open("C:\Users\Desktop\ppt.pptx")
pptapp.Visible = True
pptapp.Activate
Set pptsld2 = pptppt.Slides(2)
chart1.Copy
Set chart1a = pptsld2.Shapes.PasteSpecial
With chart1a
.Height = 132
.Width = 157
.Left = 26.1
.Top = 120
.haslegend=true
.legend.size = 12
.legend.top = 150
End With
End Sub
The first four properties your are setting are generic properties for all shapes. The legend properties are specific for a chart. The first thing that must happen is that it is pasted as an Excel object. If that is the case, you have a Chart property on your shape and you can do like this:
With chart1a
.Height = 132
.Width = 157
.Left = 26.1
.Top = 120
.Chart.HasLegend = True
.Chart.Legend.Size = 12
.Chart.Legend.Top = 150
End With

Copying image between the sheets with instant resizing & adjusting

I have got a problem.
I would like to copy the image between the Excel sheets and have it adjusted at once to the cells.
So far I managed perfectly with adjustment on the 1 sheet
Sub signature()
Dim myImage As Shape
Dim imageWidth As Double
Dim imageHeight As Double
Set myImage = ActiveSheet.Shapes("Picture 13")
imageWidth = 170
imageHeight = 65
myImage.LockAspectRatio = msoFalse
myImage.Width = imageWidth
myImage.Height = imageHeight
'x:
myImage.Left = myImage.Left + 650
'y:
myImage.Top = myImage.Top - 70
End Sub
Which looks like this:
To the image is assigned the ID, as shown below:
Now, I want to copy this image into another 2 sheets, which can be done by this solution:
Sub signature_copy()
Sheets("Sign Off Sheet").Shapes("Picture 13").Copy
Sheets("BoQ Civils").Range("C43").PasteSpecial
Sheets("BoQ Cabling").Range("C37").PasteSpecial
End Sub
Everything would be fine, but I am receiving an image of the same size.
It has to be fitted with the cells. Technically it's feasible by using the code above and changing the shape ID into the new one copied. Unfortunately, I can't do this, since I would like to use one image and make it copied & resized instantly in all sheets.
What should I do to receive this goal?
Sheets("Sign Off Sheet").Shapes("Picture 13").Copy
Sheets("BoQ Civils").Range("C43").PasteSpecial
Work with Objects. It will be easier to handle them
Try this
Option Explicit
Sub Sample()
Dim shpA As Shape, shpB As Shape
Dim rng As Range
Set shpA = Sheets("Sign Off Sheet").Shapes("Picture 13")
shpA.Copy
Set rng = Sheets("BoQ Civils").Range("C43")
Sheets("BoQ Civils").Paste Destination:=rng
Set shpB = Sheets("BoQ Civils").Shapes("Picture 13")
With shpB
.Top = rng.Top
.Left = rng.Left
.Width = rng.Width
.Height = rng.Height
End With
End Sub
Edit: If the shape name is getting renamed after copying it across then use Sheets("BoQ Civils").Shapes.Count to work with the shape as #Plutian suggested in the chat
Set shpB = Sheets("BoQ Civils").Shapes(Sheets("BoQ Civils").Shapes.Count)
You can create a resize function
Sub Example2()
SizeToRange ActiveSheet.Pictures("Picture 13"), Range("C43:D43")
End Sub
Function SizeToRange(s, Target As Range)
s.Left = Target.Left
s.Top = Target.Top
s.Width = Target.Width
s.Height = Target.Height
End Function
You could use the .Scaleheight method to scale by the height of the target cell. This will keep the aspect ratio of the picture while resizing with the height of the cell. By the looks of your picture, the target cell might be wider or narrower than you want your picture to be.
Sub signature_copy()
Dim sh As Shape
Sheets("Sign Off Sheet").Shapes("Picture 13").copy
Sheets("BoQ Civils").Range("C43").PasteSpecial
Set sh = Sheets("BoQ Civils").Shapes(Sheets("BoQ Civils").Shapes.Count)
With sh
.ScaleHeight Factor:=(.TopLeftCell.Height / .Height), RelativeToOriginalSize:=msoTrue
End With
End Sub

Ungroup buttons (shapes) using VBA

I use the following VBA to insert two buttons into my Excel sheet and group them together:
Sub Insert_Buttons()
Sheet1.Select
Dim Button_01 As Button
Set Button_01 = Sheet1.Buttons.Add(423.75, 0, 48, 15)
Dim Range_Button_01 As Range
Set Range_Button_01 = Sheet1.Range("B6:D7")
Button_01.Name = "Button_01"
With Button_01
.Top = 30
.Left = 76
.Width = 50
.Height = 20
.Text = "Button_01"
End With
Sheet1.Select
Dim Button_02 As Button
Set Button_02 = Sheet1.Buttons.Add(423.75, 0, 48, 15)
Dim Range_Button_02 As Range
Set Range_Button_02 = Sheet1.Range("B6:D7")
Button_02.Name = "Button_02"
With Button_02
.Top = 5
.Left = 76
.Width = 50
.Height = 10
.Text = "Button_02"
Sheet1.Shapes.Range(Array("Button_01", "Button_02")).Group
End Sub
All this works perfectly.
However, now I want to use another VBA to ungroup the buttons which I inserted with the above VBA. Therefore, I tried to go with the following:
Sub Ungroup_Buttons()
Sheet1.Shapes.Range(Array("Button_01", "Button_02")).Ungroup
End Sub
However, with this VBA I get runtime error 1004.
What do I need to change in my code so I can ungroup the buttons?
Maybe give this a try :
Sub Ungroup_Buttons()
Set ButtonList = Sheet1.Shapes.Range(Array("Button_01", "Button_02")).Group
ButtonList.Name= "ListToUnGroup"
Sheet1.Shapes.Range("ListToUnGroup").Ungroup
End Sub

How to insert a picture into Excel at a specified cell position with VBA

I'm adding ".jpg" files to my Excel sheet with the code below :
'Add picture to excel
xlApp.Cells(i, 20).Select
xlApp.ActiveSheet.Pictures.Insert(picPath).Select
'Calgulate new picture size
With xlApp.Selection.ShapeRange
.LockAspectRatio = msoTrue
.Width = 75
.Height = 100
End With
'Resize and make printable
With xlApp.Selection
.Placement = 1 'xlMoveAndSize
'.Placement = 2 'xlMove
'.Placement = 3 'xlFreeFloating
.PrintObject = True
End With
I don't know what I am doing wrong but it doesn't get inserted into the right cell, so what should I do to put this picture into a specified cell in Excel?
Try this:
With xlApp.ActiveSheet.Pictures.Insert(PicPath)
With .ShapeRange
.LockAspectRatio = msoTrue
.Width = 75
.Height = 100
End With
.Left = xlApp.ActiveSheet.Cells(i, 20).Left
.Top = xlApp.ActiveSheet.Cells(i, 20).Top
.Placement = 1
.PrintObject = True
End With
It's better not to .select anything in Excel, it is usually never necessary and slows down your code.
Looking at posted answers I think this code would be also an alternative for someone. Nobody above used .Shapes.AddPicture in their code, only .Pictures.Insert()
Dim myPic As Object
Dim picpath As String
picpath = "C:\Users\photo.jpg" 'example photo path
Set myPic = ws.Shapes.AddPicture(picpath, False, True, 20, 20, -1, -1)
With myPic
.Width = 25
.Height = 25
.Top = xlApp.Cells(i, 20).Top 'according to variables from correct answer
.Left = xlApp.Cells(i, 20).Left
.LockAspectRatio = msoFalse
End With
I'm working in Excel 2013. Also realized that You need to fill all the parameters in .AddPicture, because of error "Argument not optional". Looking at this You may ask why I set Height and Width as -1, but that doesn't matter cause of those parameters are set underneath between With brackets.
Hope it may be also useful for someone :)
If it's simply about inserting and resizing a picture, try the code below.
For the specific question you asked, the property TopLeftCell returns the range object related to the cell where the top left corner is parked. To place a new image at a specific place, I recommend creating an image at the "right" place and registering its top and left properties values of the dummy onto double variables.
Insert your Pic assigned to a variable to easily change its name. The Shape Object will have that same name as the Picture Object.
Sub Insert_Pic_From_File(PicPath as string, wsDestination as worksheet)
Dim Pic As Picture, Shp as Shape
Set Pic = wsDestination.Pictures.Insert(FilePath)
Pic.Name = "myPicture"
'Strongly recommend using a FileSystemObject.FileExists method to check if the path is good before executing the previous command
Set Shp = wsDestination.Shapes("myPicture")
With Shp
.Height = 100
.Width = 75
.LockAspectRatio = msoTrue 'Put this later so that changing height doesn't change width and vice-versa)
.Placement = 1
.Top = 100
.Left = 100
End with
End Sub
Good luck!
I have been working on a system that ran on a PC and Mac and was battling to find code that worked for inserting pictures on both PC and Mac. This worked for me so hopefully someone else can make use of it!
Note: the strPictureFilePath and strPictureFileName variables need to be set to valid PC and Mac paths Eg
For PC: strPictureFilePath = "E:\Dropbox\" and strPictureFileName = "TestImage.jpg" and with Mac: strPictureFilePath = "Macintosh HD:Dropbox:" and strPictureFileName = "TestImage.jpg"
Code as Follows:
On Error GoTo ErrorOccured
shtRecipeBrowser.Cells(intDestinationRecipeRowCount, 1).Select
ActiveSheet.Pictures.Insert(Trim(strPictureFilePath & strPictureFileName)).Select
Selection.ShapeRange.Left = shtRecipeBrowser.Cells(intDestinationRecipeRowCount, 1).Left
Selection.ShapeRange.Top = shtRecipeBrowser.Cells(intDestinationRecipeRowCount, 1).Top + 10
Selection.ShapeRange.LockAspectRatio = msoTrue
Selection.ShapeRange.Height = 130
Firstly, of all I recommend that the pictures are in the same folder as the workbook.
You need to enter some codes in the Worksheet_Change procedure of the worksheet. For example, we can enter the following codes to add the image that with the same name as the value of cell in column A to the cell in column D:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim pic As Picture
If Intersect(Target, [A:A]) Is Nothing Then Exit Sub
On Error GoTo son
For Each pic In ActiveSheet.Pictures
If Not Application.Intersect(pic.TopLeftCell, Range(Target.Offset(0, 3).Address)) Is Nothing Then
pic.Delete
End If
Next pic
ActiveSheet.Pictures.Insert(ThisWorkbook.Path & "\" & Target.Value & ".jpg").Select
Selection.Top = Target.Offset(0, 2).Top
Selection.Left = Target.Offset(0, 3).Left
Selection.ShapeRange.LockAspectRatio = msoFalse
Selection.ShapeRange.Height = Target.Offset(0, 2).Height
Selection.ShapeRange.Width = Target.Offset(0, 3).Width
son:
End Sub
With the codes above, the picture is sized according to the cell it is added to.
Details and sample file here : Vba Insert image to cell
I tested both #SWa and #Teamothy solution. I did not find the Pictures.Insert Method in the Microsoft Documentations and feared some compatibility issues. So I guess, the older Shapes.AddPicture Method should work on all versions. But it is slow!
On Error Resume Next
'
' first and faster method (in Office 2016)
'
With ws.Pictures.Insert(Filename:=imageFileName, LinkToFile:=msoTrue, SaveWithDocument:=msoTrue)
With .ShapeRange
.LockAspectRatio = msoTrue
.Width = destRange.Width
.height = destRange.height '222
End With
.Left = destRange.Left
.Top = destRange.Top
.Placement = 1
.PrintObject = True
.Name = imageName
End With
'
' second but slower method (in Office 2016)
'
If Err.Number <> 0 Then
Err.Clear
Dim myPic As Shape
Set myPic = ws.Shapes.AddPicture(Filename:=imageFileName, _
LinkToFile:=msoFalse, SaveWithDocument:=msoTrue, _
Left:=destRange.Left, Top:=destRange.Top, Width:=-1, height:=destRange.height)
With myPic.OLEFormat.Object.ShapeRange
.LockAspectRatio = msoTrue
.Width = destRange.Width
.height = destRange.height '222
End With
End If

Resources