VBA powerpoint - code to change table's cell shading - vba

I have a PowerPoint 2010 presentation with a table on one slide.
I want to create a VBA modeless form that will work like a pallete of
formats/colors for formatting cells of that table.
Basically, the buttons on the form would just simulate clicking
specific Shading color in Table Tools/Design menu.
example:
I place the cursor to the cell then click on a button in activated modeless form. The shading of that cell will change according to the color in the code.
The reason I want to do this is that some other people will use it and the colors must be easily accessible (format painter doesn't not seem to copy the shading)
But I cannot find a way to make this VBA. I have tried recording macro in Word (not possible in PP) with no success.

Try this... (Not polished code, but should give you what you need(ed))
Public sub TblCellColorFill()
Dim X As Integer
Dim Y As Integer
Dim oTbl as Table
set oTbl = ActiveWindow.Selection.Shaperange(1).Table 'Only works is a single table shape is selected - add some checks in your final code!
For X = 1 To otbl.Columns.Count
For Y = 1 To otbl.Rows.Count
With otbl.Cell(Y, X)
If .Selected <> False Then 'Strange bug - will ignore if statement entirely if you use "= True"
'Debug.Print "Test worked " & Now
'We have the shape we need
.shape.Fill.ForeColor.RGB = RGB(100, 150, 200) 'Add your color here
End If
End With
Next 'y
Next 'x
End Sub

For table styling in MSPowerPoint 2013 I use
Sub STYLE_TABLE_2()
' Change table style
' Two rows Dark Gray and White Font
' Next odd rows Light Gray/ even Moderate Gray/ and Black Font
Dim iCols As Integer
Dim iRows As Integer
Dim oTbl As Table
' Debug.Print (ActiveWindow.Selection.ShapeRange(1).Type)
With ActiveWindow.Selection
If .Type = ppSelectionShapes Then ' Shape is selected ppSelectionShapes=2 ppSelectionSlides=3 ppSelectionNone=0
If .ShapeRange(1).Type = msoTable Then ' If first shape Type=19 is msoTable
' (--- note not all table-looking shapes are Table style Can be Type=14 msoPlaceholder
Debug.Print ("We are certain inside table") '
Set oTbl = ActiveWindow.Selection.ShapeRange(1).Table 'Only works if single table or its part is selected
For iCols = 1 To oTbl.Columns.Count
For iRows = 1 To oTbl.Rows.Count
With oTbl.Cell(iRows, iCols)
.Shape.TextFrame.TextRange.Font.Name = "Arial"
.Shape.TextFrame.TextRange.Font.Size = 12
If iRows Mod 2 <> 0 Then ' Odd numbers
Debug.Print ("Ymod2 2") '
.Shape.Fill.ForeColor.RGB = RGB(236, 234, 241)
Else
.Shape.Fill.ForeColor.RGB = RGB(215, 210, 225)
End If
If (.Selected <> False) And (iRows < 3) Then 'Cannot be "= True"
.Shape.Fill.ForeColor.RGB = RGB(166, 166, 166)
.Shape.TextFrame.TextRange.Font.Name = "Arial"
.Shape.TextFrame.TextRange.Font.Color = RGB(255, 255, 255)
.Shape.TextFrame.TextRange.Font.Size = 12
End If
End With
Next 'iRows
Next 'iCols
End If
End If
End With
End Sub

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

VBA TO copy text from textbox into slideTitle

I have created a macro in Powerpoint that will search for slides that are using a textbox for their title and are replacing them with a Title box. The steps are
1) find the slides that have a textbox in the title area
2) Copy the text in the textbox to a variable called slTitle.
3) Delete the texbox
4) Create a Title Holder for the current slide
5) Copy the text into the Title holder
6) Move on to the next slide
My macro currently is able to get as far as step 4 but I can't figure out how to get the text in slTitle into the Title box. This should be fairly easy to do but I've tried several ways and nothing seems to work. If anyone can help me figure out this step it would be much appreciated.
I am getting a compile error "Invalid Qualifier" on the line:
Set ppPlaceholderTitle.TextFrame.TextRange.Text = slTitle
Here is my current macro.
Sub AddMiMissingTitles()
Dim shpCurrShape As Object
Dim x As Integer
Dim sl As PowerPoint.Slide
Dim sld As Slide
Dim ctr As Integer
Dim s As Shape
'x = ActivePresentation.Slides.Count
'counter ctr used to count number of slides that needed titles added
ctr = 0
'**************************************************************
Set sourcePres = ActivePresentation
x = 1 ' slide counter
'get the title text
For Each sl In sourcePres.Slides
'delete all the empty title text boxes first
For Each s In sl.Shapes
If s.Top < 45 Then ' it's in the title area
'MsgBox s.PlaceholderFormat.Type
If s.Type <> ppPlaceholderTitle Then ' it isn't a proper Title placeholder
If s.HasTextFrame = msoTrue Then
If Trim(s.TextFrame.TextRange.Text) = "" Then
s.Delete ' delete empty text holders
Else
slTitle = s.TextFrame.TextRange.Text
s.Delete
sl.CustomLayout = sl.CustomLayout 'reset the slide
Set ppPlaceholderTitle.TextFrame.TextRange.Text = slTitle
End If
End If
End If
End If
Next
'Is there a title placeholder on the current layout?
If sl.CustomLayout.Shapes.HasTitle Then
lngType = sl.CustomLayout.Shapes.Title.PlaceholderFormat.Type
'*********************************
' With ActivePresentation.Slides()
End If
Next
MsgBox "Done! " & vbCrLf & ctr & " Slides needed Titles."
'*********************************
'sl.Shapes.AddPlaceholder lngType
sl.Shapes.Title.TextFrame.TextRange = slTitle
End Sub

How can I set the background colour of the selected cell in publisher

I'm trying to create a macro that sets the font colour of text in a cell to white and the cell background to black using VBA in Publisher.
So far I have managed to set up the font colour to change but I'm really struggling with the background - I can't find the right value to change.
Here's what I have so far:
Sub set_to_clue()
Selection.TextRange.Font.Color.RGB = RGB(255, 255, 255)
Selection.TextRange.Font.Fill.BackColor.RGB = RGB(0, 0, 0)
End Sub
Progress
With a bit of further trial and error I have worked out how to get cell backgrounds to change, however currently I can only do it by specifying an item number for the CellRange. This means that the cell that changes colour is hard coded rather than the selected one. How can I calculate the item number?
Sub set_to_clue()
Selection.TextRange.Font.Color.RGB = RGB(255, 255, 255)
Selection.TableCellRange.Item(10).Fill.ForeColor.RGB = RGB(0, 255, 0)
End Sub
I now have a working version, though I am sure it is not the correct or most elegant way to achieve the goal.
It also currently only works if the cell itself is entirely highlighted rather than just the text within it or just the cursor being in the cell. I may work to improve this later.
Working code in Publisher 2016:
Sub invert_square()
For Each square In Selection.TableCellRange
If square.Selected = True Then
square.Fill.ForeColor.RGB = RGB(0, 0, 0)
square.TextRange.Font.Color.RGB = RGB(255, 255, 255)
Exit For
End If
Next
End Sub
This expands your code so that it works for the entire table if the table as a whole is selected (selection type pbSelectionShape and shape type pbTable) and for the entire cell if the selection is of type pbSelectionText.
The trick for the latter functionality is that the .ContainingObject refers to the entire Shape, and that every Table Shape consists of one Story object. The .Start and .End properties of a TextRange object refer to its position within it's Story object. By comparing these two properties, we are able to identify which cell the selected text belongs to (it is not possible in Publisher to simultaneously select a little bit of text in several different cells).
Before I figured out this approach, I tried to call .Parent until TypeName() would equal "Cell", but this wouldn't work because the .Parent for Selection.TextRange is Selection (and not the Parent in the document itself as I had hoped)
Option Explicit
Sub InvertSquare()
ActiveDocument.BeginCustomUndoAction "Invert square"
Dim oCell As Cell
Dim oShape As Shape
If selection.Type = pbSelectionTableCells Then
Debug.Print "Table cells"
For Each oCell In selection.TableCellRange
SetInvertedColors oCell
Next oCell
ElseIf selection.Type = pbSelectionText Then
Debug.Print "Text"
Dim selText As TextRange
Dim x As Variant
Set selText = selection.TextRange
Set x = selText.ContainingObject
If TypeName(x) = "Shape" Then
If x.Type = pbTable Then
For Each oCell In x.Table.Cells
If oCell.HasText Then
If oCell.TextRange.Start <= selText.Start Then
If oCell.TextRange.End >= selText.End Then
SetInvertedColors oCell
Exit For
End If
End If
End If
Next oCell
End If
End If
ElseIf selection.Type = pbSelectionShape Then
Debug.Print "ShapeRange"
Dim oShapes As ShapeRange
Set oShapes = selection.ShapeRange
For Each oShape In oShapes
If oShape.Type = pbTable Then
For Each oCell In selection.TableCellRange
SetInvertedColors oCell
Next oCell
Exit For
End If
Next oShape
Debug.Print "Shape"
End If
ActiveDocument.BeginCustomUndoAction "Invert square"
End Sub
Sub SetInvertedColors(oCell As Cell)
Debug.Print oCell.TextRange.Text
oCell.TextRange.Font.Color = RGB(255, 255, 255)
''oCell.Fill.ForeColor.RGB = RGB(0, 0, 0) ''Out of memory error for whatever reason
End Sub
For some reason, I get an out of memory error when I try to set the .ForeColor.RGB in Publisher, but this happens with your code for me too, so I'm hoping that it works for you anyway if you uncomment the second last line.

Delete row button deleting other row instead

I've created a couple of macros, one that creates a shape in a determined row with a macro assigned and the macro assigned that deletes the row when the shape is clicked on. The macro that adds the shape is activated by another macro that populates the last empty row of my table with relevant data and the shape to delete the row in question, but I'll leave that one out of it.
So the macros should add the shape to the row being populated and, once the shape gets clicked, it gets the shape's row and delete it.
Here are the macros:
--The one that creates the shape:
Sub addDelBt(ByVal Target As Range)
Dim rw As Long
rw = Target.Row
Dim shp As Object
Set shp = Plan1.Shapes.AddShape(msoShapeMathMultiply, Target.Left + 2.5, Target.Top + 2.5, Target.RowHeight - 2, Target.RowHeight - 2)
'shp.Width = 11
'shp.Height = 11
shp.Fill.ForeColor.RGB = RGB(192, 0, 0)
shp.Fill.BackColor.RGB = RGB(170, 170, 170)
shp.Line.Visible = msoFalse
With shp.Shadow
.ForeColor.RGB = RGB(0, 0, 128)
.OffsetX = 0.5
.OffsetY = 2
.Transparency = 0.5
.Visible = True
End With
With shp.ThreeD
.BevelTopType = msoBevelCircle
.BevelTopInset = 15
.BevelTopDepth = 3
.PresetLighting = msoLightRigBalanced
.LightAngle = 145
.Visible = True
End With
shp.Name = "btnDel" & rw
shp.OnAction = "delRow"
End Sub
--The action of the shape:
Sub delRow()
Plan1.Unprotect ("password")
Dim shp As Object
Set shp = Plan1.Shapes(Application.Caller)
Dim rw As Long
rw = shp.TopLeftCell.Row
Dim doc As String
doc = Plan1.Cells(rw, 2).Value
Dim msgResult As VbMsgBoxResult
msgResult = MsgBox("Você deseja deletar o documento " + doc + "?", vbYesNo)
If msgResult = vbYes Then
Plan1.Rows(rw).EntireRow.Delete
End If
Plan1.Protect ("password")
End Sub
The problem is that some times (I haven't found a pattern yet) the button from one row will delete another upper row. I can't find out why, can you see it?
Cannot see why this would happen. Everything looks alright with the code.
Once I also wanted to make very similar functionality and realized that using many dynamically created buttons is not the best option (at least not for me).
I have abandoned the idea of shapes and make similar functionality with Worksheet_SelectionChange event. With some nice formating you can make the cells in the column looks like some Delete Buttons. The Worksheet_SelectionChange event (for cells) works like OnClick event (for buttons / OnAction for shapes).
Example:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
On Error GoTo ErrHandler
Application.EnableEvents = False
If Target.Column = 5 Then 'If the clicked cell is in the column 5
Dim doc As String
doc = Cells(Target.row, 2).Value
Dim msgResult As VbMsgBoxResult
msgResult = MsgBox("Voce^ deseja deletar o documento " + doc + "?", vbYesNo)
If msgResult = vbYes Then
Plan1.Rows(Target.Row).EntireRow.Delete
End If
End If
ErrHandler:
Application.EnableEvents = True
End Sub
The ErrorHandler with Disabling events is important to prevent the row.delete event to trigger another Worksheet_SelectionChange event.

Powerpoint & VBA New slide if table bottom exceeds the bottom of the slide

So i have been struggling with this for the past few days, i have this powerpoint 2007 presentation that i fill with information from a button in a from in a access file using VBA.
And in the first slide (and only by now) i have a table that will receive part of the information, however i can't make the table content break to another slide if the table exceeds the bottom of the slide, it just goes out of range.
I have the method to create a the new slide, and that works fine. But i can't seem to find an example that could get me started.
I think i should be something like check the table bottom exceeds slide bottom if it does create a new slide, cut the overlap cells and paste them in the new slide?
Thanks in Advance.
The code example:
' Open PowerPoint
Dim pptobj As PowerPoint.Application
Dim Presentation As PowerPoint.Presentation
Dim oSl as Slide
Set pptobj = New PowerPoint.Application
Set pptobj = CreateObject("Powerpoint.Application")
pptobj.Activate
Set Presentation = pptobj.Presentations.Open("C:\Users\some.pptx")
pptobj.Visible = True
pptobj.WindowState = ppWindowMaximized
If ((Len(Forms!Some!Name> 0) Then
pptobj.ActivePresentation.Slides(1).Shapes("TableNome").Table.Cell(1, 1).Shape.TextFrame.TextRange.Text = (CStr(Forms!Some!Name))
End If
Set oSl = pptobj.ActivePresentation.Slides(1)
With oSl
.Shapes("TableCategory").Table.Cell(1, 1).Shape.TextFrame.TextRange.Text = (CStr(Forms!CVLong!TxtCategory))
.Shapes("TableEmail").Table.Cell(1, 2).Shape.TextFrame.TextRange.Text = (CStr(Forms!Some!TxtEmail))
.Shapes("TableData").Table.Cell(1, 2).Shape.TextFrame.TextRange.Text = (CStr(Forms!Some!TxtTlf))
.Shapes("TableData").Table.Cell(2, 2).Shape.TextFrame.TextRange.Text = (CStr(Forms!Some!TxtCell))
End With
Dim oSh as Shape
Dim overhang
Set oSh = pptobj.ActivePresentation.Slides(1).Shapes.AddTable(1, 3, 50, 100, 493)
'One
If ((Len(Forms!Some!One)) > 0) Then
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(1, 3).Shape.TextFrame.TextRange.Text = (CStr(Forms!Some!One)) & vbNewLine & vbNewLine
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(1, 1).Shape.TextFrame.TextRange.Text = "One"
End If
'Two
If (Len(Forms!Some!Two> 0) Then
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(5, 3).Shape.TextFrame.TextRange.Text = (CStr(Forms!Some!Two)) & vbNewLine
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(5, 1).Shape.TextFrame.TextRange.Text = "Two"
End If
'Three
If (Len(Forms!Some!Three) > 0) Then
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(4, 3).Shape.TextFrame.TextRange.Text = (CStr(Forms!Some!Three)) & vbNewLine & vbNewLine
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(4, 1).Shape.TextFrame.TextRange.Text = "Three"
End If
'Add Slide
Dim Sld As Slide
Dim x As Integer
x = 1
Set Sld = pptobj.ActivePresentation.Slides.Add(Index:=pptobj.ActivePresentation.Slides.Count + 1, Layout:=ppLayoutBlank)
For Each Sld In pptobj.ActivePresentation.Slides
If x >= 2 Then
pptobj.ActivePresentation.Slides(1).Shapes("Text Placeholder 15").Copy
pptobj.ActivePresentation.Slides(x).Shapes.Paste
pptobj.ActivePresentation.Slides(x).Shapes("Text Placeholder 15").ZOrder msoSendToBack
pptobj.ActivePresentation.Slides(x).Shapes("Text Placeholder 15").Height = 810
pptobj.ActivePresentation.Slides(x).Shapes("Text Placeholder 15").Top = 19
End If
x = x + 1
Next
End If
'Put table top border
Dim n As Integer
Dim r As Integer
n = 3
r = 1
While r <= n
If Len(pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(r, 3).Shape.TextFrame.TextRange.Text) > 0 Then
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(r, 3).Borders(ppBorderTop).Visible = msoTrue
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Cell(r, 3).Borders(ppBorderTop).ForeColor.RGB = RGB(220, 105, 0)
Else
pptobj.ActivePresentation.Slides(1).Shapes("TableInfo").Table.Rows(r).Delete
n = n - 1
r = r - 1
End If
r = r + 1
Wend
'Add Photo
pptobj.ActivePresentation.Slides(1).Shapes.AddPicture(FileName:="\\someplace\" & [Id] & ".jpg", linktofile:=mostrue, savewithdocument:=msoTrue, Left:=52, Top:=115).Select
With pptobj.ActivePresentation.Slides(1).Shapes("Picture 7")
.LockAspectRatio = msoTrue
.Width = 85
.Left = 38
.Top = 80
End With
'add footer
Dim page As Integer
page = 1
Dim s As Slide
For Each s In pptobj.ActivePresentation.Slides
On Error Resume Next
Set oSh = s.HeadersFooters.Footer
If Err.Number <> 0 Then
Call s.Master.Shapes.AddPlaceholder(ppPlaceholderFooter, 219, 805, 342, 19)
End If
On Error GoTo 0
s.HeadersFooters.Footer.Visible = msoTrue
s.HeadersFooters.Footer.Text = (CStr(Forms!Some!Name)) & " - Page " & page & " of " & pptobj.ActivePresentation.Slides.Count
page = page + 1
Next
The following code snippet may give you some inspiration. Right now it just determines that the table is too large and gives you a message. Without more information about the type of data and how you obtained it, it's hard to give an answer to the second part of the problem. Most likely you would create a table, add one row at a time and check the size of the table; when the table gets too large (or within a certain distance from the bottom) you create a new slide and continue the process. That is probably better than creating a table that's too large, then trying to figure out where to cut it.
Here is the code:
Sub createTable()
Dim oSl As Slide
Dim oSh As Shape
Dim overhang
Set oSl = ActivePresentation.Slides(1)
Set oSh = oSl.Shapes.AddTable(28, 3)
overhang = ActivePresentation.PageSetup.SlideHeight - (oSh.Height + oSh.Top)
If overhang > 0 Then
MsgBox "the table fits"
Else
MsgBox "the table is too big!"
End If
End Sub