PowerPoint O365 - v16 Prevent Screen Updating - excel

I am creating shapes on a PowerPoint slide from Excel but it is incredibly slow because each shape is drawn and the screen is updating very slowly. I'm using office 365.
I have seen various posts pointing to the link below - but it appears to be for older versions. Even adding in another line for version 16 isn't doing anything
Case "16"
hWnd = FindWindow("PPTFrameClass", 0&)
PowerPoint VBA Equivalent of Application.ScreenUpdating
Has anyone managed to get this working so I can run Excel VBA, updating PowerPoint without any screen flicker and fast speeds.
Hope there is a solution to this.
Edit: Here is some sample code to run that shows the sort of thing I'm doing. Just need to add reference to Microsoft PowerPoint 16.0 Object Library
Option Explicit
Public PPT As PowerPoint.Application
Public PRES As PowerPoint.presentation
Public SLIDE As PowerPoint.SLIDE
Public CANV As PowerPoint.Shape
Public SHP As PowerPoint.Shape
Sub OpenPowerPoint()
Set PPT = CreateObject("Powerpoint.Application")
Set PRES = PPT.Presentations.Add
PPT.Visible = True
Set SLIDE = PRES.Slides.Add(PPT.ActivePresentation.Slides.Count + 1, ppLayoutText)
End Sub
Sub CreatePPTShapes()
If PRES Is Nothing Then OpenPowerPoint
Dim l As Long, t As Long, w As Long, h As Long, x As Long
Dim size As Long, m As Long, nm As String
Dim startDate As Long
startDate = DateSerial(2021, 4, 1)
l = 5
t = 70
w = PRES.PageSetup.SlideWidth - 10
h = PRES.PageSetup.SlideHeight - 75
Set CANV = SLIDE.Shapes.AddShape(msoShapeRectangle, l, t, w, h)
With CANV
.Name = "ta_canvas"
With .Fill
.Visible = msoTrue
.ForeColor.RGB = RGB(240, 240, 240)
.Transparency = 0
.Solid
End With
With .Line
.Visible = msoTrue
.ForeColor.RGB = RGB(0, 0, 0)
.Transparency = 0.5
.Weight = 0.25
End With
End With
t = t + 5
w = (w) / 12
h = 20
For x = 0 To 2
For m = 0 To 11
nm = MonthName(Month(DateAdd("m", m, startDate)), True)
t = 70 + 7 + (x * 25)
l = 10 + (w * m)
Dim newPos As Long
Set SHP = SLIDE.Shapes.AddShape(msoShapeRoundedRectangle, l, t, w, h)
With SHP
.Name = "ta_" & nm
.Adjustments(1) = 0.25
.Line.Visible = msoFalse
.Fill.Visible = True
.Fill.ForeColor.RGB = RGB(0, 0, 0)
With .TextFrame2
.TextRange.Characters.Text = nm
.MarginLeft = 2.8346456693
.MarginRight = 2.8346456693
.MarginTop = 0
.MarginBottom = 0
.WordWrap = msoFalse
.AutoSize = msoAutoSizeShapeToFitText
With .TextRange.ParagraphFormat
.FirstLineIndent = 0
.Alignment = msoAlignCenter
End With
.VerticalAnchor = msoAnchorMiddle
With .TextRange.Font
.size = 12
With .Fill
.Visible = msoTrue
.ForeColor.RGB = RGB(255, 255, 255)
End With
End With
End With
End With
Next m
Next x
End Sub

I've found that if I switch the view in code to the handout master then the code runs much much quicker. It looks like the screen updating is suspended.
ppt.activewindow.viewtype = ppviewhandoutmaster
then switch it back at the end to ppViewNormal or whichever your preferred default view.

Related

Need help using VBA to insert hyperlinks in excel to specified pictures on my computer

I have 600+ pictures in a folder on my computer and I want to link each one to a different cell in an excel file using vba instead of going through and linking each one manually. I'm not very good at vba but the end goal is a code that can go down the line in excel and pull the designated picture from my files and link it and then go to the next.
The code I have so far is partially going off another post I saw on here and it's just trying to do the first step of inserting the first picture but I am having trouble with it:
Dim Picture_1 As String
With ActiveSheet.Pictures.Insert("X:\roena10\Q ear crack pictures")
.Left = ActiveSheet.Range("photograph").Left + 2
.Top = ActiveSheet.Range("photograph").Top + 2
Picture_1 = .Name
End With
ActiveSheet.Pictures(profile).Select
With Selection.ShapeRange
.LockAspectRatio = msoFalse
.Width = 20
.Height = 20
End With
Any help is appreciated!
Try this code:
Sub AddImages()
Const path = "c:\test\", W = 20, H = 20, h_gap = 5
Dim img As Shape, cl As Range, ws As Worksheet
Dim fname As String, ext As String, pos As Integer, T As Long, L As Long
Set ws = ThisWorkbook.Sheets("Sheet1")
Set cl = ws.Range("B1")
fname = Dir(path & "*", vbNormal)
Do While Len(fname) > 0
pos = InStrRev(fname, ".")
ext = vbNullString
If pos > 0 Then ext = LCase(Mid(fname, pos + 1))
Select Case ext
Case "jpg", "png", "bmp" 'and so on
With cl
T = .Top + 2
L = .Left + 2
.EntireRow.RowHeight = H + h_gap
End With
Set img = ws.Shapes.AddPicture(Filename:=path & fname, _
LinkToFile:=msoTrue, SaveWithDocument:=True, _
Left:=L, Top:=T, Width:=-1, Height:=-1)
img.LockAspectRatio = msoTrue
img.Height = H
With img.Line
.Visible = msoTrue
.ForeColor.RGB = vbBlack
.Transparency = 0
End With
ws.Hyperlinks.Add Anchor:=img, Address:=path & fname
T = T + H + h_gap
Set cl = cl.Offset(1)
End Select
fname = Dir
Loop
End Sub
Screenshot

Excel Waterfall Charts: Unable to resize plot/legend areas in VBA generated waterfall charts

I have a VBA function in Excel (office 365 ProPlus) generating waterfall charts, see examples below. After generating them I want to resize the plot/legend/axis areas just to adjust the looks.
But Excel doesn't let me; the edges of the areas seem to be fixed (see blue dots/circles), I can't grab them.
I can change the axis ranges but not the area sizes. If I change the chart type e.g. to stacked bars it works.
The sheet is not protected.
Is this a known problem?
Is there a workaround?
Do I have something in my code (below) that causes this behaviour, or is something missing?
Dim rngChartValues As Range
Dim rngChartXValues As Range
Dim myChart As Chart
Dim myShape As Shape
Dim dStartValue As Double
Dim dEndValue As Double
Dim dDeltaSurplus As Double
Dim dDeltaPC As Double
Dim chartTitle As String
Dim rngToplace As Range
rngChartValues.Select
Set myShape = ActiveSheet.Shapes.AddChart2(395, xlWaterfall)
Set myChart = myShape.Chart 'ActiveChart
Application.CutCopyMode = False
rngToplace.Select
With myShape
.Left = rngToplace.Left
.Top = rngToplace.Top
.Placement = xlFreeFloating
.Height = 450
End With
With myChart
.Legend.Delete
.chartTitle.Text = chartTitle
.SeriesCollection.NewSeries
.Parent.name = chartTitle
With .FullSeriesCollection(1)
.name = chartTitle
.Values = rngChartValues
.XValues = rngChartXValues
dStartValue = shtCharts.Cells(rowCapSurplusEarlr, colCA).Value
dEndValue = shtCharts.Cells(rowCapSurplusLater, colCA).Value
dDeltaSurplus = shtCharts.Cells(rowDeltaSurplus, colCA).Value
dDeltaPC = Abs(dDeltaSurplus / dStartValue)
' handle the last bar as total bar
With .Points(.Points.Count)
.IsTotal = True
If dDeltaPC < 0.1 Then ' change is smaller than 10%
If dDeltaSurplus < 0 Then ' ...but still negative
.Format.Fill.ForeColor.RGB = RGB(255, 204, 0) ' => light orange
Else ' ... and positive
If dEndValue < 0 Then ' ... but the surplus is till negative
.Format.Fill.ForeColor.RGB = RGB(255, 204, 0) ' => light orange
Else ' ... and the surplus is positive
.Format.Fill.ForeColor.RGB = RGB(153, 204, 0) ' => light green
End If
End If
ElseIf dDeltaSurplus < 0 Then ' change is >10% and negative
.Format.Fill.ForeColor.RGB = RGB(255, 153, 0) ' => orange
Else ' cange is >10$ and positive
If dEndValue < 0 Then ' ... but the surplus is till negative
.Format.Fill.ForeColor.RGB = RGB(255, 255, 0) ' => yellow
Else ' ... and the surplus is positive
.Format.Fill.ForeColor.RGB = RGB(0, 160, 0) ' => green
End If
End If
End With
End With
End With
With myChart.Parent
intTmp = .Width
intTmp = .Height
End With

Suggestions for codes format to set the chart coordinates,title and added text in excel macro

Wrote a macro to draw line with markers plot with excel, it works well in a single macro xlsm file. But when I tried to convert it to a excel addin (xlam file) , it got a lot of bugs. All the bugs are related to the format of both X and Y coordinates, position, font type and size of chart title, and position, font type and sizeof added text. Not sure what is the reason, need to know the correct format of them. Any debug suggestions or help, really appreciated. Please see the error message and my full macro codes as the following. Thanks.
The error message is run time error '-21474627161 (800004003)': the object is no longer valid.
After you clicked the debug, the code " .left=358" was highlighted with yellow.
But you checked with excel, the plot was drawn without chart title and the add text (that I want) and the format of coordinate was not that I tried to set. Again all these errors only happen with the xlam file, the macro works well with xlms fie.
Sub strain_plot()
sh_rows = ActiveWorkbook.ActiveSheet.Range("B65535").End(xlUp).Row
For i = 1 To sh_rows
If ActiveSheet.Cells(i, 1).Value < 0.000001 Then
ActiveSheet.Cells(i, 1).Value = 1000000000# * ActiveSheet.Cells(i, 1).Value
End If
Next i
ii = sh_rows
c_name = "chart1"
On Error GoTo err:
ActiveWorkbook.ActiveSheet.ChartObjects(c_name).Delete
err:
Set ch = ActiveWorkbook.ActiveSheet.ChartObjects.Add(330, 120, 480, 270) 'set graph position and size
ch.Name = c_name
With ch.Chart
For iii = 1 To 2
.SeriesCollection.NewSeries
.SeriesCollection(iii).Values = Range(ActiveWorkbook.ActiveSheet.Cells(1, iii + 1), ActiveWorkbook.ActiveSheet.Cells(ii, iii + 1))
.SeriesCollection(iii).XValues = Range(ActiveWorkbook.ActiveSheet.Cells(1, 1), ActiveWorkbook.ActiveSheet.Cells(ii, 1))
.SeriesCollection(iii).ChartType = xlLineMarkers
Next iii
.SeriesCollection(1).Name = "[110]"
.SeriesCollection(1).MarkerStyle = 2
.SeriesCollection(1).MarkerSize = 12
.SeriesCollection(1).MarkerForegroundColor = RGB(255, 0, 0)
.SeriesCollection(1).MarkerBackgroundColor = RGB(255, 0, 0)
.SeriesCollection(1).Format.Fill.ForeColor.RGB = RGB(255, 0, 0)
.SeriesCollection(2).Name = "[001]"
.SeriesCollection(2).MarkerStyle = 2
.SeriesCollection(2).MarkerSize = 12
.SeriesCollection(2).MarkerForegroundColor = RGB(96, 96, 96)
.SeriesCollection(2).MarkerBackgroundColor = RGB(96, 96, 96)
.SeriesCollection(2).Format.Fill.ForeColor.RGB = RGB(96, 96, 96)
With .Legend
.IncludeInLayout = False
.Position = xlLegendPositionRight
.AutoScaleFont = False
.Font.Size = 14
.Top = 25
.Left = 392
.Width = 72
.Height = 40
End With
With .ChartArea.Fill
.Visible = msoTrue
.ForeColor.SchemeColor = 33
.Solid
End With
With .SeriesCollection(1).Format.Line
.Visible = msoTrue
.ForeColor.RGB = RGB(255, 0, 0) 'red
.Transparency = 0
End With
With .SeriesCollection(2).Format.Line
.Visible = msoTrue
.ForeColor.RGB = RGB(96, 96, 96) 'grey
.Transparency = 0
End With
.HasTitle = True
With .ChartTitle
.Text = ActiveWorkbook.ActiveSheet.Cells(5, 8)
.Left = 358
.Top = 236
With .Font
.Name = "Tahoma"
.Size = 10
End With
End With
With .Axes(xlCategory)
.HasTitle = True
.AxisTitle.Text = "Position(nm)" 'X-axis title
.TickLabels.Font.Size = 10 'X-axis coordinate number size
.AxisTitle.Font.Size = 14 'X-axis title word font size
.TickMarkSpacing = 3
.TickLabelSpacing = 5
.TickLabels.NumberFormatLocal = "#,##0._);[red](#,##0.)"
.TickLabels.NumberFormatLocal = "#,##0_);[red](#,##0)"
.TickLabels.NumberFormatLocal = "0_);[red](0.)"
End With
With .Axes(xlValue)
.HasTitle = True
.AxisTitle.Text = "Strain" 'Y-aixs title
.AxisTitle.Font.Size = 14 'y-axis title word font size
'Minimum value of Y axis
.Axes(xlValue).MinimumScale = -0.005
.Axes(xlValue).TickLabels.NumberFormatLocal = "0.0%"
End With
End With
Dim thechartobj As ChartObject
Set thechartobj = ActiveWorkbook.ActiveSheet.ChartObjects(ch.Name)
Dim thechart As Chart
Set thechart = thechartobj.Chart
Dim thetextbox As Shape
Set thetextbox = thechart.Shapes.AddTextbox(msoTextOrientationHorizontal, 688, 372, 122, 20)
With thetextbox.TextFrame.Characters
.Text = ActiveSheet.Cells(6, 8)
With .Font
.Name = "tahoma"
.Size = 10
.Bold = msoTrue
End With
End With
End Sub

Formatting Chart Legends Using With (Syntax)

I have a macro which adds and removes (filterseries) set data series of a chart (in its own sheet) by looping through checkboxes in a separate sheet. When I add and remove them, I want to cycle the legend off then back on so that it resizes itself automatically.
I think this is just a syntax error of how I'm using the with statement.
I have a separate macro which does this for a different purpose, but it loops through chart-sheets and treats them as variables and, for some reason, it works there.
Sub ISurfSeries1Checklist()
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim i As Integer
Dim c As Integer
For i = 1 To 56
If ActiveWorkbook.Sheets("Range").Cells(3 + i, 12).Value = True Then
ActiveWorkbook.Charts("I. Surf (1)").FullSeriesCollection(i).IsFiltered = False
Else 'ActiveWorkbook.Sheets("Range").Cells(3 + i, 12) = False Then
ActiveWorkbook.Charts("I. Surf (1)").FullSeriesCollection(i).IsFiltered = True
End If
Next i
For c = 51 To 56 'ActiveWorkbook.Charts("I. Surf (1)").FullSeriesCollection.Count
ActiveWorkbook.Charts("I. Surf (1)").FullSeriesCollection(c).Format.Line.Visible = msoTrue
ActiveWorkbook.Charts("I. Surf (1)").FullSeriesCollection(c).Format.Line.ForeColor.RGB = RGB(255, 0, 0)
ActiveWorkbook.Charts("I. Surf (1)").FullSeriesCollection(c).Format.Line.Transparency = 0
Next c
ActiveWorkbook.Charts("I. Surf (1)").HasLegend = False
ActiveWorkbook.Charts("I. Surf (1)").HasLegend = True
'***Below is where it stops working.***
With ActiveWorkbook.Charts("I.Surf (1)").Legend
.Font.Size = 8
.Border.Weight = xlHairline
.Border.Color = RGB(89, 89, 89)
.Interior.Color = RGB(255, 255, 255)
.Left = Cht_Sht.PlotArea.InsideLeft - Cht_Sht.Axes(xlValue).Format.Line.Weight
.Top = Cht_Sht.PlotArea.InsideTop
End With
Runtime Error '9'. Subscript out of range
on the With statement: With ActiveWorkbook.Charts("I.Surf (1)").Legend
That means a chart named "I.Surf (1)" does not exist you are probably missing the space between the dot and Surf. It should be "I. Surf (1)".
I recommend to reference the chart by a variable so you only have to use its name once. Coding rule number 1: Don't repeat yourself.
Dim ActChart As Chart
Set ActChart = ActiveWorkbook.Charts("I. Surf (1)")
This prevents typos and if you have to change it you only need to change it in one position:
Sub ISurfSeries1Checklist()
Application.ScreenUpdating = False
Application.EnableEvents = False
Dim ActChart As Chart
Set ActChart = ActiveWorkbook.Charts("I. Surf (1)")
Dim i As Long
For i = 1 To 56
'Note that you can shorten this to:
ActChart.FullSeriesCollection(i).IsFiltered = Not (ActiveWorkbook.Sheets("Range").Cells(3 + i, 12).Value = True)
Next i
Dim c As Long
For c = 51 To 56 'ActiveWorkbook.Charts("I. Surf (1)").FullSeriesCollection.Count
With ActChart.FullSeriesCollection(c).Format.Line
.Visible = msoTrue
.ForeColor.RGB = RGB(255, 0, 0)
.Transparency = 0
End With
Next c
ActChart.HasLegend = False
ActChart.HasLegend = True
With ActChart.Legend
.Font.Size = 8
.Border.Weight = xlHairline
.Border.Color = RGB(89, 89, 89)
.Interior.Color = RGB(255, 255, 255)
.Left = Cht_Sht.PlotArea.InsideLeft - Cht_Sht.Axes(xlValue).Format.Line.Weight
.Top = Cht_Sht.PlotArea.InsideTop
End With
End Sub

Rotate line about a point

I need to rotate an horizontal line about its end point in VB Excel.
I tried various solution found on internet but they don't work well.
I give you some images about what I want to do:
This is my line:
point A (72; 378)
point B (165; 378)
And I want to rotate the point A about the point B, the angle of rotation is variable. For example this is a 60 degrees rotation
The letters A and B were added after the screenshot with a photo editor
Try this.
Sub test()
Dim x As Single, y As Single
Dim nx As Single, ny As Single, l As Single
Dim i As Single, ra As Single
Dim Ws As Worksheet
Dim shp As Shape
Set Ws = ActiveSheet
For Each shp In Ws.Shapes
If shp.Type = msoLine Then
shp.Delete
End If
Next
x = 165
y = 378
l = 165 - 72
For i = 90 To 150
ra = WorksheetFunction.Radians(i)
nx = x - Sin(ra) * l
ny = y + Cos(ra) * l
Set shp = Ws.Shapes.AddLine(x, y, nx, ny)
With shp
.Line.EndArrowheadStyle = msoArrowheadTriangle
.Line.ForeColor.RGB = RGB(255, 0, 0)
.Line.Weight = 2
End With
DoEvents
Application.Wait Now + (TimeSerial(0, 0, 1) / 2)
shp.Delete
Next i
Set shp = Ws.Shapes.AddLine(x, y, nx, ny)
With shp
.Line.EndArrowheadStyle = msoArrowheadTriangle
.Line.ForeColor.RGB = RGB(255, 0, 0)
.Line.Weight = 2
End With
End Sub

Resources