I am trying to create a macro that will toggle a shape’s color upon clicking. I’ve assigned the macro below to a shape, and it should execute with a click. However, when I click, nothing happens. Do I need to name the shape something specific? or is there something wrong in the VB language?
Sub ChangeShapeColour(ByRef oShp As Shape)
Dim oSh As Shape
' IF the shape's .Fill.ForeColor.RGB = red color:
If oSh.Fill.ForeColor.RGB = RGB(199, 70, 52) Then
' Change it to green:
oSh.Fill.ForeColor.RGB = RGB(117, 156, 108)
End If
' IF the shape's .Fill.ForeColor.RGB = green color:
If oSh.Fill.ForeColor.RGB = RGB(117, 156, 108) Then
' Change it to red:
oSh.Fill.ForeColor.RGB = RGB(199, 70, 52)
End If
End Sub
1
Toggle Shape Color
- For those new to
PowerPoint
, in theInsert
tab under theIllustration
group, there areAction Buttons
at the bottom of theShapes
menu that can utilize (call) the following codes as they are.
The Issue
- In the sub’s signature,
shp As Shape
already meansDim shp As Shape
so you mustn’t do it again inside the sub. - It makes no difference whether you add
ByVal
orByRef
since an object is always passedByRef
in VBA. - By introducing two variables and a With statement, you can make your code more readable:
Sub ToggleShapeColorYourCode(shp As Shape)
Dim Red As Long: Red = RGB(199, 70, 52) ' some red color
Dim Green As Long: Green = RGB(117, 156, 108) ' some green color
With shp.Fill.ForeColor
If .RGB = Red Then .RGB = Green
If .RGB = Green Then .RGB = Red
' With the previous two 'If' statements you are implying the following:
If .RGB <> Red And .RGB <> Green Then ' it's neither
' do nothing!?
End If
End With
End Sub
- The logic of your code yields the following: If the shape is green, make it red.
- How?
- If the shape is green, the 1st statement will ignore it while the 2nd statement will make it red.
- If the shape is red, the 1st statement will make it green, while the 2nd statement will make it red again i.e. it will remain red forever at the cost of the resources needed to make the two conversions happen.
- There is a third implicit (hidden) condition (case) that you may have forgotten about i.e. when the color is neither red nor green. In this case, nothing will happen i.e. the current shape’s color will remain forever.
- You have to decide what should happen in this case. In the continuation, I have opted for
Red
.
The Fix
- You must introduce an
ElseIf
and/or anElse
clause into theIf
statement. Alternatively, you can use theIIF
function or theSelect Case
statement.
1.) If
Long
Sub ToggleShapeColorIFLong(shp As Shape)
Dim Red As Long: Red = RGB(199, 70, 52) ' some red color
Dim Green As Long: Green = RGB(117, 156, 108) ' some green color
With shp.Fill.ForeColor
If .RGB = Red Then
.RGB = Green
ElseIf .RGB = Green Then
.RGB = Red
Else ' it is neither
.RGB = Red ' or Green, your choice
End If
End With
End Sub
2.) If
Short
Sub ToggleShapeColorIfShort(shp As Shape)
Dim Red As Long: Red = RGB(199, 70, 52) ' some red color
Dim Green As Long: Green = RGB(117, 156, 108) ' some green color
With shp.Fill.ForeColor
If .RGB = Red Then
.RGB = Green
Else ' it is not red
.RGB = Red
End If
End With
End Sub
3.) IF
Shorter
Sub ToggleShapeColorIfShort(shp As Shape)
Dim Red As Long: Red = RGB(199, 70, 52) ' some red color
Dim Green As Long: Green = RGB(117, 156, 108) ' some green color
With shp.Fill.ForeColor
If .RGB = Red Then .RGB = Green Else .RGB = Red
End With
End Sub
4.) IIF
Sub ChangeShapeColorIIf(ByVal shp As Shape)
Dim Red As Long: Red = RGB(199, 70, 52)
Dim Green As Long: Green = RGB(117, 156, 108)
With shp.Fill.ForeColor
.RGB = IIf(.RGB = Red, Green, Red)
End With
End Sub
5.) Select
Long
Sub ToggleShapeColorCaseElse(shp As Shape)
Dim Red As Long: Red = RGB(199, 70, 52) ' some red color
Dim Green As Long: Green = RGB(117, 156, 108) ' some green color
With shp.Fill.ForeColor
Select Case .RGB
Case Red: .RGB = Green
Case Green: .RGB = Red
Case Else: .RGB = Red ' or Green, your choice
End Select
End With
End Sub
6.) Select
Short
Sub ToggleShapeColorCase(shp As Shape)
Dim Red As Long: Red = RGB(199, 70, 52) ' some red color
Dim Green As Long: Green = RGB(117, 156, 108) ' some green color
With shp.Fill.ForeColor
Select Case .RGB
Case Red: .RGB = Green
Case Else: .RGB = Red
End Select
End With
End Sub
VBA PowerPoint works in mysterious ways, but this should work:
Sub ChangeShapeColour(oShp As Shape)
With oShp.Fill
If .ForeColor.RGB = RGB(199, 70, 52) Then
.ForeColor.RGB = RGB(117, 156, 108)
Else
.ForeColor.RGB = RGB(199, 70, 52)
End If
End With
End Sub