Why Does It Make A Difference If A Macro is Run When Slide Show Has Started - vba

Apologies if this is a basic question, but I am a newbie at VBA and have spent the past two weeks learning the language. I am trying to make a learning resource using PowerPoint.
I made a good macro which seems to work perfectly when it is run outside the slide show. (I typically just pressed F5 within my VBA Editor to see what the code was doing.) However, when I try running the macro when the slide show is running (using an action button) it does not work as intended. To be more precise it appears to stop running and not show any errors or provide reasons why the macro has stopped.
I tried doing a Google search on this topic, but could not find anything. I would be very grateful if anyone could provide any reasons or suggest any information sources as to why macros work differently when the slide show is running as opposed to not running? Are there any standard practices to ensure that the macros will work when the slide show is run?
Thank you for any comments!
EDIT 02/07/20 - responding to a comment I attach the code below and have explained what I am trying to do in comments below
Sub DataInputMacro()
'This procedure attempts to group (and do a check) of all 20 answer tiles.
Dim oSh As Shape
Dim i As Integer 'This is for the For statement
Dim iix As Integer 'This is to store the x position of the tiles.
Dim iiy As Integer 'This is to store the y position of the tiles.
For i = 1 To 20
If i = 1 Or i = 3 Or i = 5 Or i = 7 Or i = 9 Then
iix = 9
ElseIf i = 2 Or i = 4 Or i = 6 Or i = 8 Or i = 10 Then
iix = 198
ElseIf i = 11 Or i = 13 Or i = 15 Or i = 17 Or i = 19 Then
iix = 587
Else
iix = 774
End If
If i = 1 Or i = 2 Or i = 11 Or i = 12 Then
iiy = 9
ElseIf i = 3 Or i = 4 Or i = 13 Or i = 14 Then
iiy = 113
ElseIf i = 5 Or i = 6 Or i = 15 Or i = 16 Then
iiy = 218
ElseIf i = 7 Or i = 8 Or i = 17 Or i = 18 Then
iiy = 323
Else
iiy = 428
End If
ActiveWindow.Selection.Unselect 'This ensures that nothing has already been selected on the slide (which could then get grouped with the first rectangle!)
For Each oSh In ActivePresentation.Slides("DataInput").Shapes
If IsWithinRange(oSh, iix - 1, iiy - 1, iix + 179, iiy + 97) Then
'MsgBox oSh.Name & " " & oSh.Left
oSh.Select (msoFalse)
End If
Next
If ActiveWindow.Selection.ShapeRange.Count > 1 Then
With ActiveWindow.Selection.ShapeRange.Group
.Name = "GroupAnswer" & i
.Select
End With
ElseIf ActiveWindow.Selection.ShapeRange.Type = msoGroup Then
ActiveWindow.Selection.ShapeRange.Name = "GroupAnswer" & i & "a"
ElseIf ActiveWindow.Selection.ShapeRange.Count = 1 Then
MsgBox "Sorry, but there is a set up issues of your answer boxes. Either (1) one of your answer boxes does not contain a separate textbox or image or (2) there is a missing yellow rectangle! I note for point (1) the text must be placed in a separate text box to the yellow rectangle!"
End
End If
Next i
UpdateTitle 'This is a separate function that updates the title on the front slide.
CheckFor20Groups 'This is a function that checks that there are 20 groups for the rest of the program to use!
End Sub

Shape.Select method does not work in slide view - see remarks here: Shape.Select method (PowerPoint) - so you will have to use another method for working with your shapes - try using a variable to refer to the ShapeRange you are working with rather than ActiveWindow.Selection.ShapeRange - that way you can work with them without needing to select them.

Related

VBA Array of picture boxes

I am making a game for my intro to comp programming class, I have a 6 by 6 board where you do something different on each tile. I am currently working on a mob collision sub where if the player collides with the mob the player has to battle. Right now I have an issue with creating multiple of the same time of mob. Here is my code
Public Sub creeperS()
' Dim creeper As New PictureBox
'This is now above so it can be used by other subs
Dim creepercount As Integer
creeper.Width = 32
creeper.Height = 32
creeper.BackColor = Color.LimeGreen
creepercount = rand.Next(0, 36)
If creepercount = 0 Then
Me.Controls.Add(creeper)
creeper.Top = 95
creeper.Left = 84
creeper.BringToFront()
ElseIf creepercount = 1 Then
Me.Controls.Add(creeper)
creeper.Top = 95
creeper.Left = 184
creeper.BringToFront()
ElseIf creepercount = 2 Then
Me.Controls.Add(creeper)
creeper.Top = 95
creeper.Left = 284
creeper.BringToFront()
ElseIf creepercount = 3 Then
It does this all the way to 36, Im wondering if you can make a picture box array so i can have several of a mob on the board.
You did not post your class code, so I will try showing you a generic method to create controls and keep them in an array. In fact a Dictionary object...
Create a variable on top of your form, at the declarations side:
Option Explicit
Private shDict As Object
Then put the next code in your Form Initialize event:
Dim i As Long, No As Long
Dim txtBox As MSForms.TextBox
No = 36 'your needed controls
Set shDict = CreateObject("Scripting.Dictionary")
For i = 84 To No * 100 Step 100
Set txtBox = Controls.Add("Forms.TextBox.1", "txt_" & i)
shDict.Add txtBox.Name, Array(txtBox, 95, i, True)
Next i
Not having your class, my example code creates text boxes and fills their Name, Top and Left properties in a Dictionary array. It can keep objects, arrays, strings etc. I tried to use your Top and Left logic, but big part of them will not fit on the form surface...
Place a button on the form (named btRepAll). It will preposition all created shapes according to the values previously input in shDict.
Private Sub btRepAll_Click()
Dim i As Long
For i = 84 To shDict.Count * 100 Step 100
shDict("txt_" & i)(0).top = shDict("txt_" & i)(1)
shDict("txt_" & i)(0).left = shDict("txt_" & i)(2)
Next i
End Sub
I wanted to ask some other preliminary questions, to clarify myself regarding your real need, but since you did not answered a simple one and I cannot stay to much at my office, I preferred to post a generic answer. You can load as many properties as you want. Please try building something similar, able to better fit your real need.

VBA values from dynamically added combobox

First post here. Self-taught VBA so I'm always aware that code may not be perfect. Anyway...
Creating a Userform Questionnaire. I don't know how many questions there will be, and I want it to be easy for anyone to add new questions to the form. Idea is to have the questions listed on a Sheet so that as new questions are added, the userbox will resize accordingly and add in all the questions.
Doing this was no problem:
Public Sub UserForm_Activate()
QuestionsCount = Application.WorksheetFunction.CountA(Sheets("QuestionData").Range("A:A")) - 1
ResultsCount = Application.WorksheetFunction.CountA(Sheets("QuestionData").Range("B:B")) - 1
DepartmentCount = Application.WorksheetFunction.CountA(Sheets("QuestionData").Range("C:C")) - 1
QuestionForm1.ScrollHeight = (QuestionsCount) * 70
QuestionForm1.Width = 258
CommandButton1.Top = (QuestionsCount - 1) * 70
CommandButton1.Left = 42
CommandButton2.Top = (QuestionsCount - 1) * 70
CommandButton2.Left = 132
Dim i As Integer
Dim QQ(1 To 100) As MSForms.Control
Dim QA(1 To 100) As MSForms.Control
For i = 5 To QuestionsCount
Set QQ(i) = QuestionForm1.Controls.Add("Forms.Label.1")
Set QA(i) = QuestionForm1.Controls.Add("Forms.ComboBox.1")
With QQ(i)
.Caption = Sheets("QuestionData").Range("A" & (i + 1))
.Width = 84
.Top = i * 58
.Left = 24
.Name = "Label" & i
End With
With QA(i)
.RowSource = "QuestionData!B2:B" & ResultsCount + 1
.Width = 96
.Top = i * 58
.Left = 138
.Name = "Combo" & i
.Value = ""
End With
Next i
End Sub
Userform is created and all the questions I want are there (positioning of the command buttons isn't great, I know, will fix this soon)
The only problem is taking the values. The answers are in a ComboBox, the user will select the answers they want and click the Submit button. The idea was to then take the values from each comboBox and put them into another sheet.
The issue I'm having is that the global variables seem to disappear at the end of the sub. So when the user inserts their answers and clicks Submit, the macro tries to take values that aren't there.
What are the names of the added ComboBoxes? Where are their values stored? Is there a way to not End Sub so that the values stay as Global Variables? Any other ideas on what to do?
Any help would be appreciated...hopefully I've explained myself well!
thanks in advance!!
You've named your comboboxes using .Name = "Combo" & i.
So you could create a routine that runs on pressing a SUBMIT button or similar that reads the values with:
QuestionForm1.Controls("Combo5").Value
You could also set this up as a loop to build an array with:
Private Sub CommandButton1_Click()
ResultsCount = Application.WorksheetFunction.CountA(Sheets("QuestionData").Range("B:B")) - 1
Dim chosenvalue(100)
For i = 5 To ResultsCount
chosenvalue(i) = QuestionForm1.Controls("Combo" & i).Value
Debug.Print "Button " & i & " set to " & chosenvalue(i)
Next
End Sub

VBA Excel Transform to loop

Here i have my hundred line of code please enlighten me about how do i put line code into loop
here is my try but i wont work out still trying
If sp.Name Like "Rounded Rectangle*" Or sp.Name Like "Oval*" Then
For i = 11 To 100
x = i - 9
Sheet2.Shapes.Range(Array("Rounded Rectangle " + i)).TextFrame.Characters.Text = Sheet1.Range("A" + x)
Next i
End If
and repeat until X = 110
in this case how can i change it in to correct loop please advice
thank you
This is a general approach to making a loop to cover a string variable....say we want to loop over Shape("Rectangle 1")....Shape("Rectangle 2")....Shape("Rectangle 3)..... , etc.
Dim str As String, i As Long
For i = 11 To 100
str = "Rectangle " & CStr(i)
Sheets2.Shapes(str)................
Next i
and use a similar approach to make "A2"..."A3".........
simple math:
For i = 11 To 100
change to
For i = 11 To 119

PowerPoint Programming: Indentation with Ruler margin levels not working?

Recently we upgraded one our PowerPoint addin to support 2007 and 2010. most of the items we were able to port without problem. one problem we have is that indentations doesn't work when create tables or shapes using the addin.
for eg: same table gets dropped with proper indentation in 2003 but same thing doesn't get indentation when added to using 2007.
below is the code snippet that allows indenting:
With PropertyValues.ObjShape.Table.Cell(row, col).Shape.TextFrame.Ruler
For rulerCount = 0 To 5
.Levels(rulerCount).FirstMargin = rulerFirstMargin(rulerCount) '.LeftMargin = rulerLeftMargin
.Levels(rulerCount).LeftMargin = rulerLeftMargin(rulerCount) 'Left indent marker
Next rulerCount
End With
any idea why this is not working ?
I read the following thread too but didn't help much http://answers.microsoft.com/en-us/office/forum/office_2007-customize/why-shapetextframerulerlevelsi-cant-set-the-bullet/9eac3e46-b13b-433e-b588-216ead1d9c1a?tab=AllReplies#tabs
Updated Code:
PropertyValues.ObjShape.Table.Cell(row, col).Shape.TextFrame.TextRange.Text = "N/A"
With PropertyValues.ObjShape.Table.Cell(row, col).Shape.TextFrame
'Dim rulerCount As Short
For rulerCount = 1 To 5
.Ruler.Levels(rulerCount).FirstMargin = 10 * rulerCount 'rulerFirstMargin(rulerCount) '.LeftMargin = rulerLeftMargin
.Ruler.Levels(rulerCount).LeftMargin = 20 * rulerCount 'rulerLeftMargin(rulerCount) 'Left indent marker
Next rulerCount
End With
PropertyValues.ObjShape.Table.Cell(row, col).Shape.TextFrame.TextRange.Text = text
FWIW, in 2007 and up, you can now have up to 9 ruler levels instead of 5 as in earler versions. But your code should work as is. Here's a simplified version that does work on an arbitrary cell (2,2) of a table:
Dim oSh As Shape
Dim x As Long
Set oSh = ActiveWindow.Selection.ShapeRange(1)
With oSh.Table.Cell(2, 2).Shape.TextFrame
For x = 1 To 9
.Ruler.Levels(x).LeftMargin = x * 10
.Ruler.Levels(x).FirstMargin = x * 20
Next
End With
The other thing you might be running into is that you can apply certain types of formatting (including ruler settings) all you like; if there's no text at the level you're applying it to, PPT won't bark. It'll ignore you. Your settings will have no effect. Sometimes you need to check for text, supply some if there's none there (something highly improbable in the real world) then delete all instances of your improbable text afterwards.
Ugly. Yes.
Here we add text and set indent levels before trying to FORMAT each indent level:
Sub test()
Dim oSh As Shape
Set oSh = ActiveWindow.Selection.ShapeRange(1)
Dim RulerCount As Long
Dim sTemp As String
sTemp = "##$%" ' dummy text
With oSh.Table.Cell(2, 3).Shape.TextFrame
For RulerCount = 1 To 5
.TextRange.Paragraphs(RulerCount).Text = sTemp & vbCrLf
.TextRange.Paragraphs(RulerCount).IndentLevel = RulerCount
Next
For RulerCount = 1 To 5
.Ruler.Levels(RulerCount).FirstMargin = 10 * RulerCount 'rulerFirstMargin(rulerCount) '.LeftMargin = rulerLeftMargin
.Ruler.Levels(RulerCount).LeftMargin = 20 * RulerCount 'rulerLeftMargin(rulerCount) 'Left indent marker
Next RulerCount
End With
End Sub

Trouble with looping in VBA (access) to put items on a form and position them correctly

I've been trying to make a form with 68 items while positioning all the items on a form via a loop, but this loop isn't working :( Can someone please help me get this to work? I've tried looking everywhere but can't see what to do :/
Dim Items(67) As String
For x = 0 To 67
Items(x) = "Ctl" & x
Next
#It goes from 1 here as I manually set up 1 otherwise (x - 1) wont work.
For x = 1 To 67
Form_Home.Items(x).Top = 0
Form_Home.Items(x).Left = (Form_MainScreen.Items(x - 1).Left) + (Form_MainScreen.Items(x - 1).Width)
Form_Home.Items(x).Height = 225
Form_Home.Items(x).Width = 500
Next
Thank you everyone :)
What do you mean with Form_Home.Items? if you already have controls added to your forms, probably there is a Controls collection, so you can iterate trough it and set its properties, assuming each control has a name of the form Ctl0, Ctl1, Ctl2... then you can proceed as follow:
Dim ct_name as String
Dim ct_name_before as String
For x = 1 To 67
ct_name_before = "Ctl" & CStr(Cint(x-1))
ct_name = "Ctl" & CStr(x)
Form_Home.Controls(ct_name).Top = 0
Form_Home.Controls(ct_name).Left = (Form_MainScreen.Items(ct_name_before).Left) + _
(Form_MainScreen.Items(ct_name_before).Width)
Form_Home.Controls(ct_name).Height = 225
Next
Some version of VBA allow you to create array of controls sharing all the same name and having different index, then you can iterate through the array to get each control.