Im using the below code to iterate over a table in excel that contains named ranges and position details for cells id like to copy over to a powerpoint presentation.
The code works perfectly. Except that, and for some reason its always random, the code throws a "Shapes.paste invalid request clipboard is empty" error. Debugging didnt help since it always stops at a different object or named range. I know VBA is a little finicky with its operations in that it starts the paste before actually completing the copy operation.
I tried the Application.Wait function which isnt the best solution, it slowed the code by 3 fold. As well do/doevents calls didnt help.
Any ideas on how to curb this VBA issue ??
Thanks!
Sub MyProcedure(PPT As Object, WKSHEET As String, RangeTitle As Range, SlideNumber As Long, FTsize As Variant, FT As Variant, SetLeft As Variant, SetTop As Variant, SetHeight As Variant, SetWidth As Variant, Bool As Boolean)
Dim shP As Object
Dim myShape As Object
Dim mySlide As Object
Dim tempSize As Integer, tempFont As String
Dim Mypath As String
Dim Myname As String
Dim myTitle As String
Dim ws As Worksheet
'Application.Calculation = xlManual
'Application.ScreenUpdating = False
Set ws = Worksheets(WKSHEET)
'select the name of report
Set shP = ws.Range(RangeTitle)
'select the ppt sheet you wish to copy the object to
Set mySlide = PPT.ActivePresentation.slides(SlideNumber)
'count the number of shapes currently on the PPT
shapeCount = mySlide.Shapes.Count
'copy the previously selected shape
Do
shP.Copy
'paste it on the PPT
DoEvents
mySlide.Shapes.Paste 'Special DataType:=ppPasteOLEObject, Link:=msoFalse
'wait until the count of shapes on the PPT increases, which signals that the past operation is finished.
'<~~ wait completion of paste operation
Loop Until mySlide.Shapes.Count > shapeCount
'adjust formatting of the newly copied shape: position on the sheet, font & size
Set myShape = mySlide.Shapes(mySlide.Shapes.Count)
With myShape
.Left = SetLeft
.Top = SetTop
.Width = SetWidth
.Height = SetHeight
.TextEffect.FontSize = FTsize
.TextEffect.FontName = FT
.TextEffect.FontBold = Bool
End With
'Application.CutCopyMode = False
'Application.Calculation = xlAutomatic
'Application.ScreenUpdating = True
End Sub
Sub LoopThrougMyData()
Dim FirstRow As Integer: FirstRow = 1
Dim LastRow As Integer: LastRow = Worksheets("Table").Range("A1").End(xlDown).Row
Dim iRow As Long
Dim PPT As Object
Set PPT = CreateObject("PowerPoint.Application")
Myname = ThisWorkbook.Name
Mypath = ThisWorkbook.Path
PPT.Visible = True
PPT.Presentations.Open Filename:=Mypath & "\Actuals Review Temp.pptx"
For iRow = FirstRow To LastRow 'loop through your table here
With Worksheets("Table").Range("test")
MyProcedure PPT, WKSHEET:=.Cells(iRow, "A"), RangeTitle:=.Cells(iRow, "B"), SlideNumber:=.Cells(iRow, "C"), FTsize:=.Cells(iRow, "D"), FT:=.Cells(iRow, "E"), SetLeft:=.Cells(iRow, "F"), SetTop:=.Cells(iRow, "G"), SetHeight:=.Cells(iRow, "H"), SetWidth:=.Cells(iRow, "I"), Bool:=.Cells(iRow, "J")
'call the procedure with the data from your table
End With
Next iRow
End Sub
It's more than likely a clipboard issue. This is a common bug in VBA when copying information from one application to the other application. The best solution I've found so far is simply pausing the Excel application for a few seconds in between the copy and paste. Now this won't fix the issue in every single instance but I would say 95% of the time it fixes the error. The other 5% of the time is simply the information being removed from the clipboard randomly.
Change this section:
shP.Copy
'paste it on the PPT
DoEvents
mySlide.Shapes.Paste 'Special DataType:=ppPasteOLEObject, Link:=msoFalse
With this:
'Copy the shape
shP.Copy
'Pause the Excel Application For Two Seconds
Application.Wait Now() + #12:00:02 AM#
'Paste the object on the slide as an OLEObject
mySlide.Shapes.Paste 'Special DataType:=ppPasteOLEObject, Link:=msoFalse
Related
I have an excel sheet that has the data, I have a powerpoint presentation that has a few charts. I need to run a report eveyday, so i am trying to automate it. I wrote a vba script to copy and paste the data from excel sheet to the chart in powerpoint . But i am unable to change the selection region(the data that is displayed on the graph eventhough there may be more data).
I have written the following script. Any help that helps me change the data to be displayed on the chart is appreciated.
Private Sub CommandButton1_Click()
Dim r As Range
Dim powerpointapp As Object
Dim mypresentation As Object
Dim myslide As Object
Dim myshape As Object
Dim ppath As String
Dim titlesh As Object
Dim tdate As String
Dim chartsh As Object
tdate = Format(Date, "mmmm dd, yyyy")
ppath = "path to ppt"
Set powerpointapp = CreateObject(class:="PowerPoint.Application")
Set mypresentation = powerpointapp.Presentations.Open(ppath)
Set myslide = mypresentation.Slides(1)
Set titlesh = myslide.Shapes("Dateh")
titlesh.TextFrame.TextRange.Text = tdate
Set myslide = mypresentation.Slides(2)
Set chartsh = myslide.Shapes("Chart 6")
chartsh.Chart.ChartData.Workbook.Sheets(1).Cells.Clear
Set r = ThisWorkbook.Worksheets("Weekly Tracking").Range("B84:C158")
r.Copy
chartsh.Chart.ChartData.Workbook.Sheets(1).Range("A2:B74").Value = r.Value
powerpointapp.Visible = True
powerpointapp.Activate
Application.CutCopyMode = False
End Sub
Depends on what your data looks like. You may use .end or usedrange or a loop to looking for keyword in order to locate the end of data.
Some code just to demo the idea:
Dim lastline1 As Long, lastline2 As Long
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets("Weekly Tracking")
lastline1 = ws.Cells(84, 2).End(xlDown).Row() 'Need to check whether row 84 is the last row, otherwise it may fly to 65536 or 1048576.
lastline2 = ws.UsedRange(ws.UsedRange.Rows.Count, ws.UsedRange.Columns.Count).Row
Set r = ThisWorkbook.Worksheets("Weekly Tracking").Range("B84:C" & lastline2)
I am trying to prepare a presentation from Excel. As of now VBA code is preparing "n number of "presentations as per no of times Loop runs. I want Code to generate just 1 presentation with all slides combined. Fist Macro "Addnumber" is run, which run Macro "ExcelRangeToPowerPoint". Its Macro "ExcelRangeToPowerPoint"which need to add slides for every loop of Macro "Addnumber"
Please Support
Sub AddNumber()
Dim Ws As Worksheet
Dim rngSel As Range
Dim rng As Range
Dim Num As Double
Dim i As Long
Dim j As Long
Dim lAreas As Long
Dim lRows As Long
Dim lCols As Long
Dim Arr() As Variant
Set rngSel = Worksheets("Sheet1").Range("A5:A30")
Do Until Range("A30") = Range("A3")
Num = 26
For Each rng In rngSel.Areas
If rng.Count = 1 Then
rng = rng + Num
Else
lRows = rng.Rows.Count
lCols = rng.Columns.Count
Arr = rng
For i = 1 To lRows
For j = 1 To lCols
Arr(i, j) = Arr(i, j) + Num
Next j
Next i
rng.Value = Arr
End If
Call ExcelRangeToPowerPoint
Next rng
Loop
End Sub
Sub ExcelRangeToPowerPoint()
'PURPOSE: Copy/Paste An Excel Range Into a New PowerPoint Presentation
Dim rng As Range
Dim rng2 As Range
Dim PowerPointApp As Object
Dim myPresentation As Object
Dim mySlide As Object
Dim myShape As Object
Dim mySize As PageSetup
Dim Addtitle As Shape
Dim DateT As String
'Copy Range from Excel
Set rng = Worksheets("Sheet1").Range("E2:M30")
Set rng2 = Worksheets("Sheet1").Range("F2")
Set rng3 = Worksheets("Sheet1").Range("B3")
'Create an Instance of PowerPoint
On Error Resume Next
'Is PowerPoint already opened?
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
'Clear the error between errors
Err.Clear
'If PowerPoint is not already open then open PowerPoint
If PowerPointApp Is Nothing Then Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
'Handle if the PowerPoint Application is not found
If Err.Number = 429 Then
MsgBox "PowerPoint could not be found, aborting."
Exit Sub
End If
On Error GoTo 0
'Optimize Code
Application.ScreenUpdating = False
'Create a New Presentation
Set myPresentation = PowerPointApp.Presentations.Add
'Add a slide to the Presentation
Set mySlide = myPresentation.Slides.Add(1, 11)
'11 = ppLayoutTitleOnly
'Change Theme and Layout
mySlide.ApplyTheme "C:\Users\davinder.sond\AppData\Roaming\Microsoft\Templates\Document Themes\DefaultTheme.thmx"
myPresentation.PageSetup.SlideSize = 3
myPresentation.Slides(1).Shapes.Title.TextFrame.TextRange.Text = rng2
myPresentation.Slides(1).Shapes.Title.Left = 59
myPresentation.Slides(1).Shapes.Title.Top = 10
myPresentation.Slides(1).Shapes.Title.Height = 30
myPresentation.Slides(1).Shapes.Title.Width = 673
With myPresentation.Slides(1).Shapes.Title
With .TextFrame.TextRange.Font
.Size = 24
.Name = "Arial"
.Bold = True
.Color.RGB = RGB(255, 255, 255)
End With
End With
'Copy Excel Range
rng.Copy
'Paste to PowerPoint and position
mySlide.Shapes.PasteSpecial DataType:=2 '2 = ppPasteEnhancedMetafile
Set myShape = mySlide.Shapes(mySlide.Shapes.Count)
'Set position:
myShape.LockAspectRatio = 0
myShape.Left = 12
myShape.Top = 55
myShape.Height = 475
myShape.Width = 756
'Make PowerPoint Visible and Active
PowerPointApp.Visible = True
PowerPointApp.Activate
DateT = Format("h:mm:ss")
'Clear The Clipboard
Application.CutCopyMode = False
myPresentation.SaveAs "C:\Project Control CCJV\ExperimentsPunch\" & rng3 & ".pptm"
PowerPointApp.Quit
End Sub
You are creating a new presentation everytime you call Set myPresentation = PowerPointApp.Presentations.Add within ExcelRangeToPowerPoint().
You can either try to open/close the Presentation outside of ExcelRangeToPowerPoint() and add a parameter to the function like ExcelRangeToPowerPoint(myPresentationObject) then you can simple add the slides there
or
you call the function AddNumber() within ExcelRangeToPowerPoint() of coarse the you need to loop there...
e.g.
Sub ExcelRangeToPowerPoint()
' some preparative code
'Create a New Presentation
Set myPresentation = PowerPointApp.Presentations.Add
'Add a slide to the Presentation
Set mySlide = myPresentation.Slides.Add(1, 11)
For Each rng in rngSel.Areas
'Filling the presentation one slide at a time
AddSlide(rng)
Next
'Clear The Clipboard
Application.CutCopyMode = False
myPresentation.SaveAs "C:\Project Control CCJV\ExperimentsPunch\" & rng3 &
".pptm"
PowerPointApp.Quit
'some more code
End Sub
I have specific columns' names in Excel that I want to copy and paste into PowerPoint but I can't run the code because I get "Run Error 424." I have tried using ("B3:Q3") for the columns and that works. However, I don't want all those columns, I only want the columns that are listed below ("b3,f3,l3,n3,p3,q3").
Can anyone assist? Thank you so much!
Sub ExcelRangeToPowerPoint()
Dim rng As Range
Dim rng1 As Range
Dim PowerPointApp As Object
Dim myPresentation As Object
Dim mySlide As Object
Dim myShape As Object
'Copy Range from Excel
Set rng = ThisWorkbook.ActiveSheet.Range("b3,f3,l3,n3,p3,q3").Select 'THIS IS THE ERROR
Set rng1 = ThisWorkbook.ActiveSheet.Range("G4:I4")
'Create an Instance of PowerPoint
On Error Resume Next
'Is PowerPoint already opened?
Set PowerPointApp = GetObject(class:="PowerPoint.Application")
'Clear the error between errors
Err.Clear
'If PowerPoint is not already open then open PowerPoint
If PowerPointApp Is Nothing Then Set PowerPointApp = CreateObject(class:="PowerPoint.Application")
'Handle if the PowerPoint Application is not found
If Err.Number = 429 Then
MsgBox "PowerPoint could not be found, aborting."
Exit Sub
End If
On Error GoTo 0
'Optimize Code
Application.ScreenUpdating = False
'Create a New Presentation
Set myPresentation = PowerPointApp.Presentations.Add
'Add a slide to the Presentation
Set mySlide = myPresentation.Slides.Add(1, 11) '11 = ppLayoutTitleOnly
'Copy Excel Range
rng.Copy
'Paste to PowerPoint and position
mySlide.Shapes.PasteSpecial DataType:=7 '7 = ppPasteText
Set myShape = mySlide.Shapes(mySlide.Shapes.Count)
'Set position:rng
myShape.Left = 70
myShape.Top = 150
myShape.Width = 800
myShape.Height = 100
'Copy Excel Range
rng1.Copy
'Paste to PowerPoint and position
mySlide.Shapes.PasteSpecial DataType:=7 '7 = ppPasteText
Set myShape = mySlide.Shapes(mySlide.Shapes.Count)
'Set position:rng
myShape.Left = 70
myShape.Top = 200
myShape.Width = 800
myShape.Height = 300
'Insert the tile on the ppt
mySlide.Shapes.Title.TextFrame.TextRange.Text = "Insert Title Here"
'Make PowerPoint Visible and Active
PowerPointApp.Visible = True
PowerPointApp.Activate
'Clear The Clipboard
Application.CutCopyMode = False
End Sub
Take off the .Select.
1) You can't Set Rng = [whatever].Select. You want to do Set Rng = [whatever] then Rng.Select on a new line, but more importantly,
2) It's best to Avoid using .Select/.Activate. Although you don't seem to use it elsewhere (good!), so I bet this is just a "typo".
Also, if you want the Columns then you would do:
Set rng = ThisWorkbook.ActiveSheet.Range("b3,f3,l3,n3,p3,q3").EntireColumn
Edit: This won't solve the issue of it pasting the in-between columns, but this (admittedly a little klunky) code will select just the data used (including headers), instead of the entire columns:
'Copy Range from Excel
Dim lastRow As Long
With ThisWorkbook.ActiveSheet
lastRow = .Cells(Rows.Count, 2).End(xlUp).Row
' I assume your headers actually are in row 3, and the data is in row 4 on ward:
Set rng = ThisWorkbook.ActiveSheet.Range("b3:B" & lastRow & ",f3:F" & lastRow & ",l3:l" & lastRow & ",n3:N" & lastRow & ",p3:P" & lastRow & ",q3:Q" & lastRow)
Set rng1 = ThisWorkbook.ActiveSheet.Range("G4:I4")
End With
'Create an Instance of PowerPoint
On Error Resume Next
' Etc. etc.
I have got this error massage during merging the content of several excel files into one. I know this occurs because there is not much space left.
Can anyone help me how to include a rule like if the space is not enough then open a new worksheet and paste the remaining content there?
This is it:
Sub simpleXlsMerger()
Dim bookList As Workbook
Dim mergeObj As Object, dirObj As Object, filesObj As Object, everyObj As Object
Application.ScreenUpdating = False
Set mergeObj = CreateObject("Scripting.FileSystemObject")
Set dirObj = mergeObj.Getfolder("C:\Users\JudakV\Desktop\xxxmacro\")
Set filesObj = dirObj.Files
For Each everyObj In filesObj
Set bookList = Workbooks.Open(everyObj)
Range("A2:IV" & Range("1000000").End(xlUp).Row).Copy
ThisWorkbook.Worksheets(1).Activate
Range("A1000000").End(xlUp).Offset(1, 0).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
bookList.Close
Next
End Sub
There is a report of mine which requires to copy and paste the content of several (about 20) excel files into one single file, and if it has more than 1M rows (usually more than that) then open a new worksheet and copy the remaining part there.
I am not good at macros, but it could spare lots of time for me if it would work. But I am troubling with the page limit and to open a new worksheet part kind of stuff...
This code will copy the data to new sheets. I haven't tested on massive amounts of data, but should work.
Public Sub XLMerger()
Dim oFSO As Object
Dim oDir As Object
Dim oFiles As Object
Dim oFle As Object
Dim wrkBk As Workbook
Dim tgtLastCell As Range 'Target last cell.
Dim srcLastCell As Range 'Source last cell.
Dim lRequiredRows As Long
Dim lAvailableRows As Long
Dim tgtSheet As Worksheet
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oDir = oFSO.GetFolder(""C:\Users\JudakV\Desktop\xxxmacro\"")
Set oFiles = oDir.Files
'Will be pasting data into this sheet.
Set tgtSheet = ThisWorkbook.Worksheets("Sheet1")
For Each oFle In oFiles
If InStr(oFle.Type, "Excel") > 0 Then
Set wrkBk = Workbooks.Open(Filename:=oFle, ReadOnly:=True)
'Set reference to last cell on Target sheet.
With tgtSheet
'If there is data on the very last row an
'incorrect reference will be returned.
If .Cells(.Rows.Count, 1) <> "" Then
Set tgtLastCell = .Cells(.Rows.Count, 1)
Else
Set tgtLastCell = .Cells(.Rows.Count, 1).End(xlUp)
End If
End With
With wrkBk.Worksheets("Sheet1")
'Set reference to last cell on Source sheet.
Set srcLastCell = .Cells(.Rows.Count, 1).End(xlUp)
'Will it fit?
lRequiredRows = srcLastCell.Row - 1
lAvailableRows = ThisWorkbook.Worksheets("Sheet1").Rows.Count - tgtLastCell.Row
If lRequiredRows <= lAvailableRows Then
'Straight Copy/Paste as it all fits.
.Range(.Cells(2, 1), .Cells(srcLastCell.Row, 256)).Copy
tgtLastCell.Offset(1).PasteSpecial xlPasteValues
Else
'Copy what we can onto old sheet providing there's at least 1 blank row.
If lAvailableRows > 0 Then
.Range(.Cells(2, 1), .Cells(lAvailableRows + 1, 256)).Copy
tgtLastCell.Offset(1).PasteSpecial xlPasteValues
End If
'Create a new sheet, copy headings over and paste remaining data.
'The IIF command ensures lAvailable rows isn't looking at row 0.
Set tgtSheet = ThisWorkbook.Worksheets.Add
ThisWorkbook.Worksheets("Sheet1").Rows(1).Copy Destination:=tgtSheet.Range("A1")
.Range(.Cells(lAvailableRows + IIf(lAvailableRows = 0, 2, 0), 1), .Cells(srcLastCell.Row, 256)).Copy
tgtSheet.Range("A2").PasteSpecial xlPasteValues
End If
End With
Application.DisplayAlerts = False
wrkBk.Close SaveChanges:=False
Application.DisplayAlerts = True
End If
Next oFle
End Sub
So I am trying to paste a column into powerpoint slide notes but it only grabs one cell and pastes it into the first slide and will not go to the next slide and paste the next cell into the notes of the 2nd slide.
Sub Notes()
Dim PPTApp As PowerPoint.Application
Dim PPTPres As PowerPoint.Presentation
Dim PPTSlide As PowerPoint.Slide
Dim PPTShape As PowerPoint.Shape
Dim strNotes As String
' Amended Dim Sh As Shape to...
Dim Sh As PowerPoint.Shape
'launch powerpoint application
Set PPTApp = New PowerPoint.Application
PPTApp.Activate
'open powerpoint presentation for macmahon off the intranet
Set PPTPres = PPTApp.Presentations.Open("C:\Users)
Sheets("Raw Data").Select
Range("M2:M26").Select
Set PPTSlide = PPTPres.Slides(1)
On Error GoTo errHandler
Do While ActiveCell.Value <> ""
ActiveCell.Copy
With PPTSlide
If PPTSlide.NotesPage.Shapes.Count = 0 Then 'If no shapes to take Notes then add a shape first
PPTSlide.NotesPage.Shapes.AddShape msoShapeRectangle, 0, 0, 0, 0
Sh = PPTSlide.NotesPage.Shapes(1)
'Code change here - did not recognize Sh.TextFrame.TextRange.Text.Paste
'So, I set the object text to value of the active cell and seemed to do the trick
Sh.TextFrame.TextRange.Text = ActiveCell.Value
Else 'has shapes, so see if they take text
For Each Sh In PPTSlide.NotesPage.Shapes
If Sh.HasTextFrame Then
'Code change here - did not recognize Sh.TextFrame.TextRange.Text.Paste
'So, I set the object text to value of the active cell and seemed to do the trick
Sh.TextFrame.TextRange.Text = ActiveCell.Value
End If
Next Sh
End If
End With
Set PPTSlide = PPTPres.Slides.Add(PPTPres.Slides.Count + 1, ppLayoutText)
ActiveCell.Offset(1, 0).Select
Loop
Exit Sub
errHandler:
MsgBox Err.Number & vbTab & Err.Description, vbCritical, "Error"
End Sub
You are setting a fixed reference to slide 1 in this line:
Set PPTSlide = PPTPres.Slides(1)
Instead of that, wrap the code to copy and paste the cell content in a For...Next loop which loops through your desired slides. For example, to loop through all slides in the presentation:
For Each PPTSlide In PPTPres.Slides
With PPTSlide
' Do the things you need to do on this slide
End With
Next
Or manage a pre-defined range of slides:
Dim lSlideIndex As Long
For lSlideIndex = 2 to 5 ' Process slides 2 to 5
With PPTPres.Slides(lSlideIndex)
' Do the things you need to do on this slide
End With
Next