si1rin
si1rin

Reputation: 23

How to check if all TextBoxes in a PowerPoint document are filled in

I have a PowerPoint document where users can input text into several TextBoxes, over 6 slides in total. On the last slide, I want to check if the user has filled in every TextBox in the presentation.

I tried using lots of code snippets on the internet and modifying them, however I am a complete VBA noob and, surprisingly, it did not work out. :') I would greatly appreciate your help with this task.

It would be even better if it is possible to check whether the user has input AT LEAST 4 characters in each textbox. However I have no idea how to start programming this...

Here is my code, it does not show errors however nothing happens when clicking the CheckBox at the end.

Public Sub CheckTextBox()
    Dim fTextBox As Object
    For Each Slide In ActivePresentation.Slides
    For Each fTextBox In ActivePresentation.Slides
        If TypeName(fTextBox) = "TextBox" Then
            If fTextBox.Text = "" Then
                MsgBox "Please make sure to fill out all fields!"
            End If
        End If
    Next
    Next
End Sub


'When ticking this CheckBox, the MsgBox should show up

Private Sub CheckBox1_Click()
CheckTextBox
End Sub

Thank you guys so much for your help.

Upvotes: 1

Views: 1379

Answers (2)

trinalbadger587
trinalbadger587

Reputation: 2109

For those looking for c# code to list all text boxes in a presentation:

using Microsoft.Office.Interop.PowerPoint;
using MsoShapeType = Microsoft.Office.Core.MsoShapeType;

public static IEnumerable<Shape> AllTextBoxes (Presentation presentation) =>
    from slide in presentation.Slides.Cast<Slide>()
    from shape in slide.Shapes.Cast<Shape>()
    from textBox in AllTextBoxes(shape)
    select textBox;

public static IEnumerable<Shape> AllTextBoxes (Shape sh)
{
    IEnumerable<Shape> _() { if (sh.Type == MsoShapeType.msoTextBox) yield return sh; }
    return sh.Type == MsoShapeType.msoGroup ? sh.GroupItems.Cast<Shape>().SelectMany(AllTextBoxes) : _();
}

Upvotes: 1

FunThomas
FunThomas

Reputation: 29146

Your inner For-loop is wrong, you need to loop over all Shapes of the slide, instead, you start another loop over all slides.

Basically, all objects that you place on a slide are Shapes. If you use TypeName, you will get Shape. To distinguish the single shape-types, use the property type of the shape-object. A list of types can be found at https://learn.microsoft.com/de-de/office/vba/api/office.msoshapetype - a textbox has a type msoTextBox (17).

To get the text of a shape, use the property TextFrame.TextRange.Text of the shape.

Try the following code (it checks already for a length of at least 4 characters). It will stop at the first textbox that has less than 4 chars in it (else, you would get one MsgBox for every textbox) and select it.

Public Sub CheckTextBox()
    Dim sh As Shape, slide As slide
    For Each slide In ActivePresentation.Slides
        For Each sh In slide.Shapes
            Debug.Print TypeName(sh)
            If sh.Type = msoTextBox Then
                If Len(sh.TextFrame.TextRange.Text) < 4 Then
                    MsgBox "Please make sure to fill out all fields!"
                    slide.Select
                    sh.Select
                    Exit For
                End If
            End If
        Next
    Next

End Sub

UPDATE The code above didn't take into account the shapes within groups. The following code loops over all shapes of all slides and calls the function checkShape that will check
a) If the shape is a textBox (msoTextBox, 17) - if yes, the length of the text is checked and if too short, that shape is returned.
b) If the shape is a group (msoGroup, 6), it calls (recursively) the function for all child shapes and returns the first child textbox found.
The main routine (CheckAllTextBoxes) checks if any textBox was found, and, if yes, will select it and issue the message.

Public Sub CheckAllTextBoxes()
    Dim slide As slide, sh As Shape
    For Each slide In ActivePresentation.Slides
        For Each sh In slide.Shapes

            Dim textBox As Shape
            Set textBox = CheckShape(sh, 4)
            If Not textBox Is Nothing Then
                slide.Select
                textBox.Select
                MsgBox "Please make sure to fill out all fields!"
                Exit Sub
            End If
        Next
    Next

End Sub

Function CheckShape(sh As Shape, minLen As Integer) As Shape

    ' Check if shape is a Textbox and then text is not long enough
    If sh.Type = msoTextBox Then
        If Len(sh.TextFrame.TextRange.Text) < minLen Then
            Set CheckShape = sh
            Exit Function
        End If
    End If

    ' For a group, check all it's child shapes
    If sh.Type = msoGroup Then
        Dim child As Shape
        For Each child In sh.GroupItems
            Dim textBox As Shape
            Set textBox = CheckShape(child, minLen)
            If Not textBox Is Nothing Then
                ' Found a Textbox within the group, return it
                Set CheckShape = textBox
                Exit Function
            End If
        Next child
    End If

End Function

Upvotes: 3

Related Questions