Loop Through Columns in Existing Worksheet - Paste Values to Existing PowerPoint as Textboxes - excel

Ive made a VBA macro that automatically creates a PowerPoint and one that creates a Worksheet named "Handlungsempfehlungen" with Text. The Worksheet "Handlungsempfehlungen" looks like this:
https://i.stack.imgur.com/nZEL8.png
It has about 40 columns (A-AO) and Text in each column from Row 1 to max. 34 (Number of rows filled with text varies each column). I now need to somehow loop through each row in each column and give each Cell.Value over to the existing (and currently opened) PowerPoint. Until now Ive used something like this to create textboxes in PowerPoint and fill them with Cell Values from Excel:
'New PPslide (copy slide 2 which is emtpy)
Set PPslide = PPapp.ActivePresentation.Slides(2).Duplicate.Item(1)
'Put new slide to end of PP
PPslide.MoveTo (PPpres.Slides.Count)
'Change title
PPslide.Shapes.Title.TextFrame.TextRange = "Slidetitle"
PPslide.Shapes(2).TextFrame.TextRange.Text = "Second title"
'Insert Textbox
Set PPtextbox = PPslide.Shapes.AddTextbox(msoTextOrientationHorizontal, Left:=40, Top:=133, Width:=875, Height:=30)
PPtextbox.TextFrame.TextRange.Text = ActiveWorkbook.Worksheets("Handlungsempfehlungen").Cells(1, 1).Value
But with 40 columns and about 30 rows per column each filled with text I would need to create about 1000 textboxes and hand them to my PowerPoint. How could I loop through this Worksheet and automatically have positions on the PowerPoint Slide set for each textbox? The slidetitle for each PowerPointslide is already saved in the Row 35 of each Column in the Worksheet (see screenshot), so I would give this over to PP inside the loop as well (for each column set slidetitle = currentColumn.Row 35 is kinda the idea)
My current Idea for all of this is I having 5 textboxes per slide with set positions, filling them with the values from row 1-5 of the first column and then create a new slide and do the same process for rows 6-10 and so on until the Cell.Value in the current column is empty, then jump one column to the right and create a new PPslide again and repeat the whole process until the whole Worksheet has been worked through. I think this seems relatively simple but I am still a beginner and have difficulties implementing this.
Would this be a good idea and how would I need to get there? Im quite bad at looping but Im happy for every answer! Thanks for your time & help!
PS: the declarations for the created PP and its Objects:
Public Shape As Object
Public PPshape As PowerPoint.Shape
Public PPapp As PowerPoint.Application
Public PPpres As PowerPoint.Presentation
Public PPslide As PowerPoint.Slide
Public PPtextbox As PowerPoint.Shape
Set PPapp = New PowerPoint.Application
PPapp.Visible = msoTrue

The following code covers two scenarios:
You have PowerPoint open with an active presentation that has a slide at the begining with a Title and 5 texboxes properly named
You have PowerPoint closed
You need to set a reference to PowerPoint object model like this:
Read code's comments and try to adjust it to fit your needs
Use the F8 key to step into the code line by line
You can also add a Stop statement so the code breaks and then use the F8 key
Public Sub TransferDataToPPT()
' Set basic error handling
On Error GoTo CleanFail
' Turn off stuff
Application.ScreenUpdating = False
Dim pptApp As PowerPoint.Application
Dim pptPresentation As PowerPoint.Presentation
Dim pptMainSlide As PowerPoint.Slide
Dim pptContentSlide As PowerPoint.Slide
Dim isNewPPTInstance As Boolean
' Open and get PowerPoint instance
Set pptApp = OpenGetPowerPoint(isNewPPTInstance)
' If it's a new instance add new presentation and main slide
If isNewPPTInstance Then
pptApp.Visible = msoTrue
Set pptPresentation = pptApp.Presentations.Add(msoTrue)
Set pptMainSlide = pptPresentation.Slides.Add(1, ppLayoutTitleOnly)
pptMainSlide.Shapes.AddTextbox(msoTextOrientationHorizontal, 100, 150, 100, 20).Name = "Textbox1"
pptMainSlide.Shapes.AddTextbox(msoTextOrientationHorizontal, 100, 200, 100, 20).Name = "Textbox2"
pptMainSlide.Shapes.AddTextbox(msoTextOrientationHorizontal, 100, 250, 100, 20).Name = "Textbox3"
pptMainSlide.Shapes.AddTextbox(msoTextOrientationHorizontal, 100, 300, 100, 20).Name = "Textbox4"
pptMainSlide.Shapes.AddTextbox(msoTextOrientationHorizontal, 100, 350, 100, 20).Name = "Textbox5"
Else
Set pptPresentation = pptApp.ActivePresentation
Set pptMainSlide = pptPresentation.Slides(1)
End If
' Set a reference to the sheet holding the values
Dim contentSheet As Worksheet
Set contentSheet = ThisWorkbook.Worksheets("Sheet1")
' Set the Excel range to be evaluated
Dim contentRange As Range
Set contentRange = contentSheet.Range("A1:AO34")
' Start a cell counter
Dim cellCounter As Long
cellCounter = 1
' Loop through columns and cells
Dim contentColumn As Range
Dim contentCell As Range
For Each contentColumn In contentRange.Columns
For Each contentCell In contentColumn.Cells
' Skip after first blank cell
If contentCell.Value = vbNullString Then Exit For
' Add new slide every 5 cells and fill title
If cellCounter = 1 Then
Set pptContentSlide = pptPresentation.Slides(1).Duplicate()(1)
pptContentSlide.MoveTo pptPresentation.Slides.Count
pptContentSlide.Shapes.Title.TextFrame.TextRange = contentSheet.Cells(35, contentColumn.Column).Value
End If
' Add value to textbox
pptContentSlide.Shapes("Textbox" & cellCounter).TextFrame.TextRange = contentCell.Value
cellCounter = cellCounter + 1
' Reset counter
If cellCounter > 5 Then cellCounter = 1
Next contentCell
Next contentColumn
CleanExit:
' Turn on stuff again
Application.ScreenUpdating = True
If isNewPPTInstance Then
If Not pptApp Is Nothing Then
pptPresentation.SaveAs "C:\Temp\NewPPT.pptx"
pptApp.Quit
End If
End If
Set pptApp = Nothing
Exit Sub
CleanFail:
MsgBox "An error occurred:" & Err.Description
GoTo CleanExit
End Sub
Private Function OpenGetPowerPoint(ByRef isNewPPTInstance As Boolean) As PowerPoint.Application
Dim pptApp As PowerPoint.Application
On Error Resume Next
Set pptApp = GetObject(, "PowerPoint.Application")
If pptApp Is Nothing Then
'PPT wasn't running, start it from code:
Set pptApp = CreateObject("PowerPoint.Application")
isNewPPTInstance = True
End If
Set OpenGetPowerPoint = pptApp
End Function
Let me know if it works

Related

How to copy PPT chart data to XLS most efficiently with VBA

I need to copy chart data from hundreds of PPTX files, each having approx. 40 charts, into an Excel file. This code here runs, after some trial and error, stable, but takes about 2-3 minutes per file. I wonder if there is a faster way to extract the data from the PPTs?
Many thanks for any ideas...
Marco
Sub CopyPPTChartdataToXLS()
Dim ppApp, ppFile, ppSlide, ppShape As Object
Dim ppSlideNr, ppShapeNr As Byte
Dim wsDestination As Worksheet
Set wsDestination = ThisWorkbook.Sheets(1) 'this is the worksheet to insert the data
Set ppApp = CreateObject("PowerPoint.Application")
ppApp.Visible = True
Set ppFile = ppApp.Presentations.Open(Filename:="c:\dummyFile.pptx")
For ppSlideNr = 1 To ppFile.Slides.Count 'runs through all slides
Set ppSlide = ppFile.Slides(ppSlideNr)
For ppShapeNr = 1 To ppSlide.Shapes.Count 'runs through all shapes on slide
Set ppShape = ppSlide.Shapes(ppShapeNr)
With ppShape.Chart.ChartData.Workbook
wsDestination.Range("A2:J101").Value = .Sheets(1).Range("A1:J100").Value
.Close
End With
End If
Call DataProcessing 'sub will use the data for quality checks
Next ppShapeNr
Next ppSlideNr
Set ppSlide = Nothing
Set ppShape = Nothing
Set ppFile = Nothing
Set ppApp = Nothing
End Sub

Excel to PowerPoint VBA

I am trying to paste few cells from Excel to a slide in PowerPoint, using an ActiveX CheckBox in Excel as control. There is no problem of transferring one slide to my designated PowerPoint Presentation, but the problem appears when I ticked more than one box.
So what I do is basically making a temporary template presentation, and when I click on another button called the "Launch" button, it will be pasted to my designated presentation. This is my code:
Private Sub CheckBox1_Click()
If CheckBox1.Value = True Then
Dim PPSlide As PowerPoint.Slide
Dim PPPres As PowerPoint.Presentation
Dim PP As PowerPoint.Application
Set PP = CreateObject("PowerPoint.Application")
Set PPPres = PP.Presentations.Open("(my temporary filename)")
Dim iCheckCount As Integer
iCheckCount = 0
Dim obj As OLEObject
For Each obj In ActiveSheet.OLEObjects
If obj.Object.Value = True Then iCheckCount = iCheckCount + 1
Next
If iCheckCount = 1 Then
Set PPSlide = PPPres.Slides(1)
With PPSlide
.Shapes("Textfeld 2").TextFrame.TextRange.Text = ActiveSheet.Range("G3").Text
.Shapes("Textfeld 3").TextFrame.TextRange.Text = ActiveSheet.Range("B3").Text
.Shapes("Textfeld 4").TextFrame.TextRange.Text = ActiveSheet.Range("C3").Text
.Shapes("Textfeld 5").TextFrame.TextRange.Text = ActiveSheet.Range("D3").Text
.Shapes("Textfeld 6").TextFrame.TextRange.Text = ActiveSheet.Range("F3").Text
End With
PPPres.Slides(1).Copy
Else
If iCheckCount > 1 Then
PPPres.Slides.Paste
PPPres.Slides(2).Copy
Set PPSlide = PPPres.Slides(1)
With PPSlide
.Shapes("Textfeld 2").TextFrame.TextRange.Text = ActiveSheet.Range("G3").Text
.Shapes("Textfeld 3").TextFrame.TextRange.Text = ActiveSheet.Range("B3").Text
.Shapes("Textfeld 4").TextFrame.TextRange.Text = ActiveSheet.Range("C3").Text
.Shapes("Textfeld 5").TextFrame.TextRange.Text = ActiveSheet.Range("D3").Text
.Shapes("Textfeld 6").TextFrame.TextRange.Text = ActiveSheet.Range("F3").Text
End With
End If
End If
End If
End Sub
I know that it won't work for more than 2 boxes (copied to designated Presentation). So my questions are:
1) How can you copy more than 1 Slide at once? I´ve tried
For i = 1 to PPPres.Slides.Count
PPPres.Slides.Item(i).Copy
Next i
but it won't work.
2) I found an if code for every ticked ActiveX CheckBox I have. But the problem is, how can I mention all the Sub for CheckBox_Click and ask the program to do it? The names of the Sub are Box1, Box2, Box3,...,Box46.
I know that my questions are really messy and I'm not explaining it very well since I am also new to VBA. Don't hesitate to ask me if you want to know more about my code.
Thankyou!
You may use e.g:
ActivePresentation.Slides.Range(Array(1, 2, 3)).Duplicate
' Or
For i = 1 to PPPres.Slides.Count
PPPres.Slides.Item(i).Duplicate
Next i

Reading data from a table does not work in particular table

I am currently trying to create a new PPT presentation by deleting unwanted slides from a presentation. The slides - and their slide numbers - are being selected in the first column of a table I have in Excel.
I tried to solve this problem by taking another table instead of the one I want to use and it worked. For some reason it seems not work with the "Table 3".
Sub CreatingNewPresentation()
Dim Destination1PPT As String
Dim ppApp As PowerPoint.Application
Dim ppPres As PowerPoint.Presentation
Dim ppSlide As PowerPoint.Slide
Dim myTable As ListObject
Dim TempArray As Variant
Dim x As Long
If MsgBox("This can take a while", vbOKCancel + vbExclamation, "Creating new presentation") = vbCancel Then
Exit Sub
Else
Set ppApp = CreateObject("PowerPoint.Application")
Destination1PPT = "C:\Users\Steffen\Desktop\Test2\1.pptx"
Set ppPres = ppApp.Presentations.Open(Destination1PPT)
ppApp.Visible = True
ppApp.Activate
Set myTable = ActiveSheet.ListObjects("Table3")
TempArray = myTable.ListColumns(1).DataBodyRange
For x = ppApp.ActivePresentation.Slides.Count To 1 Step -1
If IsError(Application.Match(x, TempArray, False)) Then
ppApp.ActivePresentation.Slides(x).Delete
End If
Next
End If
End Sub
I expect the code to open the presentation and delete all slides except the ones I store in "Table3" - column 1.
What it does instead is just open the presentation and nothing else. There is no error message.
I found the "stupid" mistake I made. I was getting ALL data entries of the referred table instead only getting the visible data entries.
This helps:
Set myTable = ThisWorkbook.Sheets("Sheet1").ListObjects("Table3")
TempArray = myTable.ListColumns(1).DataBodyRange.SpecialCells(xlCellTypeVisible)

Issue plotting excel tables to multiple powerpoint slides

I have created a template on excel which is populated with data for a specific country. The template contains 3 tables and a chart (line graph). I have a list of countries that I need to loop through, and for each loop, I need to create a powerpoint slide made up of the 3 tables and chart.
I build the macro below using bits from various sources (mostly from this platform). The macros scales and positions each of the elements. The first slide populates correctly, but I am running into the following issues:
All the tables and charts are positioned correctly on the first slide, but are not being positioned on every other slide. Note that the objects are still being scaled correctly
I get Run-time error ‘-214788160 (80048240): Selection (unknown member) : Invalid request. This view does not support selection
Does anyone have any suggestions for what the issue could be?
Sub MulipleCountrySlides()
'Step 1: Declare your variables
Dim ListOfSystems As Variant
Dim pptLayout As CustomLayout
Dim PP As PowerPoint.Application
Dim PPPres As PowerPoint.Presentation
Dim PPSlides As PowerPoint.Slides
Dim PPSlide As PowerPoint.Slide
Dim SlideTitle As String
Dim XLS_Out As Variant
Dim shp As Object
Dim chtObj As ChartObject
Dim chtTop As Double
Dim chtLeft As Double
Dim chtWidth As Double
Dim chtHeight As Double
'Step 2: Open PowerPoint and create new presentation
Set PP = New PowerPoint.Application
Set PPPres = PP.Presentations.Add
PP.Visible = True
'Step 3: Add new slide as slide 1 and set focus to it
PPPres.ApplyTemplate "C:\Users\yogeswaran saravanan\AppData\Roaming\Microsoft\Templates\blank.potx"
ListOfSystems = Range("listofsystemstest") 'This is the list of systems that I will be looping through
For y = LBound(ListOfSystems) To UBound(ListOfSystems)
Set PPSlide = PPPres.Slides.Add(y, ppLayoutTitleOnly)
Worksheets("System output sheet").Range("j2").Value = ListOfSystems(y, 1)
Sheets("Indexed data").Calculate
ActiveSheet.Calculate
If Not Application.CalculationState = xlDone Then ' Calculation takes a while to run
DoEvents
End If
Set PPSlide = PPPres.Slides(y)
'The following arrays specify the regions/charts to be copied/pasted,
'the sizes/positions of these regions/charts, and the slide numbers corresponding
'to region/chart destinations
'Region/chart widths (Length/width ratios are preserved)
OWidth = Array(910, 450, 900, 465) '' 72px per Inch
OHeight = Array(400, 120, 33, 147)
'Horizontal positions on slides
OLeft = Array(22, 22, 22, 22)
'Vertical positions on slides
OTop = Array(100, 360, 504, 200)
'Regions and charts to be copied/pasted
XLS_Out = Array(Range("Countryslidetable"), _
Range("Chartdeltas"), _
Range("Countryfootnote"), _
Worksheets("System output sheet").ChartObjects("Chart 1"))
'Region/Chart type: 1 corresponds to chart objects, 0 corresponds to regions
XLS_OutFormat = Array(0, 0, 0, 1)
'Loop through arrays and copy/paste regions and charts one at a time
For x = 0 To 3 'LBound(MySlideArray) To UBound(MySlideArray)
'Copy Excel range/chart
XLS_Out(x).Copy
'Paste to PowerPoint
If (XLS_OutFormat(x) = 0) Then
'Paste an Excel range
Set shp = PPPres.Slides(y).Shapes.PasteSpecial(ppPasteHTML)
Else
'Paste an Excel chart
Set shp = PPPres.Slides(y).Shapes.PasteSpecial(ppPasteShape)
shp.LinkFormat.BreakLink
End If
'Change position/size of pasted regions/charts based on previously-defined arrays
With PPPres.Slides(y)
'shp.LockAspectRatio = msoTrue
shp.Height = OHeight(x)
shp.Width = OWidth(x)
shp.Top = OTop(x)
shp.Left = OLeft(x)
shp.ZOrder msoSendToFront
'End With
If (XLS_OutFormat(x) = 0) Then
If (x = 2) Then
PP.ActiveWindow.Selection.ShapeRange.TextEffect.FontSize = 10
End If
If (x = 0) Then
'Set oShp = PPSlide.Shapes(1)
'Set oShp = PP.ActiveWindow.Selection.ShapeRange
Set oTbl = shp.Table
For i = 1 To oTbl.Columns.Count
For J = 1 To oTbl.Rows.Count
'oShp.TextFrame.TextRange.Font.Size = 11
oTbl.Cell(J, i).Shape.TextFrame.TextRange.Font.Size = 11
Next
Next
End If
End If
End With
Next x
'Step 6: Add the title to the slide
SlideTitle = "Country Price Recommendations: " & Worksheets("System output sheet").Range("J2")
PPPres.Slides(y).Shapes.Title.TextFrame.TextRange.Text = SlideTitle
'Step 7: Memory Cleanup
PP.Activate
Next y
Set PPSlide = Nothing
Set PPPres = Nothing
Set PP = Nothing
End Sub

Use of CommandBars.ExecuteMso problems

Berry is a Range of multiple cells from another excel file and Melon is a table in a powerpoint slide. I am attempting to paste Berry into the ppt table, by first selecting the cell(3,2) on the ppt table. After doing so, I would like to unselect anything. and select cell(3.7).
The following code successfully pastes the range into the table with Cell(3,2) in the top left corner.
Berry.Copy
Melon.Table.Cell(3, 2).Shape.Select
Lemon.CommandBars.ExecuteMso ("PasteExcelTableDestinationTableStyle")
However, when i try the following code, the range gets pasted into the table with Cell(3,7) in the top left corner. I would think the range will get pasted as per earlier followed by merely have the Cell(3,7) selected without any pasting.
Berry.Copy
Melon.Table.Cell(3, 2).Shape.Select
Lemon.CommandBars.ExecuteMso ("PasteExcelTableDestinationTableStyle")
Melon.Table.Cell(3, 7).Shape.Select
It seems like the ExecuteMso code always get executed as the last line of code.
Pardon my english and I thank you for your time and help.
The following is the complete code:
Sub Auto()
Application.CutCopyMode = False
Dim apple As Workbook
Dim grape As Workbook
Dim orange As Range
Dim Kiwi As Shape 'Shape
Dim Peach As Object
Dim Berry As Range
Dim pear As Range
Dim Lemon As PowerPoint.Application 'PPApp
Dim LemonJuice As PowerPoint.Presentation 'PPpres
Dim Melon As PowerPoint.Shape
Dim LCounter As Integer
Set grape = Workbooks.Open(Filename:="C:\Users\206521654\Documents\Automate vba\try.xlsx")
Set apple = Workbooks.Open(Filename:="C:\Users\206521654\Documents\Automate vba\Monthly Report\Msia\Weekly Channel Ranking Broken Out.xlsx")
Set orange = apple.Sheets("Periods").Range("A5:C25")
orange.Copy
grape.Sheets("Sheet1").Range("B3:D23").PasteSpecial xlPasteValues
grape.Sheets("Sheet1").Range("E3").Formula = "=D3/C3-1"
Set SourceRange = grape.Sheets("Sheet1").Range("E3")
Set fillRange = grape.Sheets("Sheet1").Range("E3:E23")
SourceRange.AutoFill Destination:=fillRange
grape.Sheets("Sheet1").Range("E3:E23").NumberFormat = "0%"
grape.Sheets("Sheet1").Range("B3:E23").Font.Name = "Calibri"
grape.Sheets("Sheet1").Range("B3:E23").Font.Size = "11"
grape.Sheets("Sheet1").Range("C3:D23").NumberFormat = "0.000"
For Each Cell In grape.Sheets("Sheet1").Range("E3:E23")
If Cell.Value < 0 Then
Cell.Font.Color = vbRed
Else:
Cell.Font.Color = vbBlue
End If
Next
Set Berry = grape.Sheets("Sheet1").Range("B3:E23")
Berry.Copy
Set Lemon = New PowerPoint.Application
Set LemonJuice = Lemon.Presentations.Open("C:\Users\206521654\Documents\Automate vba\Automate test.pptx")
Set Melon = LemonJuice.Slides(1).Shapes(8)
Melon.Table.Cell(3, 2).Shape.Select
Lemon.CommandBars.ExecuteMso "PasteExcelTableDestinationTableStyle"
Melon.Table.Cell(7, 2).Shape.Select
End Sub
So here is some example code that takes an open excel document and open powerpoint and copies over the table data from excel into a NEW table in powerpoint.
You MUST add the powerpoint reference to your excel VBA.
Put something in cells 2,2 and 2,3 in excel, it should be pasted over into a new table in powerpoint.
Note: Since I merely mashed a bunch of code from the documentation together, you get some unnecessary functionality such as creating a new table every time and modifying all tables, but I hope that this code serves as a necessary base for showing you how you can avoid using msoExecute.
Option Explicit
Sub TestCopyData()
Dim sSht As Worksheet
Set sSht = ActiveWorkbook.Sheets("Sheet1")
Dim PPApp As PowerPoint.Application
Dim PPPres As PowerPoint.Presentation
Dim PPSlide As PowerPoint.Slide
'Open PPT if not running, otherwise select active instance
On Error Resume Next
Set PPApp = GetObject(, "PowerPoint.Application")
On Error GoTo 0
If PPApp Is Nothing Then
'Open PowerPoint
Set PPApp = CreateObject("PowerPoint.Application")
PPApp.Visible = True
End If
PPApp.ActivePresentation.Slides(1).Shapes _
.AddTable NumRows:=3, NumColumns:=4, Left:=10, _
Top:=10, Width:=288, Height:=288
Dim sh As Integer
Dim col As PowerPoint.Column
With PPApp.ActivePresentation.Slides(1)
For sh = 1 To .Shapes.Count
If .Shapes(sh).HasTable Then
For Each col In .Shapes(sh).Table.Columns
Dim cl As PowerPoint.Cell
For Each cl In .Shapes(sh).Table.Rows(2).Cells
cl.Shape.Fill.ForeColor.RGB = RGB(50, 125, 0)
Next cl
.Shapes(sh).Table.Columns(1).Width = 110
.Shapes(sh).Table.Cell(2, 1).Shape.TextFrame.TextRange.Text = sSht.Cells(2, 2)
.Shapes(sh).Table.Cell(2, 2).Shape.TextFrame.TextRange.Text = sSht.Cells(2, 3)
Next col
End If
Next
End With
End Sub

Resources