how to call a sub from a different slide in vba powerpoint - vba

working in PowerPoint, I need to call a sub from a different slide. For example, I'm creating a macro that is located in one slide, and refers to a sub in another slide, for example:
**Slide 3:**
Sub Login()
If Slide3.LoginBox.Text = Slide1.CreatePasswordLogin.Text Then
ActivePresentation.SlideShowWindow.View.Next
Slide3.LoginBox.Text = ""
Call LoginShapeLoad (the one from slide 4 for example)
Else
MsgBox "Incorrect Password!", vbExclamation, "Login Prompt"
Slide3.LoginBox.Text = ""
End If
End Sub
**Slide 4:**
Sub LoginShapeLoad()
If Shapes("Shape1").Visible Then
Else
Shapes("Shape1").ZOrder msoBringToFront
Shapes("Shape1").Visible = msoTrue
End If
End Sub

Add a module to your VBA project and put this code there. You can then call it from anywhere else.
Public Sub LoginShapeLoad()
With ActivePresentation.Shapes("Shape1")
If Not .Visible Then
.ZOrder msoBringToFront
.Visible = msoTrue
End If
End With
End Sub
Or to make it more generically useful:
Public Sub LoginShapeLoad(oSh as Shape)
With oSh
If Not .Visible Then
.ZOrder msoBringToFront
.Visible = msoTrue
End If
End With
End Sub
And invoke it with something like this:
Sub MakeAnyShapeVisible()
Dim oSh as Shape
' Change 42 to the slide number, SomeName to the shape name
' you want to make visible:
Set oSh = ActivePresentation.Slides(42).Shapes("SomeName")
Call LogInShapeLoad(oSh)
End Sub

Related

PPT VBA Routine works in Step Mode, but not in Run

I try to use a selected picture on the slide and copy/paste it into the Placeholder (I can not load the picture from a file, it has to be from the slide itself.)
It works fine when I go through the code with F8 step by step. But when I run the macro, the placeholder stays empty.
I tried to set Delays in order to give PPT enough time but no matter how high I make the delay, it won't work (Placeholder doesn't get filled)
Any ideas, what could cause this weird behavior? Better ideas how to place the selected image into the template Placeholder (should work on Mac too though). Thank you for your time!
Sub SetImageIntoPlaceholder()
Dim sImage As Shape
Dim iSl As Integer
Dim oSl As Slide
Dim oPl As Shape
On Error GoTo ErrorHandler
If ActiveWindow.Selection.ShapeRange().Count <> 1 Then
MsgBox "Please select only the picture you wish to place in the Placeholder", vbOKOnly Or vbCritical, Application.Name
Exit Sub
End If
iSl = ActiveWindow.View.Slide.SlideIndex
Set oSl = ActivePresentation.Slides(iSl)
Set sImage = ActiveWindow.Selection.ShapeRange(1)
sImage.Copy
For Each oPl In oSl.Shapes
If oPl.Type = msoPlaceholder Then
With oPl
Select Case oPl.PlaceholderFormat.Type
Case Is = 18
'Its a picture placeholder
Delay 4
oPl.Select
Delay 4
ActiveWindow.View.Paste
Delay 5
'oSl.Shapes.Paste
Application.CommandBars.ExecuteMso ("SlideReset")
'Delay 1.5
'sImage.Delete
Exit Sub
Case Else
' ignore other shape types
End Select
End With
End If
Next oPl
ErrorHandler:
'Resume Next
End Sub
Try adding DoEvents after you copy and after you paste. Also, try separating your copy and paste operations into separate procedures. VBA should wait until the operations are complete before entering and exiting a procedure. I haven't tested it, but maybe something like this . . .
Option Explicit
Sub SetImageIntoPlaceholder()
Dim sImage As Shape
Dim iSl As Integer
Dim oSl As Slide
On Error GoTo ErrorHandler
If ActiveWindow.Selection.ShapeRange().Count <> 1 Then
MsgBox "Please select only the picture you wish to place in the Placeholder", vbOKOnly Or vbCritical, Application.Name
Exit Sub
End If
iSl = ActiveWindow.View.Slide.SlideIndex
Set oSl = ActivePresentation.Slides(iSl)
Set sImage = ActiveWindow.Selection.ShapeRange(1)
sImage.Copy
DoEvents
PastePictureInSlide oSl
ErrorHandler:
'Resume Next
End Sub
Private Sub PastePictureInSlide(ByVal oSl As Slide)
Dim oPl As Shape
For Each oPl In oSl.Shapes
If oPl.Type = msoPlaceholder Then
With oPl
Select Case .PlaceholderFormat.Type
Case Is = 18
'Its a picture placeholder
.Select
ActiveWindow.View.Paste
'oSl.Shapes.Paste
Application.CommandBars.ExecuteMso ("SlideReset")
DoEvents
Exit Sub
Case Else
' ignore other shape types
End Select
End With
End If
Next oPl
End Sub

Using a UserForm in VBA to update DocVariables in Word

I have created DocVariables in my word template, and am using a UserForm to allow user input to populate these variables.
Here is the code I have been using:
Private Sub CommandButton1_Click()
Dim ReportTitle, reportSub As String
ReportTitle = Me.textBox1.Value
reportSub = Me.textBox2.Value
ActiveDocument.Variables("Report Title").Value = ReportTitle
ActiveDocument.Variables("Sub-Title").Value = reportSub
ActiveDocument.Fields.Update
Me.Repaint
End Sub
This does insert the values from the text boxes into the variables, but it does not update the fields, so I have to manually go to each field and update it.
Can you please tell me where I have gone wrong so that I can fix this issue.
Any and all help is appreciated.
Try:
Private Sub CommandButton1_Click()
Application.ScreenUpdating = False
With ActiveDocument
.Variables("Report Title").Value = Me.textBox1.Value
.Variables("Sub-Title").Value = Me.TextBox2.Value
.Fields.Update
.PrintPreview
.ClosePrintPreview
End With
Me.Repaint
Application.ScreenUpdating = True
End Sub

How can I automate the hiding of PowerPoint slides?

I use PowerPoint in my lectures and print a subset of the slides for my students (to allow them to fill in blanks before I show my answers). Currently, I put a light blue circle at the bottom left of slides that I want to hide while printing (but not while lecturing). I then manually hide slides when it is time to print them, then unhide all of the slides before lecturing. Is there any way to automate this process? I use Office 365 on both PCs and Macs.
This will get you started, save this as pptm then save a copy as addin:
ChangeAnswersSlideState - changes activeslide to be an Answer Slide or not
PrintStudentHandout - Hide Answer slides and then print, then unhide
Option Explicit
Private Const ANS_ID As String = "ANS"
Sub PrintStudentHandout()
ChangeAnswersSlideVisible
With ActivePresentation
.PrintOptions.ActivePrinter = "Microsoft XPS Document Writer"
.PrintOut
End With
ChangeAnswersSlideVisible msoFalse
End Sub
Private Sub ChangeAnswersSlideVisible(Optional Hide As MsoTriState = msoTrue)
Dim oSlide As Slide, oShp As Shape
For Each oSlide In ActivePresentation.Slides
For Each oShp In oSlide.Shapes
If IsAnswersShape(oShp) Then
oSlide.SlideShowTransition.Hidden = Hide
Exit For
End If
Next oShp
Next oSlide
End Sub
Sub ChangeAnswersSlideState()
Dim oShp As Shape, bChanged As Boolean
bChanged = False
For Each oShp In Application.ActiveWindow.View.Slide.Shapes
If IsAnswersShape(oShp) Then
oShp.Delete
bChanged = True
End If
Next oShp
If Not bChanged Then MakeAnswersSlide
End Sub
Private Sub MakeAnswersSlide(Optional ByRef AnswerSlide As Slide = Nothing)
If AnswerSlide Is Nothing Then Set AnswerSlide = Application.ActiveWindow.View.Slide
With AnswerSlide.Shapes.AddShape(msoShapeOval, -80, 460, 72, 72)
.TextFrame.TextRange.Text = ANS_ID
End With
End Sub
Private Function IsAnswersShape(ByRef CheckShape As Shape) As Boolean
Dim bIsAnAnswerShape As Boolean
bIsAnAnswerShape = False
With CheckShape
If .AutoShapeType = msoShapeOval Then
If .HasTextFrame Then
If .TextFrame.TextRange.Text = ANS_ID Then
bIsAnAnswerShape = True
End If
End If
End If
End With
IsAnswersShape = bIsAnAnswerShape
End Function

One function for clickable checkboxes

Hye there.
I would like to ask for any ideas from anyone here.
I have a lot of checkboxes in a worksheet which I link with a chart in the same worksheet. I would like to make a function which run the same code for each of the checkboxes ( I have 24 check boxes overall) when it is click. If you have any idea or suggestion, do tell me.
Here is the idea of mine for the flow of the code. I just have the same flow of code.
Private Sub CheckBox1_Click()
On Error Resume Next
Sheets("REPORT").Activate
ActiveSheets.ChartObjects("STOCK MOVEMENT GRAPH").Activate
On Error GoTo 0
If CheckBox1.Value = False Then
ActiveChart.SeriesCollection(1).Delete
Else
ActiveChart.SeriesCollection.Add Source:=Sheets("REPORT").Range("B4:AB4")
End If
End Sub
Private Sub CheckBox2_Click()
On Error Resume Next
Sheets("REPORT").Activate
Worksheets("REPORT").ChartObjects("STOCK MOVEMENT GRAPH").Activate
On Error GoTo 0
If CheckBox2.Value = False Then
ActiveChart.SeriesCollection(2).Delete
Else
ActiveChart.SeriesCollection.Add Source:=Sheets("REPORT").Range("B5:AB5"), PlotBy:=xlRows
End If
End Sub
Thanks in advance. Regards.
You can pull out the common code into a standalone Sub:
Sub UpdateChart(rowNum As Long, AddingIt As Boolean)
Dim cht As Chart, s As Series, rng As Range, f, i
Set cht = Sheets("REPORT").ChartObjects("STOCK MOVEMENT GRAPH").Chart
'what's the data range?
Set rng = Sheets("REPORT").Range("B3").Offset(rowNum, 0).Resize(1, 2)
If AddingIt Then
'note: not checking if already added....
cht.SeriesCollection.Add Source:=rng
Else
For i = cht.SeriesCollection.Count To 1 Step -1
Set s = cht.SeriesCollection(i)
f = s.Formula
If InStr(f, rng.Address()) > 0 Then s.Delete
Next i
End If
End Sub
Then your checkbox code reduces to this:
Private Sub CheckBox1_Click()
UpdateChart 1, CheckBox1.Value
End Sub
Private Sub CheckBox2_Click()
UpdateChart 2, CheckBox2.Value
End Sub
'etc....

How to remove a border from an inline shape

I am working in VBA on Word 2010.
I have some code to add borders to an inlineshape which is working ok, but I need to be able to remove the border and that doesn't seem to be working. I've searched through this site and can't find anything close apart from this:
Mimic word borders and shading option "apply to:" (text) with vba on an inline shape
Code is a follows:
Sub TestAddBorders()
Dim rngShape As InlineShape
For Each rngShape In ActiveDocument.InlineShapes
With rngShape.Range.Borders
.OutsideLineStyle = wdLineStyleSingle
.OutsideColorIndex = wdPink
.OutsideLineWidth = wdLineWidth300pt
End With
Next rngShape
End Sub
Sub TestRemoveBorders()
Dim rngShape As InlineShape
For Each rngShape In ActiveDocument.InlineShapes
With rngShape.Range.Borders
.OutsideLineStyle = wdLineStyleNone
End With
Next rngShape
End Sub
I am always left with a picture (inlineshape) that has a greyish border around it. Using "Picture Border > No Outline" on the Picture Tools > Format Tab removes it, but I can' find any way to do it in VBA. The wdLineStyleNone just doesn't seem to work and I can't see an option for colour = "none", or linewidth = "none"
Thank you.
From MSDN:
To remove all the borders from an object, set the Enable property to False.
http://msdn.microsoft.com/en-us/library/office/ff196058.aspx
This will remove the borders as you applied them:
Sub TestRemoveBorders()
Dim rngShape As InlineShape
For Each rngShape In ActiveDocument.InlineShapes
With rngShape.Range.Borders
.Enable = False
End With
Next rngShape
End Sub
The above method removes borders but not lines. To remove lines, try this:
With rngShape.Line
.Visible = msoFalse
End With
David's answer is correct, but I wanted to add to it for anyone who stumbles upon this later.
I prefer not to use the Borders method that I see most other people list to add a border to an InlineShape, and thanks to David's answer here I learned that you can just use the Line member like you can with normal Shapes!
I'm aware that this might not exactly answer the question for those of you who are not also setting the border yourself, but in my personal case it was helpful. With that in mind, here are the revised versions of methods to Add and Remove the borders from shapes.
Option Explicit
Sub PicturesAll_Borders_Show()
'for pictures which are "In Line with Text"
Dim inShp As InlineShape
For Each inShp In ActiveDocument.InlineShapes
If inShp.Type = wdInlineShapePicture Then
With inShp.Line
.Visible = True
.Style = msoLineSingle
.Weight = 1
.ForeColor.RGB = RGB(0, 0, 0)
End With
End If
Next inShp
'for pictures which are "With Text Wrapping"
Dim shp As Shape
For Each shp In ActiveDocument.Shapes
If shp.Type = msoPicture Then
With shp.Line
.Visible = True
.Style = msoLineSingle
.Weight = 1
.ForeColor.RGB = RGB(0, 0, 0)
End With
End If
Next shp
End Sub
Sub PicturesAll_Borders_Hide()
'for pictures which are "In Line with Text"
Dim inShp As InlineShape
For Each inShp In ActiveDocument.InlineShapes
If inShp.Type = wdInlineShapePicture Then inShp.Line.Visible = False
Next inShp
'for pictures which are "With Text Wrapping"
Dim shp As Shape
For Each shp In ActiveDocument.Shapes
If shp.Type = msoPicture Then shp.Line.Visible = False
Next shp
End Sub