This question is about a new problem that came up while I was trying to get an addition to something to work I already asked a question about.
What I want my macro to do/what it's already kind of doing:
Add a header to a Word document (same one for the whole document)
Read image files from a specific folder from the HDD and insert them into the document
Add a section break if the image orientation (landscape or portrait) differs from the previous one and set the page orientation for the new section accordingly (BEFORE adding the image)
Add a line break and the file name of the image
Add a page break (each image gets its own page, no matter its size)
To ensure that the name doesn't get pushed to the next page (if the image fills the whole page), I set the bottom margin to a higher value before adding the image and the name and then set the margin back to the original value. This way the image is a little bit smaller and leaves enough space for the name.
My code (see below) does add section breaks but it seems like it sets the orientation for the whole document, not just the current section, so I end up with the same orientation on all pages. The images are also only added in the very last section without any page/section breaks in between.
How do I fix this?
In the other question someone already posted full code to set the orientation but I'd prefer understanding why my code doesn't work as intended to just copying someone else's completely different one.
My code:
Sub ImportImages(path As String)
Dim fs As Object
Dim ff As Variant
Dim img As Variant
Dim i As Long
Dim fsize As Long
Dim bottomMarginOriginal As Single
Dim topMarginOriginal As Single
Dim vertical As Boolean
Dim objShell As New Shell
Dim objFolder As Folder
Dim objFile As ShellFolderItem
Dim width As Integer
Dim height As Integer
Set fs = CreateObject("Scripting.FileSystemObject")
Set ff = fs.GetFolder(path).Files
i = 0
fsize = ff.Count
vertical = True
Set objFolder = objShell.NameSpace(path)
With ActiveDocument
bottomMarginOriginal = .PageSetup.BottomMargin
topMarginOriginal = .PageSetup.TopMargin
For Each img In ff
Select Case Right(img.name, 4)
Case ".bmp", ".jpg", ".gif", ".png", "tiff", ".tif"
Set objFile = objFolder.ParseName(img.name)
width = objFile.ExtendedProperty("{6444048F-4C8B-11D1-8B70-080036B11A03} 3")
height = objFile.ExtendedProperty("{6444048F-4C8B-11D1-8B70-080036B11A03} 4")
If width > height Then
If vertical = False Then 'Already landscape -> just add page break
.Characters.Last.InsertBefore Chr(12)
Else 'Set to landscape
Selection.InsertBreak Type:=wdSectionBreakNextPage
.PageSetup.Orientation = wdOrientLandscape
.PageSetup.TopMargin = topMarginOriginal 'Adjust margins to new orientation
.PageSetup.RightMargin = bottomMarginOriginal
.PageSetup.BottomMargin = bottomMarginOriginal
.PageSetup.LeftMargin = bottomMarginOriginal
.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = "test " & i 'Set header
vertical = False
End If
ElseIf height > width Then
If vertical = True Then 'Already portrait -> just add page break on page 2+
If i <> 0 Then
.Characters.Last.InsertBefore Chr(12)
End If
Else 'Set to portrait
Selection.InsertBreak Type:=wdSectionBreakNextPage
.PageSetup.Orientation = wdOrientPortrait
.PageSetup.TopMargin = topMarginOriginal 'Adjust margins to new orientation
.PageSetup.RightMargin = bottomMarginOriginal
.PageSetup.BottomMargin = bottomMarginOriginal
.PageSetup.LeftMargin = bottomMarginOriginal
.Sections(1).Headers(wdHeaderFooterPrimary).Range.Text = "test " & i 'Set header
vertical = True
End If
Else
If i <> 0 Then
.Characters.Last.InsertBefore Chr(12)
End If
End If
.PageSetup.BottomMargin = bottomMarginOriginal + Application.CentimetersToPoints(1) 'Add 1cm to the bottom margin
i = i + 1
.Characters.Last.InlineShapes.AddPicture filename:=img
.Characters.Last.InsertBefore Chr(11) & img.name
.PageSetup.BottomMargin = bottomMarginOriginal 'Reset bottom margin to default
End Select
Next
End With
End Sub
Here is the concept code based around putting images in Tables. A habit I have acquired from long long use of Word.
At the moment the ParseName keyword isn't being recognised even though I added a reference to Microsoft Shell etc etc.
Not a pagebreak in sight as they are not needed.
Option Explicit
Const PortraitPictureHeight As Long = 0 ' change to cm value
Const PortraitTextHeight As Long = 0 ' change to a cm value
Const LandscapePictureHeight As Long = 0 ' change to a cm value
Const LandscapeTextHeight As Long = 0 ' change to a cm value
Const HeightOfLineAfterTable As Long = 0 ' change to a points
Sub test()
ImportImages "C:\\Users\\slayc\\Pictures"
End Sub
Sub ImportImages(path As String)
Dim fs As Scripting.FileSystemObject
Dim ff As Variant
Dim img As Variant
Dim objShell As Shell
Dim objFolder As Folder
Dim objFile As ShellFolderItem
Dim width As Long
Dim height As Long
Set fs = New Scripting.FileSystemObject
Set ff = fs.GetFolder(path).Files
Set objShell = New Shell
Set objFolder = objShell.NameSpace(path)
' The assumption is that we are adding sections to the end of the document
' so we add the Heder to the last document
' this header will be copied to each section we add to the document
' when we use Activedocument.sections.add
ActiveDocument.Sections.Last.Headers(wdHeaderFooterPrimary).Range.Text = "This is your header"
For Each img In ff
If InStr(".bmp,.jpg,.gif,.png,.tiff", Right(img.Name, 4)) = 0 Then GoTo Continue_img
Set objFile = objFolder.ParseName(img.Name)
width = objFile.ExtendedProperty("{6444048F-4C8B-11D1-8B70-080036B11A03} 3")
height = objFile.ExtendedProperty("{6444048F-4C8B-11D1-8B70-080036B11A03} 4")
' every image gets its own section with its own orientation
If width > height Then
InsertLandscapeSection
Else
InsertPortraitSection
End If
FormatLastTable
With ActiveDocument.Sections.Last.Range.Tables(1).Range
.Rows(1).Range.Cells(1).Range.Characters.Last.InlineShapes.AddPicture FileName:=img
.Rows(2).Range.Cells(1).Range.Text = img.Name
End With
Continue_img:
Next
End Sub
Public Sub InsertLandscapeSection()
Dim my_range As Word.Range
With ActiveDocument.Sections
' Deal with the case where the first section is the last section
If .Last.Range.Tables.Count > 0 Then
.Add
.Last.Range.Previous(unit:=wdParagraph).Font.Size = HeightOfLineAfterTable
End If
.Last.PageSetup.Orientation = wdOrientLandscape
With .Last
Set my_range = .Range.Duplicate
my_range.Collapse direction:=wdCollapseStart
.Range.Tables.Add my_range, 2, 1
With .Range.Tables(1).Range
.Rows.HeightRule = wdRowHeightExactly
.Rows(1).height = CentimetersToPoints(LandscapePictureHeight)
.Rows(2).height = CentimetersToPoints(LandscapeTextHeight)
End With
End With
End With
End Sub
Public Sub InsertPortraitSection()
Dim my_range As Word.Range
With ActiveDocument.Sections
If .Last.Range.Tables.Count > 0 Then
.Add
.Last.Range.Previous(unit:=wdParagraph).Font.Size = HeightOfLineAfterTable
End If
.Last.PageSetup.Orientation = wdOrientPortrait
With .Last
Set my_range = .Range.Duplicate
my_range.Collapse direction:=wdCollapseStart
.Range.Tables.Add my_range, 2, 1
With .Range.Tables(1).Range
.Rows.HeightRule = wdRowHeightExactly
.Rows(1).height = CentimetersToPoints(PortraitPictureHeight)
.Rows(2).height = CentimetersToPoints(LandscapeTextHeight)
End With
End With
End With
End Sub
Sub FormatLastTable()
With ActiveDocument.Sections.Last.Range.Tables(1)
' turn off all borders
.Borders.Enable = False
'Do any additional formatting of the table that is not related to row height
End With
End Sub
Related
my program :
produce a picture that is extracting data from excel .
Paste it in word and make the page setting as Landscape .
However ,the picture generated is small and the setting of page become custom.
the photo is so wide .I don't want to enlarge by myself everytimes.
How can I add this setting in vba ?Make it as large and wide as it can .
Secondly , it is pleasure that the data extracted can be pasted as table format.
my codes :
Private Sub CommandButton1_Click()
Dim tbl0 As Excel.RANGE
Dim Tbl As Excel.RANGE
Dim tbl2 As Excel.RANGE
Dim wordApp As Word.Application
Dim myDoc As Word.Document
Dim WordTable As Word.Table
Dim wb As Workbook
Dim ws As Worksheet
Set wb = ThisWorkbook
Set ws = wb.Worksheets("17-18") ' Change e.g. sheet9.Name
'Optimize Code
Application.ScreenUpdating = False
Application.EnableEvents = False
Value1 = Me.TextBox1.Value
Value2 = Me.TextBox2.Value
ws.Rows("84:89").EntireRow.Hidden = True 'ADJUST AS APPROPRIATE
'Copy Range from Excel
'Set tbl0 = ws.RANGE("A78:I83")
Set Tbl = ws.RANGE("A78:I92")
' Set tbl2 = ws.Range("A90:I92")
'Create an Instance of MS Word
On Error Resume Next
'Is MS Word already opened?
Set wordApp = GetObject(Class:="Word.Application")
'Clear the error between errors
Err.Clear
'If MS Word is not already open then open MS Word
If wordApp Is Nothing Then Set wordApp = CreateObject(Class:="Word.Application")
'Handle if the Word Application is not found
If Err.Number = 429 Then
MsgBox "Microsoft Word could not be found, aborting."
GoTo EndRoutine
End If
On Error GoTo 0
'Make MS Word Visible and Active
wordApp.Visible = True
wordApp.Activate
'Create a New Document
Set myDoc = wordApp.Documents.Add
'Trigger copy separately for each table + paste for each table
Tbl.CopyPicture Appearance:=xlScreen, Format:=xlPicture
wordApp.Selection.Paste
wordApp.Selection.TypeParagraph
wordApp.Selection.PageSetup.Orientation = wdOrientLandscape
resize_all_images_to_page_width myDoc
EndRoutine:
'Optimize Code
Application.ScreenUpdating = True
Application.EnableEvents = True
'Clear The Clipboard
Application.CutCopyMode = False
End Sub
Although I don't fiddle with Word but Excel only it might give you an idea...
The code of my XmasPrep excel sucks in a bunch of pictures in order to produce a catalog, listing the pictures to select from.
For each line, i.e. each picture, the code
assigns an Excel cell range and then resizes the range ROW height and width
as well as the range height itself
assigns the picture object thisPic = .Parent.Pictures.Insert(picFileName) and then resizes that according to the cell range's coordinates and size:
thisPic.Top = .Top + 1
thisPic.Left = .Left + 1
thisPic.Width = .Width - 2
thisPic.Height = .Height - 2
So, if you're able to grab the picture object (thisPic) in Word you might be able to resize it to your needs as well. Hope it helps.
:
Const MaxHeight = 50
Const MaxWidth = 14
Dim picFileName As String
Dim i, j, k As Long
Dim col_Filenames As Long
Dim col_Pictures As Long
Dim range_PicCell As Range
Dim thisPic As Picture
:
picFileName = filesPath & select2order.Cells(i, col_Filenames).Value
Set range_PicCell = select2order.Cells(i, col_Pictures)
range_PicCell.RowHeight = MaxHeight
range_PicCell.ColumnWidth = MaxWidth
With range_PicCell
.Height = MaxHeight
Set thisPic = .Parent.Pictures.Insert(picFileName)
thisPic.Top = .Top + 1
thisPic.Left = .Left + 1
thisPic.Width = .Width - 2
thisPic.Height = .Height - 2
End With
:
I am new to VBA and seeking help on a work project. I have done some research and got started but am now over my head.
My objectives are:
Create a click shape or button (preview/close) that displays an image from another location on computer.
The image displayed will be dependent on the data input (col A: patient name; same name of jpeg image) for each name that is entered in the same row.
Also I would like a new button/shape to be automatically created in the corresponding cell when a new name is added
Thanks Rick
Sub Macro1()
Dim Path As String
Set myDocument = Worksheets(1)
Path = "F:\CAD_CAM division\Unsorted Models\"
myDocument.Pictures.Insert (Path & ActiveCell.Value & ".jpg")
With ActiveSheet.Shapes("Rounded Rectangle 1").TextFrame2.TextRange.Characters
If .Text = "Close" Then
.Text = "Preview"
ActiveSheet.Pictures.Delete
Else
.Text = "Close"
With ActiveSheet.Shapes("Rounded Rectangle 1")
End With
End If
End With
End Sub
While your original code was actually working, I made a few slight adjustments to ensure that all (multiple) pictures are included / shown on the sheet and to align these picture below each other. Have a look at the comments in the code and let me know what you think:
Option Explicit
Sub Macro1()
Dim lngRow As Long
Dim strPath As String
Dim picItem As Picture
Dim shtPatient As Worksheet
'If there are multiple pictures then they should be shown
' underneath each other. dblLeft and dblTop will be used
' to place the next picture underneath the last one.
Dim dblTop As Double
Dim dblLeft As Double
Set shtPatient = ThisWorkbook.Worksheets(1)
strPath = "F:\CAD_CAM division\Unsorted Models\"
With shtPatient.Shapes("Rounded Rectangle 1").TextFrame2.TextRange.Characters
If .Text = "Close" Then
.Text = "Preview"
ActiveSheet.Pictures.Delete
Else
.Text = "Close"
For lngRow = 2 To shtPatient.Cells(shtPatient.Rows.Count, "A").End(xlUp).Row
'First check if the file actually exists / can be found and inserted
If Dir(strPath & shtPatient.Cells(lngRow, 1).Value2 & ".jpg") <> "" Then
Set picItem = shtPatient.Pictures.Insert(strPath & shtPatient.Cells(lngRow, 1).Value2 & ".jpg")
'Name the picture so it can be found afterwards again using VBA
picItem.Name = shtPatient.Cells(lngRow, 1).Value2 & ".jpg"
If lngRow = 2 Then
picItem.Top = shtPatient.Range("F2").Top
picItem.Left = shtPatient.Range("F2").Left
dblTop = picItem.Top + picItem.Height + 10
dblLeft = picItem.Left
Else
picItem.Top = dblTop
picItem.Left = dblLeft
dblTop = picItem.Top + picItem.Height + 10
End If
End If
Next lngRow
End If
End With
End Sub
I need to call a word file from excel, and to create a template. Template will have 3 images UpperLeft, Upper Right and central image.
I thought that would be the best result do it through the table.
From some reason I can't create table from excel..
Private Sub CommandButton13_Click()
'Using early binding, not late-binding
Dim wsDoc As Word.Document
Dim wsApp As Word.Application
Dim wsRng As Word.Range
Dim wsTable as Word.Table
Dim intNoOfRows
Dim intNoOfColumns
Dim s As Word.InlineShape
Dim shp As Word.Shape
intNoOfRows = 4
intNoOfColumns = 2
Set wsApp = New Word.Application
wsApp.Visible = True
Set wsDoc = wsApp.Documents.Add
Set wsRange = wsDoc.Content
Set wsTable = wsDoc.Tables.Add(wsRange, intNoOfRows, intNoOfColumns)
wsTable.Borders.Enable = True
wsTable.Cell(1, 1).Range.InlineShapes.AddPicture _
UserForm1.txtImageLogoAdecco
wsTable.Cell(1, 2).Range.ParagraphFormat.Alignment = wdAlignParagraphRight
wsTable.Cell(1, 2).Range.InlineShapes.AddPicture _
UserForm1.txtImageLogoClient
Set wsRng = wsTable.Cell(2, 1).Range
With wsRng.Paragraphs.Add
wsTable.Cell(2, 1).Merge MergeTo:=wsTable.Cell(2, 2)
wsTable.Cell(2, 1).Height = 520
wsTable.Cell(2, 1).Range.Paragraphs.Add
wsTable.Cell(3, 1).Merge MergeTo:=objTable.Cell(3, 2)
wsTable.Cell(3, 1).Range.Text = "Prepared by:" & " " & UserForm1.txtPrepared
wsTable.Cell(4, 1).Merge MergeTo:=objTable.Cell(4, 2)
wsTable.Cell(4, 1).Range.ParagraphFormat.Alignment = wdAlignParagraphRight
wsTable.Cell(4, 1).Range.Text = "Belgrade," & " " & Format(Date, "MMMM DD, YYYY ")
Set wsRange = Nothing
Set wsTable = Nothing
Set wsDoc = Nothing
Set wsApp = Nothing
End Sub
Well, it's a bit clearer, but not completely. I've taken the liberty of editing your code so that it's correct, consistent and readable (without all the empty lines)!
I'll start with the part that is clear: << I want to move cursor a few lines down and to write some text. >>
To move the focus below a table, you get the table's range, then collapse it. For example:
Set wsRange = wsTable.Range
wsRange.Collapse wdCollapseEnd
'Now the range is in the paragraph following the table
wsRange.Text = "text following table"
"with background image I want to convert it to shape. I want to send iy behind the text"
This is the part that's not clear to me. Are you saying you want to insert one more image and position it behind the text? Use the Shapes.Add method and set the WrapFormat.Type to wdWrapBehind
Whilst this proven method has worked for people and works for me in the general sense, I receive "Error 1004: Method 'Paste' of object '_Chart' failed." However, on the 5th iteration of the loop this method failure occurs. I have tried isolating each component of the Array and the 6th and 7th elements always fail, but when the 5th element is used in isolation or as the starting point of the loop it succeeds. I have also tried clearing the clipboard at different stages of the process to see if that helps and tested the object property of the "cht" object.
Sub PicturesCopy()
'Define path variables
Path = "C:\Users\khill\Documents\Macro Tests\"
PathSC = Path & "Master Cockpit\"
FileMCP = "Master_Daily sales cockpit.xlsm"
Set wbMCP = Workbooks(FileMCP)
Dim cht As ChartObject
Dim rngList, fileList As Variant
rngList = Array("B2:Y19", "B22:U39", "B43:O58", "B61:R76", "B81:J96", "B101:AD118", "B122:V139")
fileList = Array("Fig 1a", "Fig 1b", "Fig 2a", "Fig 2b", "Fig 2c", "Fig 3a", "Fig 3b")
For x = 0 To UBound(rngList)
'Application.CutCopyMode = True
With wbMCP.Worksheets("Graphs")
Debug.Print rngList(x)
Dim rgExp As Range: Set rgExp = .Range(rngList(x))
Debug.Print x
rgExp.CopyPicture Appearance:=xlScreen, Format:=xlPicture
End With
''' Create an empty chart with exact size of range copied
Set cht = wbMCP.Worksheets("Pictures").ChartObjects.Add(Left:=rgExp.Left, Top:=rgExp.Top, _
Width:=rgExp.Width, Height:=rgExp.Height)
cht.Name = "PicChart"
With cht
.Chart.Paste
Debug.Print fileList(x)
.Chart.Export "C:\Users\khill\Documents\Macro Tests\Pics\" & fileList(x) & ".jpg"
.Delete
'Application.CutCopyMode = False
End With
Set cht = Nothing
Set rgExp = Nothing
Next x
End Sub
Have you tried using a clipboard viewer to verify that the rgExp.CopyPicture operation has done what you expect when Debug.Print x shows 5 (6th iteration)?
Assuming you are using some version of Windows, there are some tips on how to view clipboard here, depending on version:
View & Manage Clipboard In Windows 10 / 8 / 7
http://www.thewindowsclub.com/windows-clipboard-manager-viewer
Ok. I found the problem. The charts have to be contained within the viewable screen to be pasted by the clipboard. so you can either zoom out (not ideal because the images are saved small and therefore pixelated) or zoom to the new Chart area/select the position where the chart object is placed in the first place. My solution was to zoom to the range. Adjusted Code is below. Hope this helps someone else :)
Sub PicturesCopy()
'Define path variables
Path = "C:\Users\khill\Documents\Macro Tests\"
PathSC = Path & "Master Cockpit\"
FileMCP = "Master_Daily sales cockpit.xlsm"
Set wbMCP = Workbooks(FileMCP)
Dim cht As ChartObject
Dim rngList, fileList As Variant
rngList = Array("B2:Y19", "B22:U39", "B43:O58", "B61:R76", "B81:J96", "B101:AD118", "B122:V139")
fileList = Array("Fig 1a", "Fig 1b", "Fig 2a", "Fig 2b", "Fig 2c", "Fig 3a", "Fig 3b")
For x = 0 To UBound(rngList)
'Application.CutCopyMode = True
With wbMCP.Worksheets("Graphs")
Debug.Print rngList(x)
Dim rgExp As Range: Set rgExp = .Range(rngList(x))
Debug.Print x
rgExp.CopyPicture Appearance:=xlScreen, Format:=xlPicture
End With
''' Create an empty chart with exact size of range copied
Set cht = wbMCP.Worksheets("Pictures").ChartObjects.Add(Left:=rgExp.Left, Top:=rgExp.Top, _
Width:=rgExp.Width, Height:=rgExp.Height)
cht.Name = "PicChart"
'Use ZoomToRange sub to re-size the window as appropriate
ZoomToRange ZoomThisRange:=Range(rngList(x)), PreserveRows:=True
With cht
.Chart.Paste
Debug.Print fileList(x)
.Chart.Export "C:\Users\khill\Documents\Macro Tests\Pics\" & fileList(x) & ".jpg"
.Delete
'Application.CutCopyMode = False
End With
Set cht = Nothing
Set rgExp = Nothing
Next x
End Sub
The ZoomToRange macro that is called in the above is as follows:
Sub ZoomToRange(ByVal ZoomThisRange As Range, _
ByVal PreserveRows As Boolean)
'###################################
'This macro resizes the window and''
'zoom properties to be appropriate''
'for our use''''''''''''''''''''''''
'###################################
'Turn alerts and screen updating off
Application.DisplayAlerts = False
Application.ScreenUpdating = False
'Declare variable type
Dim Wind As Window
'Create variable for window
Set Wind = ActiveWindow
'Zooming to specified range set to true
Application.GoTo ZoomThisRange(1, 1), True
'Select the resized range
With ZoomThisRange
If PreserveRows = True Then
.Resize(.Rows.Count, 1).Select
Else
.Resize(1, .Columns.Count).Select
End If
End With
'Set zoom and visible range to specified range
With Wind
.Zoom = True
.VisibleRange(1, 1).Select
End With
End Sub
Ok, here is what I am looking for (Im new, so be gentle):
Copy and paste (default format) from excel to powerpoint (from just the one sheet)
I can only fit so many rows in ppt - so after a slide fills, I want ppt to create a new slide
Same title for each slide is fine!
I only need columns B:K copied over
That's it, however I am stuck :( I know the below code is NOT the best way to write this and it contains errors in which I am sure will be easy to spot. I cannot find how to do this anywhere on the net.
This is what I have so far:
Sub ExcelRangeToPowerPoint()
Dim rng As Excel.Range
Dim PowerPointApp As PowerPoint.Application
Dim myPresentation As PowerPoint.Presentation
Dim mySlide As PowerPoint.Slide
Dim myShapeRange As PowerPoint.Shape
Dim i As Integer
'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")
'Make PowerPoint Visible and Active
PowerPointApp.Visible = True
PowerPointApp.Activate
'Create a New Presentation
Set myPresentation = PowerPointApp.Presentations.Add
'Add a slide to the Presentation
Set mySlide = myPresentation.Slides.Add(1, ppLayoutTitleOnly)
For i = 1 To 6
'need to set focus to slde 1
PowerPointApp.ActiveWindow.View.GotoSlide (1)
'Deletes Title
'mySlide.Shapes.Title.Delete
'builds new title
mySlide.Shapes.AddShape Type:=msoShapeRectangle, left:=9, Top:=6, Width:=702, Height:=30
mySlide.Shapes(mySlide.Shapes.Count).Line.Visible = msoTrue
mySlide.Shapes(mySlide.Shapes.Count).TextFrame.TextRange.Font.Size = 20
mySlide.Shapes(mySlide.Shapes.Count).TextFrame.TextRange.Font.Color.RGB = RGB(0, 0, 0)
mySlide.Shapes(mySlide.Shapes.Count).TextFrame.TextRange.ParagraphFormat.Alignment = ppAlignLeft
mySlide.Shapes(mySlide.Shapes.Count).TextFrame.TextRange.Text = "Current Full Initiative Details – Branded Book as of " & Date
mySlide.Shapes(mySlide.Shapes.Count).Name = "I am TITLE"
mySlide.Shapes(mySlide.Shapes.Count).Line.ForeColor.RGB = RGB(0, 0, 0)
mySlide.Shapes(mySlide.Shapes.Count).Line.Weight = 1
mySlide.Shapes(mySlide.Shapes.Count).Fill.Visible = msoTrue
mySlide.Shapes(mySlide.Shapes.Count).Fill.ForeColor.RGB = RGB(255, 255, 255)
'Copy Range from Excel
Set rng = ActiveWorkbook.Worksheets("RAW").Range("B1:K23")
'Copy Excel Range
rng.Copy
'Paste to PowerPoint and position
PowerPointApp.ActiveWindow.View.PasteSpecial DataType:=ppPasteDefault
Set myShapeRange = mySlide.Shapes(mySlide.Shapes.Count)
'Set position:
myShapeRange.left = 10
myShapeRange.Top = 42
myShapeRange.Height = 492
myShapeRange.Width = 702
ActiveWorkbook.Sheets("RAW").Rows("2:23").Delete
Call myPresentation.Slides.Add(1, PpSlideLayout.ppLayoutTitleOnly)
'Clear The Clipboard
Application.CutCopyMode = False
Next i
End Sub
As requested in comments, here is the code I use to copy a slide from a master PPT template to the report PPT.
There is some extraneous code in there to provide status updates on the form we use to drive the process, as well as a debugging flag that I can toggle on/off at run time - these can both be removed.
This will serve as a starting point to finding the proper solution for your situation, and is not a complete answer to the question as asked.
'I've chosen to declare these globally, though it's probably not the best way:
Dim PPTObj As PowerPoint.Application
Dim PPTMaster As PowerPoint.Presentation
Dim PPTClinic As PowerPoint.Presentation
Private Sub InsertPPT(ByVal SlideName As String, ByVal StatusText As String)
Dim Shp As PowerPoint.Shape
Dim Top As Single
Dim Left As Single
Dim Height As Single
Dim width As Single
PPTMaster.Slides(SlideName).Copy
PPTClinic.Slides.Paste
Form_Master.ProcessStatus.Value = StatusText & " InsertPPT"
With PPTClinic.Slides(PPTClinic.Slides.count)
If Debugging Then
.Select
End If
.Design = PPTMaster.Slides(SlideName).Design 'this ensures we get all the right formatting - only seems to be necessary 1 time, but we'll just do it on all
.ColorScheme = PPTMaster.Slides(SlideName).ColorScheme
.FollowMasterBackground = PPTMaster.Slides(SlideName).FollowMasterBackground
For Each Shp In .Shapes 'loop through all the shapes on the slide
If Debugging Then
' .Select
Shp.Select
End If
Form_Master.ProcessStatus.Value = StatusText & " InsertPPT-" & Shp.Name
If Shp.Type = msoLinkedOLEObject Then 'when we find a linked one
ReLinkShape Shp, TempVars!NewXLName
'need to store off top, left, width, height
Top = Shp.Top
Left = Shp.Left
Height = Shp.Height
width = Shp.width
Shp.LinkFormat.Update 'and force the link to refresh
MySleep 2, "S" 'hopefully, the 2 second pause will allow everything to update properly before moving on.
'then reset them here - they seem to change shape when I update them
Shp.LockAspectRatio = msoFalse
Shp.Top = Top
Shp.Left = Left
Shp.width = width
Shp.Height = Height
ElseIf Shp.Name = "SlideName" And Not Debugging Then 'if it's the "SlideName" tag
Shp.Delete 'delete it (unless we're debugging)
End If
Next
End With
Form_Master.ProcessStatus.Value = StatusText
End Sub
Private Sub ReLinkShape(ByRef Shp As PowerPoint.Shape, ByVal NewDestination As String)
Dim Link() As String
Dim link2() As String
If Shp.Type = msoLinkedOLEObject Then 'when we find a linked one
Link = Split(Shp.LinkFormat.SourceFullName, "!") 'update the link to point to the new clinic spreadsheet instead of the master
If InStr(1, Link(2), "]") > 0 Then
link2 = Split(Link(2), "]")
Link(2) = "[" & TempVars!ClinicName & ".xlsx]" & link2(1)
End If
Shp.LinkFormat.SourceFullName = NewDestination & "!" & Link(1) & "!" & Link(2)
End If
End Sub
Public Sub MySleep(ByRef Unit As Double, ByRef UOM As String)
Dim Pause As Date
Pause = DateAdd(UOM, Unit, Now())
While Now < Pause
DoEvents
Wend
End Sub