PowerPoint Shape Export Constant Image Dimensions - vba

I am trying to export a PPT Shape into an image file, however, PowerPoint is re-sizing the shape to the text length.
I know there is an Autosize feature in VBA, however I cannot get the msoAutoSizeTextToFitShape feature working in PowerPoint 2013.
My code is as follows
Sub RunMe()
Dim MyShape As Shape
Dim i As Integer
Dim S(0 To 2) As String
Set MyShape = ActivePresentation.Slides(1).Shapes.AddShape(msoShapeRectangle, 50, 50, 100, 40)
S(0) = "short text"
S(1) = "Medium length text"
S(2) = "Really Really Long and descriptive Text"
For i = 0 To 2
With MyShape
'.TextFrame.AutoSize = PowerPoint.ppAutoSizeMixed
.TextFrame.TextRange.Text = S(i)
.Export "C:\temp\" & "\" & S(i) & ".png", ppShapeFormatPNG
End With
Next i
End Sub
As you will see, the generated image dimensions are different. Is there a way to create images of the same size?

You could either adjust the text size to make sure it fits within the shape or adjust the shape to fit the text size. My guess is that you'd want the former, so have a shot with this:
Sub RunMe()
Dim MyShape As Shape
Dim i As Integer
Dim S(0 To 2) As String
Dim sngOriginalSize As Single
Set MyShape = ActivePresentation.Slides(1).Shapes.AddShape(msoShapeRectangle, 50, 50, 100, 40)
S(0) = "short text"
S(1) = "Medium length text"
S(2) = "Really Really Long and descriptive Text"
For i = 0 To 2
With MyShape
.TextFrame.TextRange.Text = S(i)
' store original text size
sngOriginalSize = .TextFrame.TextRange.Font.Size
' decrement font size until the text fits
' within the shape:
Do While .TextFrame.TextRange.BoundHeight > MyShape.Height
.TextFrame.TextRange.Font.Size = .TextFrame.TextRange.Font.Size - 1
Loop
.Export "C:\temp\" & "\" & S(i) & ".png", ppShapeFormatPNG
' reset the text to original size
.TextFrame.TextRange.Font.Size = sngOriginalSize
End With
Next i
End Sub

I have version 2003 installed on my current PC so the following is NOT TESTED.
According to some websites, TextFrame2 is a new property from 2007 onwards.
You may try msoAutoSizeTextToFitShape on TextFrame2 instead.
EDIT :
I tried this in my home PC with version 2010 and it looks okay. Give it a try.
Replace TextFrame in your code by TextFrame2

Related

PowerPoint macro to toggle multi words on slide to change font size & color in order from left to right. MouseOver toggles the change

I’m creating reading materials using PPT slide. Each slide contains a series of rectangle shapes containing a word - text color is black.Rectangles are named 1, 2, 3, 4, 5, 6 … Rectangle shapes run across the page. Macro MouseOver is assigned to all rectangle shape on slide. At the start of presentation: 1. several global variables are set. 2.Rectangle named 1 will increase in font size, text color to red. Mouseover on Rectangle 1, font size & font color returns to original size & color for Rectangle 1 and Rectangle 2, increase font size & change text color to red. When mouseover Rectangle 2, change font size & font color returns to original size for Rectangle 2 and for Rectangle 3, increase font size & change text color to red. In general, mouseover returns text to normal size & color and change color & size of next word in order. The order is 1, 2, 3 ... based on the name of Rectangles.
Thank you.
Trying to code with code found on website:
Update: I got StartSetUp to work. Having trouble declaring global variables - NumCnt & Last. I just discover Visual Studio Editor to type in code. Editor is a big help. Will work on MouseOver tomorrow.
Update 9/10/2022: Got it working. Need more testing. Macro is not pretty. I'm new to PPT. I learned a lot reading all the questions and answers on this site. Thank you everyone!
Update 9/11/2022: I believe it works. Closing.
Public NumCnt As Integer
Public Last As Integer
Public Sub Setting(ByRef oGraphic As Shape)
NumCnt = 1
Last = 3
Debug.Print "In Setting"
Debug.Print NumCnt
Debug.Print Last
SetBig(ByRef oGraphic As Shape)
End Sub
Public Sub SetBig(ByRef oGraphic As Shape)
Dim RGBColorBig As Long
Dim RGBColorSmall As Long
Dim oSld As Slide
Dim oShp As Shape
Dim RGBColorBig As Long
Dim NameStr As String
'
'For debug
Debug.Print "in TextHover"
Debug.Print "Last is " Last
Debug.Print "NumCnt is "; NumCnt; ""
'For debug
'
RGBColorBig = RGB(255, 0, 0)
RGBColorSmall = RGB(0, 0, 0)
Set oSld = oGraphic.Parent
'
' Find first word. Change font text size and font color
'
For Each oShp In oSld.Shapes
NameStr = oShp.Name
If NameStr = CStr(NumCnt) Then
If oShp.HasTextFrame Then
If oShp.TextFrame.HasText Then
With oShp.TextFrame.TextRange.Font
.Size = 30
.Color.RGB = RGBColorBig
End With
End If
End If
Exit Sub
End If
Next
End Sub
Public Sub TextHover2(ByRef oGraphic As Shape)
Dim oSld As Slide
Dim oShp As Shape
Dim RGBColorBig As Long
Dim RGBColorSmall As Long
Dim NameStr As String
'
'For debug
Debug.Print "in TextHover"
Debug.Print "Last is " Last
Debug.Print "NumCnt is "; NumCnt; ""
'For debug
'
RGBColorBig = RGB(255, 0, 0)
RGBColorSmall = RGB(0, 0, 0)
Set oSld = oGraphic.Parent
If NumCnt = 1 Then
NameStr = oGraphic.Name
If NameStr = CStr(NumCnt) Then
If oGraphic.HasTextFrame Then
If oGraphic.TextFrame.HasText Then
With oGraphic.TextFrame.TextRange.Font
.Size = 20
.Color.RGB = RGBColorSmall
End With
NumCnt = NumCnt + 1
'
'Find Next word on slide
'Change text font to big size and text font color to red
'
SetBig(ByRef oGraphic As Shape)
End If
End If
Else
'End Sub
Exit Sub
End If
ElseIf NumCnt > 1 Then
NameStr = oGraphic.Name
If NameStr = CStr(NumCnt) Then
With oGraphic.TextFrame.TextRange.Font
.Size = 20
.Color.RGB = RGBColorSmall
End With
NumCnt = NumCnt + 1
If NumCnt <= Last Then
'
'Find Next word on slide
'Change text font to big size and text font color to red
'
SetBig(ByRef oGraphic As Shape)
ElseIf NumCnt >= Last Then
'
'do some Reset here
'
Debug.Print "Hello World"
End If
End If
End If
End Sub

Insert a picture into an InlineShape

I’m writing a Document in which I have to include many Pictures. In the ongoing process the Pictures get changed many times.
My idea was to include Rectangle Shapes as placeholders and give them a suitable name. I created a Macro that selects the Shape, deletes the old Picture and inserts the new one into the Shape.
Sub InsertImage(Shape As String, Picture As String, Hight As Integer)
Dim shp As Word.Shape
Dim strFile As String
Dim strExt As String
strFile = "C:\Pictures"
strExt = ".png"
ActiveDocument.Shapes.Range(Array(Shape)).Select
Selection.TypeBackspace
Set shp = ActiveDocument.Shapes.AddPicture(Anchor:=Selection.Range, FileName:= _
strFile & "\" & Picture & strExt, LinkToFile:=False, SaveWithDocument:=True)
With shp
.LockAspectRatio = msoTrue
.Height = CentimetersToPoints(Hight)
End With
End Sub
Sub Insert1()
InsertImage "Shape01", "Pic01", 10
End Sub
I want this for floating Shapes as well as for InlineShapes.
When I set my Placeholder Shapes to InlineShapes the TypeBackspace line deletes the InlineShape and the picture does not get inserted into the InlineShape.
Thank you very much for the help. After many struggles, the solution with Tables + Bookmarks works perfekt.
Here is the code:
Sub InsertPic(Pic As String, Cut As Single)
Dim strFile As String
Dim strExt As String
Dim ils As InlineShape
strFile = "C:\Pictures“
strExt = ".png"
Application.ScreenUpdating = False
ActiveDocument.Bookmarks(Pic).Select
Selection.Delete
Set ils = Selection.InlineShapes.AddPicture(FileName:= _
strFile & "/" & Pic & strExt, _
LinkToFile:=False, SaveWithDocument:=True)
With ils
.PictureFormat.CropBottom = CentimetersToPoints(Cut)
.LockAspectRatio = msoTrue
.Height = .Range.Cells(1).Height
If .Width > .Range.Cells(1).Width Then
.Width = .Range.Cells(1).Width
End If
End With
ActiveDocument.Bookmarks.Add (Pic)
Application.ScreenUpdating = True
End Sub
Sub Insert01()
InsertPic "Image01", 20
MsgBox "Done"
End Sub
Some explanation:
For this code, the Bookmark and the Picture need the same Name. I made this to avoid mix-ups.
With the Selection.Delete command, the Bookmark gets also deleted, so I just added a new Bookmark with the same name at the end. I’m sure there are more elegant ways to solve this, but this solution works.
I have had many struggles because i wanted to crop the Picure. But the size gets changed to the size of the table-cell when its inserted and the cutting step comes afterwards. So the Picturs wasn´t filling the complete cell size. Therefore, I added a part to resize the Image to the table-cell Size. As well, im sure there are better ways to overcome this ...
Because of this resizing, the Makro needs a bit of time (at least for my document). So I disabled the Screenupdating.

Powerpoint VBA to insert image and change size

I think this could solve problems for a lot of people doing tedious pasting of images from one directory into powerpoint then resizing them.
My problem is that I have 16 images all in one directory which need updating each month and it's very slow to do it one by one. The task is:
Open directory
Open first image
Paste image into powerpoint
Reposition image to top left
Resize image to height 550 by width 960 (fills A4 page)
Send image to back
Move to next slide
Repeat for second image
Continue until no more images in directory
Directory is (e.g.) "C:\Users\xxxxxx\Documents\Work\Procurement Project\Slides"
First image name is (e.g.) "01 Summary", second is "02 Client Contracts" etc etc
I think I need a str and a path and a table for the str to add to path to create each new path using i and i + 1 etc
I think I then need some code that's a bit like this:
Sub Picture_size_and_position()
Dim oShape As Shape
Dim oPresentation As Presentation
Dim oSlide As Slide
Dim oSelection As Selection
ActiveWindow.View.GotoSlide oSlide.SlideIndex
With ActiveWindow.Selection.ShapeRange
.LockAspectRatio = msoFalse
.Height = 550
.Width = 960
.Left = 0
.Top = 0
End With
End Sub
Then I'm sure I need a looping function to repeat this until there's nothing left in the directory using some combination of i and j...but the whole code is way beyond me, very frustratingly.
Could someone offer some tips, please? Much much appreciated!
Thank you!
Sub ImportABunch()
Dim strTemp As String
Dim strPath As String
Dim strFileSpec As String
Dim oSld As Slide
Dim oPic As Shape
' Edit these to suit:
strPath = "C:\Users\username\"
strFileSpec = "*.png"
strTemp = Dir(strPath & strFileSpec)
i = 1
Do While strTemp <> ""
Set oSld = ActivePresentation.Slides(i)
Set oPic = oSld.Shapes.AddPicture(FileName:=strPath & strTemp, _
LinkToFile:=msoFalse, _
SaveWithDocument:=msoTrue, _
Left:=0, _
Top:=0, _
Width:=960, _
Height:=550)
i = i + 1
With oPic
.LockAspectRatio = msoFalse
.ZOrder msoSendToBack
End With
' Or (with thanks to David Marcovitz) make the picture as big as possible on the slide
' without changing the proportions
' Leave the above commented out, uncomment this instead:
' With oPic
' If 3 * .width > 4 * .height Then
' .width = ActivePresentation.PageSetup.Slidewidth
' .Top = 0.5 * (ActivePresentation.PageSetup.Slideheight - .height)
' Else
' .height = ActivePresentation.PageSetup.Slideheight
' .Left = 0.5 * (ActivePresentation.PageSetup.Slidewidth - .width)
' End If
' End With
' Optionally, add the full path of the picture to the image as a tag:
'With oPic
' .Tags.Add "OriginalPath", strPath & strTemp
'End With
' Get the next file that meets the spec and go round again
strTemp = Dir
Loop
End Sub
Credit to http://www.pptfaq.com/index.html - Great little site!
Have an idea to automate it/or upon manual launch of a new Macro Enabled PowerPoint Template file. To automate macro upon file open, add customUI: onLoad="ImagesToPowerPoint". Search "CustomUI Editor" for it.
Note I have not fully tested the automation part.
Option Explicit
Sub ImagesToPowerPoint()
Const FileType As String = "*.png"
Dim sSaveFilePath As String, sSaveFileName As String, sImagesFolder As String
Dim oLayout As CustomLayout, oSlide As Slide, i As Long, sFile As String
sImagesFolder = Environ("USERPROFILE") & "\Documents\Work\Procurement Project\Slides\"
' Prepare auto save PowerPoint file name
sSaveFilePath = Environ("USERPROFILE") & "\Documents\Work\PowerPoints\"
sSaveFileName = Format(Now, "yyyy_mmdd") & "_Procurement.pptx"
With ActivePresentation
' Use the first layout for all new slides
Set oLayout = .SlideMaster.CustomLayouts(1)
' Start processing all files in the folder
sFile = Dir(sImagesFolder & FileType)
Do Until sFile = ""
' Add new slide
Set oSlide = .Slides.AddSlide(.Slides.Count, oLayout)
' Delete all the shapes from that layout
For i = oSlide.Shapes.Count To 1 Step -1
oSlide.Shapes(i).Delete
Next
' Add the image to slide
With oSlide.Shapes.AddPicture(sImagesFolder & sFile, msoFalse, msoTrue, 0, 0, oLayout.Width, oLayout.Height)
.LockAspectRatio = msoFalse
.AlternativeText = Now & " | " & sImagesFolder & sFile
End With
sFile = Dir
Loop
.SaveAs sSaveFilePath & sSaveFileName
End With
Presentations(sSaveFileName).Close
If Presentations.Count = 0 Then Application.Quit
End Sub

VBA powerpoint - Macro for formatting notes

I'm trying to make a macro that can change all the text in all the notes of a powerpoint presentation to a specified font and fontsize (given through InputBoxes).
It seems to work but not in all the slides, some slides it just resets the fontsize to something way larger than what was given. anyone know what could go wrong?
Sub FormatNotes()
Dim intSlide As Integer
Dim strNotes As String
Dim nts As TextRange
Dim strFont, intSize
intSize = InputBox("Please enter font size", "fontsize", "12")
strFont = InputBox("Please enter font", "font type", "Calibri")
With ActivePresentation
For intSlide = 1 To .Slides.Count
Set nts = ActivePresentation.Slides(intSlide).NotesPage. _
Shapes.Placeholders(2).TextFrame.TextRange
With nts
If intSize = "" Then intSize = 12
.Paragraphs.Font.Size = intSize
.Paragraphs.Font.Name = strFont
End With
Next intSlide
End With
MsgBox ("FormatNotes uitgevoerd")
End Sub
Seems to work to me. I also tried it after deleting .Paragraphs as you don't need that if you want to set the whole text to the same type face and size. Do you have an example of it not working for investigation?
By the way, did you know that Notes formatting is not shown by default in PowerPoint and has to be turned on in the Outline view?
Original question is why code did not work for all slides. I think it has to do with fact the code used Placeholder(2) as hard value, so the code only works with TextRange in that Placeholder. If the NotesPage has more than one Placeholder, the code will not work for the other Placeholders.
My code shown here uses .HasTextFrame to determine if a Placeholder has text, and only attempts to set font size and type if this is true. (I used debug.print to see how far the code got, you can comment it out.)
Sub FormatNotes()
' Written 2020-08-29 P.Irving for myself
Dim mySlide As Integer, myPlace As Integer
Dim myNotes As String
Const mySize = "11", myFont = "Calibri"
With ActivePresentation ' qualify macro name
Debug.Print "Slide#", "LEN(Notes)", "LEFT(Notes,50)"
For mySlide = 1 To .Slides.Count
myNotes = ""
For myPlace = 1 To ActivePresentation.Slides(mySlide). _
NotesPage.Shapes.Placeholders.Count
' code copied from learn.microsoft.com/en-us/office/_
' vba/api/powerpoint.textrange.font
' this code does not attempt to SET nts
With ActivePresentation.Slides(mySlide). _
NotesPage.Shapes.Placeholders(myPlace)
If .HasTextFrame Then
With .TextFrame.TextRange.Font
.Size = mySize
.Name = myFont
'.Bold = True
'.Color.RGB = RGB(255, 127, 255)
End With
myNotes = myNotes & _
ActivePresentation.Slides(mySlide). _
NotesPage.Shapes.Placeholders(myPlace). _
TextFrame.TextRange
End If ' .HasText
End With
Next myPlace
Debug.Print mySlide, Len(myNotes), Left(myNotes, 50)
Next mySlide
End With
MsgBox "Applied to " & ActivePresentation.Slides.Count & " slides", _
vbOKOnly, "FormatNotes"
End Sub

How to read lines from a text file one by one with Power Point VBA code?

This code will read a line from a text file:
set file = CreateObject("Scripting.FileSystemObject").OpenTextFile("c:\number.txt", 1)
text = file.ReadLine
MsgBox text
How can I make it read repeatedly one line after another from the same file? I guess, I should use a loop here, right? I need it to read the first line from the file at the first iteration, the second line at the second iteration, the third one at the third and so on till all the lines have been read. How can I do it?
Important addition: I need the code to operate on each line one by one - not all at once!
Use the ReadAll() method:
text = file.ReadAll
(Might be of interest: FileSystemObject Sample Code)
With a loop:
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim fso, MyFile, FileName, TextLine
Set fso = CreateObject("Scripting.FileSystemObject")
FileName = "c:\testfile.txt"
Set MyFile = fso.OpenTextFile(FileName, ForReading)
'' Read from the file
Do While MyFile.AtEndOfStream <> True
TextLine = MyFile.ReadLine
'' Do stuff to TextLine
Loop
MyFile.Close
If for some reason you want to use the in-built VBA file handling routines, you would use code like this:
Sub ReadAFileLineByLine()
Dim InStream As Integer
InStream = FreeFile()
Open "C:/tmp/fastsynchtoquesttry_quest.txt" For Input As InStream
Dim CurrLine As String
Do While True
Line Input #InStream, CurrLine
' do stuff to CurrLine
If EOF(InStream) Then Exit Do
Loop
Close #InStream
End Sub
You can add a reference* to the Windows Script Host Object Model, it will help you with the FileSystemObject Object, because you can then say:
Dim fs As FileSystemObject
Dim f As TextStream
Which will allow you to use intellisense to see the various properties and the Object Browser to explore the library.
* In the code window, choose Tools, References and tick the box beside the library you want.
I wrote a VBA routine that reads a text file and insert a new slide for each sentence in the text.
First, in slide #1, add a button that calls the macro named "generate"
Source code goes:
Const DEFAULT_SLIDE = 1 ' the slide to copy the layout style from
Const MARGIN = 50 ' margin of the generated textbox
Sub generate()
Dim txtFile As String ' text file name
Dim fileNo As Integer ' file handle
Dim buffer As String ' temporary string buffer
Dim sentence() As String ' the main array to save sentences
Dim i, total As Integer
Dim myLayout As CustomLayout
Dim mySlide As Slide
Dim myShape As Shape
Dim myWidth, myHeight As Integer 'slide width and height
txtFile = "text2sample.txt"
txtFile = ActivePresentation.Path & "\" & txtFile 'textfile should be in the same Dir as this ppt
If Len(Dir$(txtFile)) = 0 Then
MsgBox txtFile & " file not found."
Exit Sub
End If
'Initialize array
ReDim sentence(0)
'get file handle number
fileNo = FreeFile()
Open txtFile For Input As #fileNo
i = 0
Do While Not EOF(fileNo)
Line Input #fileNo, buffer 'read & save sentences line by line
ReDim Preserve sentence(i + 1) ' increase 1 more array
sentence(i) = LTrim(RTrim(buffer))
i = i + 1
Loop
Close #fileNo
total = i
Randomize ' for random color
With ActivePresentation.PageSetup
myWidth = .SlideWidth - MARGIN 'get width and height
myHeight = .SlideHeight - MARGIN
End With
For i = 0 To total
Set myLayout = ActivePresentation.Slides(DEFAULT_SLIDE).CustomLayout
'add a slide like slide #1
Set mySlide = ActivePresentation.Slides.AddSlide(DEFAULT_SLIDE + 1 + i, myLayout)
'add a textbox with margin
Set myShape = ActivePresentation.Slides(DEFAULT_SLIDE + 1 + i).Shapes. _
AddTextbox(msoTextOrientationHorizontal, MARGIN, MARGIN, myWidth, myHeight)
With myShape
'add a sentence
.TextFrame.TextRange.Text = sentence(i)
.TextFrame.TextRange.Font.Size = 60
' color 255 is too bright. Pick a less bright color (200)
.TextFrame.TextRange.Font.Color.RGB = RGB(Int(Rnd * 200), Int(Rnd * 200), Int(Rnd * 200))
.TextFrame.TextRange.Font.Bold = msoTrue
.TextFrame.TextRange.Font.Shadow = msoTrue
' If you want to change the color of the shape
'.Fill.ForeColor.RGB = RGB(Int(Rnd * 200), Int(Rnd * 200), Int(Rnd * 200))
'.Fill.BackColor.RGB = RGB(Int(Rnd * 200), Int(Rnd * 200), Int(Rnd * 200))
'.Fill.Solid
End With
'add a textbox for slideshow progress ex) 1/100
Set myShape = ActivePresentation.Slides(DEFAULT_SLIDE + 1 + i).Shapes. _
AddTextbox(msoTextOrientationHorizontal, 0, 0, 150, 20)
With myShape
.TextFrame.TextRange.Text = "( " & i & " /" & total & " )"
.TextFrame.TextRange.Font.Size = 20
.TextFrame.TextRange.Font.Color.RGB = RGB(100, 100, 100)
End With
Next
MsgBox total & " Slides were added.", vbInformation
End Sub
Download file:
http://konahn.tistory.com/attachment/cfile8.uf#2175154C573D3BC02A2DFA.pptm