I'm trying to add a little interaction to a PowerPoint presentation I'm working on. I'm written a little VB that will increase the size and position a particular chart object when the script runs. I'm tested the script in design mode and everything seems to work fine. When, however, I link my code to an action button and try to run it from within the slide show the code does not run. I do most of my VB in Excel so I have not run across this before. Can anyone suggest a fix for this. My code is set forth below:
Sub MoveChart23()
Dim s
For Each s In ActiveWindow.Selection.SlideRange.Shapes
If s.Name = "Chart 23" Then
s.Top = 50
s.Width = 620
s.Left = 50
s.Height = 400
End If
Next
End Sub
Thanks for your help.
Anyway, I think your problem is in the following line:
For Each s In ActiveWindow.Selection.SlideRange.Shapes
while you have no Selection in presentation mode. Depending on the way you run and control the whole presentation you should use something like this instead:
For Each s In ActiveWindow.Slides(1).Shapes
But if you need to refer to currently viewed slide you should go this way:
For Each s In SlideShowWindows(1).View.Slide.Shapes
Related
I'm working on a Word Macro to streamline doing my University Mathematics and Statistics Coursework. Basically, selecting a group of equations and running it changes font size, line height and formats the paragraph in the way that I want to be common to all my maths/equations sections. It's great, but there's one little bit which I still have to do "manually", so to speak, which is right clicking and selecting "Align at equals".
Now the reason I'm asking this here and not on Super User is that I think I've exhausted all ways of doing this at the "record macro" stage. I found out how to access the right click menu without right clicking and accessed the "align at equals" option during record. Nothing was recorded.
Truth be told I'd prefer to code the lot anyway as it gives me more control. So, I'll post my code here and if anyone knows what line(s) of code I need to add to get it to replicate the "align at equals" command I would be extremely grateful.
Sub Equationiser()
'
' Equationiser Macro
'
'
With Selection.ParagraphFormat
.SpaceBefore = 12
.SpaceAfter = 12
.LineSpacingRule = wdLineSpace1pt5
End With
Selection.Font.Size = 20
End Sub
So, ideally just before the "With Selection.ParagraphFormat" section there would be some kind of "AlignAtEquals" command or whatever is needed so that, on one keypress, I would be able to align all the equals, set the line height to 1.5, place a 12 point space before and after the paragraph and change the font size to 20.
My absolute ideal would also be to programatically select all equation boxes that are in the same block, as "align at equals" is notoriously fussy and finicky as to when it will execute. That might also mean there may be a try and catch needed depending on whether trying to run "align at equals" when it wouldn't normally be available from the right click menu would do nothing or cause an error.
Any help on these two implementations would be gratefully appreciated but I'd happily settle for just the first.
I've built a solution that should address your needs, based on:
Looking through the equation to find the equal-sign.
Get the location of that equal-sign
Use that location to set the AlignPoint property of the OMath object
that is your equation
Use this MSDN reference if you want to explore more
Sub Equationiser()
'
' Equationiser Macro
'
'
Dim equationCounter As Long, charLoc As Long, FormattedTextLoc As Long
With Selection
For equationCounter = 1 To .OMaths.Count:
FormattedTextLoc = 0
For charLoc = 1 To Len(.OMaths(equationCounter).Range.FormattedText):
FormattedTextLoc = FormattedTextLoc + Len(.OMaths(equationCounter).Range.FormattedText.Characters(charLoc))
If .OMaths(equationCounter).Range.FormattedText.Characters(charLoc) = "=" Then
.OMaths(equationCounter).AlignPoint = (FormattedTextLoc - 1)
Exit For
End If
Next charLoc
Next equationCounter
End With
With Selection.ParagraphFormat
.SpaceBefore = 12
.SpaceAfter = 12
.LineSpacingRule = wdLineSpace1pt5
End With
Selection.Font.Size = 20
End Sub
I've done some brief testing that from what I can see this should be able to manage several code-blocks, i.e. when selecting 2 code-blocks it will align-at-equals all equations in the first block, then align-at-equals all equations in the second block (both blocks are not aligned with each oter) - is this your desired outcome to your request: My absolute ideal would also be to programatically select all equation boxes that are in the same block, as "align at equals" is notoriously fussy and finicky as to when it will execute.
I am fairly familiar with userforms, so I decided to try and get a little fancy and attempted to make a userform grow/shrink and reposition to align center based on a checkbox change event.
The code is working as intended, but there is one issue. When shrinking the userform, the userform leaves a trail of all size increments set during the loop. This makes the program look less "smooth". I've included a screenshot of the issue as well as the relevant code.
I've tried including variations of DoEvents and Application.ScreenUpdating. ScreenUpdating seemed to do nothing, while DoEvents halved the number of trails, but also made the text inside the userform go a bit crazy during execution.
Note: The checkbox is named "MyCheckBox" and the userform is named "ColumnSelect"
Perhaps I'm trying to do too much with excels memory or w/e.. Any help is appreciated though. Thank you!
Private Sub MyCheckBox_Change()
Dim w As Integer
Application.ScreenUpdating = False
If MyCheckBox.Value = True Then
For w = 425 To 838 Step 7
ColumnSelect.Width = ColumnSelect.Width + 7
ColumnSelect.Left = ColumnSelect.Left - 3.5
Next w
Else
'DoEvents
For w = 838 To 425 Step -7
ColumnSelect.Width = ColumnSelect.Width - 7
ColumnSelect.Left = ColumnSelect.Left + 3.5
Next w
End If
Application.ScreenUpdating = True
End Sub
I have tested the file on my home (gaming) of, which is much more powerful than the laptop/monitor setup I used when posing the question. There was no visible trail when resizing the user form, so it seems user A.S.H was correct in his assumption that the issue involved the PC/monitor rather than the code.
If you want credit for the answer I will be happy to give it to you, just submit your own. Otherwise I'll mark this as answerws. Thanks for your help
I'm busy with some word automation and have run into an issue whereby a context menu within a document has items in, that I wish to remove.
Once the document is open, through vba I can remove these items by running the following code;
[VBA]
Dim oContextMenu As CommandBar
Dim oContextMenuItem As CommandBarControl
'Make changes to the ActiceDocument only (this is needed to make any changes to this document).
CustomizationContext = ActiveDocument
For Each oContextMenu In ActiveDocument.CommandBars
If oContextMenu.Type = MsoBarType.msoBarTypePopup Then 'Loop through all the context menus of type (msoBarTypePopup)
For Each oContextMenuItem In oContextMenu.Controls
If (InStr(oContextMenuItem.Caption, "Smokeball")) Then
oContextMenuItem.Delete
End If
Next
End If
Next
If I execute this code and check the document, all contextMenu sub items that contain the text "smokeball" are removed.
When I try move this code to my VB.NET solution (I have no choice of language, so VB it is), I get errors on the CustomizationContext = ActiveDocument line (this line has to be there for it to affect the current document).
The error I get is CustomizationContext' is not a by reference property.
Does anyone know how to get just that ONE line equivalent for vb.net?
Thanks in advance.
EDIT: In case you need to see the vb.net sub:
Private Sub RemoveUnwantedContextMenuItems()
Dim oContextMenu As CommandBar
Dim oContextMenuItem As CommandBarControl
'Make changes to the ActiceDocument only (this is needed to make any changes to this document).
WordApplication.CustomizationContext = WordApplication.ActiveDocument 'This is the error.
For Each oContextMenu In WordApplication.CommandBars
If oContextMenu.Type = MsoBarType.msoBarTypePopup Then 'Loop through all the context menus of type (msoBarTypePopup)
For Each oContextMenuItem In oContextMenu.Controls
If (InStr(oContextMenuItem.Caption, "Smokeball")) Then
oContextMenuItem.Delete()
End If
Next
End If
Next
End Sub
PS - I have also already tried using the .AttachedTemplate as well as .Normal / .NormalTemplate
Jules pointed me in the right direction with his sample code.
After lots of playing around I noticed that somewhere in the solution, the [TYPE] of WordApplication was getting changed to a dynamic type of sorts, hence, it couldn't use CustomizationContext.
My solution was this:
I changed this line;
WordApplication.CustomizationContext = WordApplication.ActiveDocument
To this:
CType(WordApplication, Microsoft.Office.Interop.Word.Application).CustomizationContext = WordApplication.ActiveDocument
Forcing the types to be correct.
Simple solution but took some time.
Thanks to Jules for pointing me in the right direction.
(Points should go to you).
I've created a bit of code that populates an Excel sheet with Lables, TextBoxes and a ListBox. After populating the ListBox with .List=Sheets().Range().Value I am unable to click to select an item. If I save the sheet, close and reopen it works fine.
I've checked
http://blogs.technet.com/b/the_microsoft_excel_support_team_blog/archive/2014/12/11/forms-controls-stop-working-after-december-2014-updates-.aspx
But I'm not getting an error so this seems the wrong fix.
When I search KB for the following
http://support.microsoft.com/kb/3025036/EN-US
The symptoms are different from what I'm experiencing.
I also tried using Sheets().Activate as posted here:
Excel ActiveX Listbox not enabled on file open
But that didn't help or I'm implementing it incorrectly.
This is the code that creates the ListBox
Private Sub Create_ListBox_ActiveXControlProperties()
Dim oLISTBOX As OLEObject
Set oLISTBOX = ActiveSheet.OLEObjects.Add(classtype:="Forms.ListBox.1", Top:=35, Width:=500, Left:=650, Height:=600)
ActiveSheet.OLEObjects("ListBox1").Object.Font.Size = 14
ActiveSheet.OLEObjects("ListBox1").Object.ListStyle = 0
ActiveSheet.OLEObjects("ListBox1").Object.List = Sheets("Search Criteria Control").Range("g1:g21").Value
End Sub
Can anyone suggest where I can look for a solution to this?
Can't give you an explanation but if you add Activesheet.Select to the end of your Sub then you can select your items.
Another way of writing:
Sub M_snb()
With ActiveSheet.OLEObjects.Add("Forms.ListBox.1", , , , , , , 35, 50, 65, 60)
.Object.Font.Size = 14
.Object.List = ActiveSheet.Range("g1:g21").Value
.Object.ListIndex = 0
.Parent.select
End With
End Sub
For the purposes of documenting all possible solutions, here is what worked for me.
None of the workarounds provided in all forums helped me.
I added a bunch of ListBoxes dynamically including location, height, width, ListRange etc. When my code would create the controls in the Worksheet, I wasn't able to select the items in the ListBox.
This is what solved my problem: .OLEObjects().Activate
You need to activate the control soon after creating it.
Same issue there. As a workaround(app.activate don't works for me and the bahavior isn't wished), you can just add 1 to the height, it will sligthly redraw each object and réactivate it.
ListBox_Options1.Height = ListBox_Options1.Height + 1
It's a workaround, not the source of the bug.
I am all new to powerpoint vba. All i want do is to write a little piece of code wich allows me to change the layout of my slide depending on a selection made by clicking a button.
The Problem with my code is that i get the runtimeerror 438.
Here is what i have:
Private Sub CommandButton1_Click() 'Klick Button 1'
ActivePresentation.Slides(10).Delete
ActivePresentation.Slides(9).Delete
ActivePresentation.Slides(8).Delete
Dim x As Integer
For x = 1 To 100
With ActivePresentation.Slides(x)
If .CustomLayout = .CustomLayout(8) Then
Set .CustomLayout = .CustomLayout(12)
End If
End With
Next x
End Sub
EDIT: Error Description is: "object does not support this property or method"
I'd really appreciate any kind of help and constructive input.
EDIT II: I understand now that .CustomLayout returns a custom layout. But how can i set/change the Layout of a certrain slide? How do i need to adress it?
Thank you very much
EDIT III: I still have no solution and i am really frustrated right now. You guys are my last chance for help I guess. So here again my code right now:
Dim x As Integer
For x = 7 To 100
If ActivePresentation.Slides(x).CustomLayout = ActivePresentation.Designs(1).SlideMaster.CustomLayouts(8) Then ActivePresentation.Slides(x).CustomLayout = ActivePresentation.Designs(1).SlideMaster.CustomLayouts(12)
End If
Next x
I still get the runtime error descriped above. How can i get rid of it and make my code work?
Thank you very much!
CustomLayout is an object tha define a custom layout, in the interface they are:
In vba they can be accessed using the ActivePresentation.Designs.SlideMaster object.
Every Slide object can have, obviously, only 1 CustomLayout applied, and you can access it using the property CustomLayout.
So, if you want to change the slide 1 CustomLayout using the CustomLayout n. 3 you have to do:
ActivePresentation.Slides(1).CustomLayout = ActivePresentation.Designs(1).SlideMaster.CustomLayouts(3)
See : MSDN
Regarding your code, you MUST use Names in your If block comaprison, so:
If ActivePresentation.Slides(x).CustomLayout.Name = ActivePresentation.Designs(1).SlideMaster.CustomLayouts(3).Name Then
ActivePresentation.Slides(x).CustomLayout = ActivePresentation.Designs(1).SlideMaster.CustomLayouts(7)
End If