Link to home
Start Free TrialLog in
Avatar of swapna panthangi
swapna panthangi

asked on

Error :Macro to Copy from Excel Worksheets and paste to specific Powerpoint slides

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 move to the next slides and copy the remaining worksheets to the next further slides. I've 20 worksheets in a workbook with different data and with different used Range  with 40 slides in a template of a powerpoint presentation.  So, it is pasting the data in 4th slide but not adjusting it to the slide as it is throwing the error as

Object Doesn't support this property or method a Runtime Eror 438

 
PPslide.Shapes.PasteSpecial DataType:=2 '2 = ppPasteEnhancedMetafile
Set myshape = PPslide.Shapes(PPslide.Shapes.Count)

Open in new window



So, I Need a macro to loop through all the sheets and if the usedrange is not fitting in the current slide then it should automatically  split  and go to next slide and then split and paste the remaining data and even if the data is more than that slide also then it should again go to next slide and  split and paste the data. Likewise it should automatically paste all the remaining worksheets usedrange to slides and adjust its position according to the data.

I'm attaching sample workbook with 3 worksheets with same data as of now. I do have a powerpoint template of around 40 slides in which it should be started from 4th slide to paste to powerpoint from worksheet.

I'm also providing the code which is working currently . Any Suggestions are highly appreciated!!!


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\EOL EOS All Domains_Template.pptx")

    
 m = 4
 '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 = m To 45

'Exit For

'Slidecount = PPpres.Slides.Count
'Set PPslide = PPpres.Slides.Add(5, 33)
PP.ActiveWindow.View.GotoSlide (k)

'Paste to PowerPoint and position
Set PPslide = PPpres.Slides(k)
PPslide.Shapes.PasteSpecial DataType:=2 '2 = ppPasteEnhancedMetafile
Set myshape = PPslide.Shapes(PPslide.Shapes.Count)
  
    'Set position:
      myshape(1).Left = 38
      myshape(1).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


    
'slidecount = PPpres.Slides.Count
'Set PPslide = PPpres.Slides.Add(slidecount + 1, ppLayoutTitle)
'Make PowerPoint Visible and Active
  PP.Visible = True
  PP.Activate


'Clear The Clipboard
  Application.CutCopyMode = True
m = m + 1

Exit For
Next k



End If

Next WS


End Sub

Open in new window



The macro should work with Excel/Powerpoint 2010 or latest

Please provide me the solution for this.

Thank you in advance!!
sample-data.xlsx
Avatar of Neil Fleming
Neil Fleming
Flag of United Kingdom of Great Britain and Northern Ireland image

I don't think your code will do what you want, as it seems to contain several different versions of the "copy" action, some strange loops, and various other things.

Attached is a workbook that I think does what you are looking for, however. The code below works as follows:
  • Switches to Powerpoint or creates a new instance if Powerpoint is not running
  • Opens your presentation
  • Copies the slide format from the first slide
  • Calculates the size available on each slide in which to paste an image from Excel - the code assumes that slide #4 contains a header box and a text area. The maximum size and image position are calculated from this text area (shape #2 on the slide). If your slides do not have these areas, the code will need tweaking.
  • Loops throught each worksheet, chopping the "usedRange" into chunks that will fit on your powerpoint slides
  • Loops through the chunks, copying them and pasting each chunk to a new slide
  • Labels each slide based on source worksheet and chunk number
  • Creates additional slides as needed, using the slide format copied from the first slide (you can change this, of course)
Option Explicit
Dim PP As PowerPoint.Application

Sub copyXL2PP()
'copy Excel worksheet used ranges to Powerpoint slides
Dim PPpres As PowerPoint.Presentation
Dim PPslide As PowerPoint.Slide
Dim PPShape As PowerPoint.Shape, PPTitle As PowerPoint.Shape, PPMain As PowerPoint.Shape
Dim ppLayout As PowerPoint.CustomLayout
Dim ws As Worksheet
Dim iSlide As Long, iMaxWidth As Long, iMaxHeight As Long, iChunkWidth As Long, iChunkHeight As Long, iCount As Long
Dim iLeft As Long, iTop As Long
Dim rAll As Range, rChunk As Range
   
'switch to Powerpoint or create new instance if program not running, calling function startPP
If Not startPP Then
MsgBox ("Can't start Powerpoint")
Exit Sub
End If

DoEvents
Set PPpres = PP.Presentations.Open("\\C:\Users\EOL EOS All Domains_Template.pptx")

'define standard layout based on first slide (change if needed)
Set ppLayout = PPpres.Slides(1).CustomLayout

'get basic frame size etc
iSlide = 4
PP.ActiveWindow.View.GotoSlide (iSlide)
Set PPslide = PPpres.Slides(iSlide)
'NB assumes each slide has a header and text area:
Set PPMain = PPslide.Shapes(2)
'get maximum width and height for image based on size of text area
iMaxWidth = PPMain.Width
iMaxHeight = PPMain.Height
'get left and top for image
iLeft = PPMain.Left
iTop = PPMain.Top

'Loop through worksheets
 For Each ws In Worksheets
    If (ws.Name) <> "EOS" Then
    ws.Activate
    'create range for all used cells
    Set rAll = ws.UsedRange
    'creat range to use for "chunk" copies
    Set rChunk = rAll
    
    'resize copy area to fit slide
    While rChunk.Width > iMaxWidth
    Set rChunk = rChunk.Resize(rChunk.Rows.Count, rChunk.Columns.Count - 1)
    Wend
    iChunkWidth = rChunk.Column + rChunk.Columns.Count
        
    While rChunk.Height > iMaxHeight
    Set rChunk = rChunk.Resize(rChunk.Rows.Count - 1, rChunk.Columns.Count)
    Wend
    iChunkHeight = rChunk.Column + rChunk.Columns.Count
    
    'count number of chunks used
    iCount = 1
    Do
      Do
        Application.CutCopyMode = False
        rChunk.Select
        rChunk.CopyPicture
        PP.ActiveWindow.View.GotoSlide (iSlide)
        Set PPslide = PPpres.Slides(iSlide)
        'set slide title based on worksheet name and chunk #
        Set PPTitle = PPslide.Shapes(1)
        PPTitle.TextFrame.TextRange = "Out of Support, " & ws.Name & " - section " & iCount
        'add image to slide:
        PPslide.Shapes.PasteSpecial DataType:=2 '2 = ppPasteEnhancedMetafile
        Set PPShape = PPslide.Shapes(PPslide.Shapes.Count)
        'Set position:
        PPShape.Left = iLeft
        PPShape.Top = iTop
        'select next chunk to right
        Set rChunk = rChunk.Offset(0, iChunkWidth)
        'increment slide
        iSlide = iSlide + 1
            'add an extra slide if needed
            If iSlide > PPpres.Slides.Count Then
            PPpres.Slides.AddSlide iSlide, ppLayout
            End If
        'increment chunk count
        iCount = iCount + 1
        'loop until all of used area has been covered horizontally
        Loop Until rChunk.Column > rAll.Column + rAll.Columns.Count - 1
        
    'reset chunk to first column of used range and move down by chunk height
    Set rChunk = rChunk.Offset(iChunkHeight, -1 * (rChunk.Column - 1))
    'loop until all of used area has been covered vertically
    Loop Until rChunk.Row > rAll.Row + rAll.Rows.Count - 1
    
    
    End If

Next ws
       
    Application.CutCopyMode = False
    PP.Visible = True
    PP.Activate

End Sub

Open in new window


And here is the function "startPP" that switches to or starts Powerpoint (your code assumed the application was already open).
Function startPP() As Boolean
On Error GoTo errortrap
'initialize Powerpoint>>
'see if app is open:
Set PP = GetObject(, "Powerpoint.Application")
'if not, errorhandler will create an instance
PP.Visible = True
PP.Activate
startPP = True
Exit Function

errortrap:
Select Case Err.Number
'if can't access activeX object, then create one:
Case 429
Set PP = CreateObject("Powerpoint.Application")
DoEvents
Resume Next
Case Else
MsgBox (Err.Number & ": " & Err.Description)
startPP = False
End Select

End Function

Open in new window


The attached workbook also contains a routine called "clearPP" which I wrote for test purposes. This routine opens your presentation, deletes all slides after slide 10, and clears additional shapes and headers from slide 4 onwards.

Hope this is what you wanted. Using your test file, the code creates around 186 slides...
sample-data-PP.xlsm
Avatar of swapna panthangi
swapna panthangi

ASKER

Hi Neil,

Thank you so much for the solution.. I think this would really help me out with the solution what i need exactly. But  when i tried using the code it is throwing error . So , can you please help me out with this even.

I've  a question here that when i'm trying to execute the code while debugging it is throwing error in this lines of code.
Run time Error 1004 Application defined or object defined error

'resize copy area to fit slide
    While rChunk.Width > iMaxWidth
    Set rChunk = rChunk.Resize(rChunk.Rows.Count, rChunk.Columns.Count - 1)
    Wend

Open in new window


Can you please let me know if something needs to change from my side.
Thank you in Advance!!!
hmm.. that looks like you have no text area on the default slide, so imaxwidth is maybe set to zero.

have you tried setting the max width manually?

also possible is that there is a worksheet with zero usedRange.

Do you want to post your workbook here?
Hello Neil,

I'm trying in the same workbook which you have posted here i.e sample-data-PP.xlsm.  

I tried setting maxwidth manually..But even I could see throwing the same error..

Can you please check on this and provide me the solution for this..

Again attaching the same for your Reference.
sample-data-PP.xlsm
Can you post your powerpoint file too? I just ran the file you uploaded and it generated 196 slides without a problem. See attached Powerpoint Pres.

Also wondering if you are clicking on Powerpoint while the routine is running, which might cause a 1004 error at the line
rChunk.Select

Open in new window

.

I would delete that line, since it is actually not necessary and may be complicating things.
ppTest.pptx
Also, just to check. The code IS opening your powerpoint file, right?

the file address ""\\C:\Users\EOL EOS All Domains_Template.pptx" looks odd. Or is it a server address, with a C: drive on the server?
Thank you very much Neil for your Quick Response.

As I see in the PPT there are columns splitting in each slide whereas I need the Rows to be split in the slide when there are more rows which doesn't fit in the slide.  

I'm providing you the sample PPT and sample Data for your reference.

As my post says that I've 20-25 worksheets in a workbook each with different data with different used range but the column header remains same for every Worksheet. So, when I copy the used range in a worksheet if that contains less records which fits in the slide then that copies the header as well but when there are more than the records that doesn't fit in the slide then it should split those rows (For EX: till 25 rows) then from there on it should paste  next 25 rows in the next slide with header and so on till the used range  is completely fit in the next further slides and then should go to  next worksheet and paste that used range in the next slide . After this if there are any worksheets with more rows which doesn't fit to the slide then it should again split and continue the same till the usedrange is fit completely in the slide.


I've given sample data here in the PPT as well as in the Workbook.

I'm changing the path in VBA as I've given sample path..


the file address ""\\C:\Users\EOL EOS All Domains_Template.pptx" looks odd. Or is it a server address, with a C: drive on the server?


Can you also explain this code how is this working here.

'resize copy area to fit slide
  While rChunk.Width > iMaxWidth
          Set rChunk = rChunk.Resize(rChunk.Rows.Count, rChunk.Columns.Count - 1)
   Wend
          iChunkWidth = rChunk.Column + rChunk.Columns.Count
          
  While rChunk.Height > iMaxHeight
    Set rChunk = rChunk.Resize(rChunk.Rows.Count - 1, rChunk.Columns.Count)
 Wend
    iChunkHeight = rChunk.Column + rChunk.Columns.Count

Open in new window



 Thank you in Advance!!
PPT_ExpertsExchange.pptx
SampleData_ExpertsExchange.xlsx
That piece of code works as follows:

iMaxWidth and iMaxHeight are determined earlier in the code by looking at the size of the "text" area on the slide (the assumption is you have a header (shape 1) and a text area (shape 2).

Set PPMain = PPslide.Shapes(2)
'get maximum width and height for image based on size of text area
iMaxWidth = PPMain.Width
iMaxHeight = PPMain.Height

Open in new window


The code starts by setting the range rChunk to cover the whole of the UsedRange on each worksheet.

Then if the width of rChunk is greater than iMaxwidth, the chunk size is reduced by one Excel column until it will fit on the PPT slide.
'resize copy area to fit slide
  While rChunk.Width > iMaxWidth
          Set rChunk = rChunk.Resize(rChunk.Rows.Count, rChunk.Columns.Count - 1)
   Wend
          iChunkWidth = rChunk.Column + rChunk.Columns.Count

Open in new window


The "while" statement checks whether the chunk is wider than iMaxWidth and if it is, it repeatedly resizes the chunk to have one fewer column. Then it  calculates the number of columns in the chunk and stores that value in iChunkWidth to make it easy to move from one chunk to the next later in the code.

The second piece of the code, with iMaxHeight, does the same re-sizing operation with the height of the chunk.

I am trying to understand your explanation of exactly what you want meanwhile.. Do you want the code only to split into row chunks? In other words to resize the pasted image to fit on the slide, no matter how many columns there are?
Yes Neil,

I want the code for splitting the row chunks. Yes, Irrespective of the columns I need the rows to be split when it doesn't fit in a single slide.
ASKER CERTIFIED SOLUTION
Avatar of Neil Fleming
Neil Fleming
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
No comment has been added to this question in more than 21 days, so it is now classified as abandoned.

I have recommended this question be closed as follows:

Accept: Neil Fleming (https:#a42161312)

If you feel this question should be closed differently, post an objection and the moderators will review all objections and close it as they feel fit. If no one objects, this question will be closed automatically the way described above.

MacroShadow
Experts-Exchange Cleanup Volunteer