Find and Replace on PowerPoint Excel Worksheet for a Chart - vba

So this code will run a Find and Replace on PowerPoint charts. the goal is to replace the x-axis labels. The issue I'm having is that I get this popping up: We couldn't find anything to replace. Click options for more ways to search."
It pops up every time the chart doesn't have the word I'm looking for. So I added rngFound. I want to be able to say "If word is Found then Replace" instead of having my Replace just do everything at once.
So I went and added Set rngFound = Worksheets(1).objRange.Find(fndList). But it's not working. I suspect rngFound isn't actually doing anything for me, and would like any sort of help with this issue. Thank you in advance!
Option Explicit
Private Sub findAndReplaceChrt()
'Timer start
Dim StartTime As Double
Dim SecondsElapsed As Double
StartTime = Timer
Dim pptPres As Object
Dim sld As Slide
Dim shpe As Shape
Dim c As Chart
Dim sht As Object
Dim fndList As Variant
Dim rplcList As Variant
Dim listArray As Long
Dim rngFound As Variant
fndList = Array("Red", "Purple")
rplcList = Array("red", "blue")
'Make pptPres the ppt active
Set pptPres = PowerPoint.ActivePresentation
'Loop through each sld and check for chart title, grab avgScore values and create pptTable to paste into ppt chart
For Each sld In pptPres.Slides
'searches through shapes in the slide
For Each shpe In sld.Shapes
'Checks if shape is a Charts and has a Chart Title
If Not shpe.HasChart Then GoTo nxtShpe
Set c = shpe.Chart
If Not c.ChartType = xlPie Then
ActiveWindow.ViewType = ppViewNormal
c.ChartData.Activate
'Loop through each item in Array lists
For listArray = LBound(fndList) To UBound(fndList)
Set rngFound = Worksheets(1).objRange.Find(fndList)
If Not rngFound Is Nothing Then
Worksheets(1).Cells.Replace What:=fndList(listArray), Replacement:=rplcList(listArray), _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
End If
Next listArray
c.ChartData.Workbook.Close
End If
nxtShpe:
Next shpe
Next sld
'End Timer
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub

Related

Copying Charts from Excel to PowerPoint with Special Paste doesn't work anymore

i´m using VBA in Excel to go through all Chart-Sheets and copy them to a existing PowerPoint-presentation.
Until today the program worked fine. But since today it doesn´t copy the Charts to PowerPoint anymore.
The program works like: go through all Chart-Sheets and call a Helpfunction.
The helpfunction copys the ChartArea and pastes it with:
With pptApp.ActiveWindow
.ViewType = ppViewNormal
.View.PasteSpecial DataType:=ppPasteOLEObject, link:=msoTrue
End With
on the PowerPoint.
But the Problem here is that the PasteSpecial doesn´t work anymore and i don´t understand why.
Thank you for your help.
Here is the full code:
'Declaring the necessary Power Point variables (are used in both subs).
Dim pptApp As PowerPoint.Application
Dim pptPres As PowerPoint.Presentation
Dim pptSlide As PowerPoint.Slide
Dim pptSlideCount As Integer
Sub ChartsToPowerPoint()
Dim ws As Worksheet
Dim intChNum As Integer: intChNum = 0
Dim objCh As Object
Dim ppPres As String
Dim counter As Integer
Dim rng As Range
Dim oChart As Chart
Dim zähler As Integer
Set rng = ActiveWorkbook.Sheets("Daten").Range("A1:Z200").Find("Pfad für die Powerpoint")
ppPres = rng.Offset(1, 0).Value
counter = 4
For Each ws In ActiveWorkbook.Worksheets
intChNum = intChNum + ws.ChartObjects.Count
Next ws
zähler = ActiveWorkbook.Charts.Count
'Count the embedded charts.
'For Each ws In ActiveWorkbook.Worksheets
' intChNum = intChNum + ws.ChartObjects.Count
'Next ws
'Check if there are chart (embedded or not) in the active workbook.
If intChNum + ActiveWorkbook.Charts.Count < 1 Then
MsgBox "Sorry, there are no charts to export!", vbCritical, "Ops"
Exit Sub
End If
'Open PowerPoint and create a new presentation.
Set pptApp = New PowerPoint.Application
Set pptPres = pptApp.Presentations.Open(ppPres)
'Loop through all the embedded charts in all worksheets.
For Each ws In ActiveWorkbook.Worksheets
For Each objCh In ws.ChartObjects
Call pptFormat(objCh.Chart, counter)
Next objCh
Next ws
'Loop through all the chart sheets.
For Each objCh In ActiveWorkbook.Charts
Call pptFormat(objCh, counter)
counter = counter + 1
Next objCh
'Show the power point.
pptApp.Visible = True
'Cleanup the objects.
Set pptSlide = Nothing
Set pptPres = Nothing
Set pptApp = Nothing
'Infrom the user that the macro finished.
'MsgBox "The charts were copied successfully to the new presentation!", vbInformation, "Done"
End Sub
Private Sub pptFormat(xlCh As Chart, i As Integer)
'Formats the charts/pictures and the chart titles/textboxes.
Dim chTitle As String
Dim j As Integer
Dim tempName As String
Dim oLayout As CustomLayout
Dim counter As Integer
On Error Resume Next
'Get the chart title and copy the chart area.
xlCh.ChartArea.Copy
'Count the slides and add a new one after the last slide.
pptSlideCount = pptPres.Slides.Count
'tempName = GetLayout("Layout für QGs")
counter = i
'Set pptSlide = pptPres.Slides.Add(pptSlideCount + 1, Layout:=ppLayoutVerticalTitleAndTextOverChart)
pptApp.ActivePresentation.Slides(counter).Select
'pptApp.ActivePresentation.Slides(counter).Shapes.PasteSpecial DataType:=ppPasteOLEObject, link:=msoTrue
With pptApp.ActiveWindow
.ViewType = ppViewNormal
.View.PasteSpecial DataType:=ppPasteOLEObject, link:=msoTrue
End With
With pptApp.ActiveWindow.Selection.ShapeRange
.LockAspectRatio = msoFalse
'Oberer Rand 1 cm unter Standardtitel
.Top = 3.92 * 28.38
'Linker Rand 1.5 cm von linkem Folienrand
.Left = 4.51 * 28.38
'Eingefügte Tabelle auf Links und rechts 1,5 cm Rand skalieren
.Width = 24.23 * 28.38
'Bei Bedarf Höhe noch einstellen
'Hier ist jedoch zu beachten, dass das Object skaliert wird !!!
'Die Breite verändert sich dann
.Height = 12.7 * 28.38
.Line.Visible = msoFalse
End With
End Sub
Try using this code
Function PasteChartIntoSlide(theSlide As Object) As Object
Sleep 100
On Error Resume Next
theSlide.Shapes.Paste.Select
PPT.ActiveWindow.Selection.ShapeRange.LockAspectRatio = msoFalse
End Function
Function CopyChartFromExcel(theSlide As Object, cht As Chart) As Object
cht.CopyPicture Appearance:=xlScreen, Format:=xlPicture, Size:=xlScreen
End Function
Function PositionChart(leftPos As Integer, rightPos As Integer, widthPos As Integer, heightPos As Integer) As Object
Sleep 50
PPT_pres.Windows(1).Selection.ShapeRange.Left = leftPos
PPT_pres.Windows(1).Selection.ShapeRange.Top = rightPos
PPT_pres.Windows(1).Selection.ShapeRange.Width = widthPos
PPT_pres.Windows(1).Selection.ShapeRange.Height = heightPos
End Function
Function CopyPasteChartFull(Sld As Integer, cht As Chart, leftPos As Integer, rightPos As Integer, widthPos As Integer, heightPos As Integer) As Object
If PPT Is Nothing Then Exit Function
If PPT_pres Is Nothing Then Exit Function
Dim mySlide As Object
Dim myShape As Object
PPT_pres.Slides(Sld).Select 'Pointless line, just lets the user see what is happening
Set mySlide = PPT_pres.Slides(Sld)
With mySlide
.Select
'copy chart
CopyChartFromExcel mySlide, cht
'Paste chart
PasteChartIntoSlide mySlide
'Position Chart
PositionChart leftPos, rightPos, widthPos, heightPos
End With
'Clear The Clipboard
Application.CutCopyMode = False
End Function

Is there something I can "release" to make this faster?

So this code will run through every chart I have in a presentation and look to do a Find/Replace on the values inside.
My presentations usually have 100-300 charts on them, and by the time the code gets to the 300th chart in the presentation, it takes 10-30 seconds to do everything (when it would do 5 graphs in that time when I initially run the program.)
So my question is: Is there any way to make this faster? I'm thinking something along the lines of "releasing" something from memory, if VBA has it, would be the solution but I can't find anything on that.
I added
Set c = Nothing
Excel.Application.ScreenUpdating = True
Excel.Application.EnableEvents = True
Excel.Application.DisplayAlerts = True
Application.DisplayAlerts = True
I think suppressing everything is helping out a little bit, but I can't tell with the Set c = Nothing.
There must be something that could be"refresher" or "released" to make this run the same every loop and not slow down.
Any help appreciated!
Option Explicit
Private Sub findAndReplaceChrt()
'Timer start
Dim StartTime As Double
Dim SecondsElapsed As Double
StartTime = Timer
' use & vbLF & for alt + enter
Dim pptPres As Object
Dim sld As Slide
Dim shpe As Shape
Dim c As Chart
Dim sht As Object
Dim fndList As Variant
Dim rplcList As Variant
Dim listArray As Long
Excel.Application.ScreenUpdating = False
Excel.Application.EnableEvents = False
Excel.Application.DisplayAlerts = False
Application.DisplayAlerts = False
fndList = Array("a", "b", "c", "d", "e", "f")
rplcList = Array("1", "2", "3", "4", "5", "6")
'Make pptPres the ppt active
Set pptPres = PowerPoint.ActivePresentation
'Loop through each sld and check for chart title, grab avgScore values and create pptTable to paste into ppt chart
For Each sld In pptPres.Slides
'searches through shapes in the slide
For Each shpe In sld.Shapes
'Checks if shape is a Charts and has a Chart Title
If Not shpe.HasChart Then GoTo nxtShpe
Set c = shpe.Chart
If Not c.ChartType = xlPie Then
ActiveWindow.ViewType = ppViewNormal
c.ChartData.Activate
'Loop through each item in Array lists
For listArray = LBound(fndList) To UBound(fndList)
Worksheets(1).Cells.Replace What:=fndList(listArray), Replacement:=rplcList(listArray), _
LookAt:=xlPart, SearchOrder:=xlByRows, MatchCase:=False, _
SearchFormat:=False, ReplaceFormat:=False
Next listArray
c.ChartData.Workbook.Close
End If
Set c = Nothing
nxtShpe:
Next shpe
Next sld
Excel.Application.ScreenUpdating = True
Excel.Application.EnableEvents = True
Excel.Application.DisplayAlerts = True
Application.DisplayAlerts = True
'End Timer
SecondsElapsed = Round(Timer - StartTime, 2)
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub

Copy UserForm data to the next empty row inside PowerPoint Chart

I created a UserForm, with the help of many, within PowerPoint to assist with consistent embedded chart data entries. From what I have learned I will never do this again because addtional code that is needed to traverse through the PowerPoint to get to the correct location for the desired updates. No matter, I would like to finish the final objective of getting data from the UserForm into the first empty row. I have code but there is an error that is preventing the data to unload. The code I have is below. Any help in identifying the glitch is greatly appreciated.
Private Sub CPDataAdd_Click()
Dim sld As Slide
Dim shp As shape
Dim chrt As Chart
Dim xlWB As Object
For Each sld In ActivePresentation.Slides
For Each shp In sld.Shapes
If shp.Type = msoChart Then
If shp.Name = "DVchart" Then
Set xlWB = shp.Chart.ChartData.Workbook
Exit For
End If
End If
Next
If Not xlWB Is Nothing Then Exit For
Next
Set shp = sld.Shapes("DVchart")
Set xlWB = shp.Chart.ChartData.Workbook
Dim LastRow As Long
With xlWB.Sheets(1)
LastRow = .Range("AI" & Rows.Count).End(xlup).Row + 1
.Range("AI" & LastRow).Value = CPDate.Text
.Range("BI" & LastRow).Value = CPCompleteN.Text
.Range("CI" & LastRow).Value = CPPassN.Text
.Range("DI" & LastRow).Value = CPFailN.Text
.Range("EI" & LastRow).Value = CPNotN.Text
End With
End Sub

Copy from Excel Worksheets to specific Powerpoint slides

I am transferring data from excel to powerpoint slides with an automated script by using EXcel VBA. I'm trying to copy the usedrange of a excel worksheet and paste it to as a image in a powerpoint Template of 4th slide and from there on it should add new slides and copy the remaining worksheets to the next further slides.
So, In my code for the first iteration it is copying from excel worksheet of first sheet and pasting it in the 4th slide but for the next iteration it is throwing the error as below:
The code which i'm currently using is getting the following error
"Run Time Error -2147188160(80048240) AutomationError".
I'm new to Excel VBA. Please help
Can anyone suggest me the code for the following.
Hope this is clearly explained. If not please ask for more clarification.
Thanks
Private Sub CommandButton2_Click()
Dim PP As PowerPoint.Application
Dim PPpres As Object
Dim PPslide As Object
Dim PpTextbox As PowerPoint.Shape
Dim SlideTitle As String
Dim SlideNum As Integer
Dim WSrow As Long
Dim Sh As Shape
Dim Rng As Range
Dim myshape As Object
Dim myobject As Object
'Open PowerPoint and create new presentation
Set PP = GetObject(class, "PowerPoint.Application")
PP.Visible = True
Set PPpres = PP.Presentations.Open("\\C:\Users\Templates")
'Specify the chart to copy and copy it
For Each WS In Worksheets
If (WS.Name) <> "EOS" Then
ThisWorkbook.Worksheets(WS.Name).Activate
ThisWorkbook.ActiveSheet.UsedRange.CopyPicture
lastrow = ActiveSheet.UsedRange.Rows(ActiveSheet.UsedRange.Rows.Count).Row
'Copy Range from Excel
Set Rng = ThisWorkbook.ActiveSheet.Range("A1:I" & lastrow)
'Copy Excel Range
Rng.Copy
For k = 4 To 40
slidecount = PPpres.Slides.Count
PP.ActiveWindow.View.GotoSlide (k)
'Paste to PowerPoint and position
Set PPslide = PPpres.Slides(k)
PPslide.Shapes.PasteSpecial DataType:=10 '2 = ppPasteEnhancedMetafile
Set myshape = PPslide.Shapes(PPslide.Shapes.Count)
'Set position:
myshape.Left = 38
myshape.Top = 152
'Add the title to the slide
SlideTitle = "Out of Support, " & WS.Name & " "
Set PpTextbox = PPslide.Shapes.AddTextbox(msoTextOrientationHorizontal,
0, 20, PPpres.PageSetup.SlideWidth, 60)
PPslide.Shapes(1).TextFrame.TextRange = SlideTitle
'Set PPslide = PPpres.Slides.Add(slidecount + 1, ppLayoutTitle)
'Make PowerPoint Visible and Active
PP.Visible = True
PP.Activate
'Clear The Clipboard
Application.CutCopyMode = False
Next k
Exit For
End If
Next WS
End Sub

With VBA in Excel how can I reference a cell with a variable

As the title suggests, I can't figure out how to go to a cell using a variable for the row. I have attached the code I currently have and the commented section is what I'm having issues with, Thanks!
Private Sub Go_Click()
Dim id As Double
Dim qt As Double
Dim num As Double
Dim rngSearch As Range, rngFound As Range
id = Range("D4").Value
qt = Range("E4").Value
Set rngSearch = Range("A:A")
Set rngFound = rngSearch.Find(What:=id, LookIn:=xlValues, LookAt:=xlPart)
num = rngFound.Row
If rngFound Is Nothing Then
MsgBox "Stock ID Not Found"
Else
MsgBox rngFound.Row
'Range("O num.Value") = Range("O num.Value") - qt
End If
Range(rngFound.Row) = Range(rngFound.Row) - qt
End Sub
Perhaps
Range("O" & num).value=Range("O" & num).value-qt