Delete all command buttons in document and add them back again - vba

I am trying to save some values from all command buttons in Word, then delete them, and then add them back again.
This is for printing purposes.
My question is how can I loop through all the command buttons to save their top, left, name and width values, how can I then delete them and then how can I create new buttons with their previous name, width and position.
I know how to create arrays and whatnot, all I need to figure out is the syntax for looping through the command buttons and for adding new command buttons with the values from the old ones.

Not tested the code but should work with little modification where ever required
Delete Command Button
For Each o In ActiveDocument.InlineShapes
If o.OLEFormat.Object.Name = "CommandButtonName" Then
'Save all properties of the command button using .Top, .Left, .Width etc
o.Delete
End If
Next
For Adding Command Button (Check http://support.microsoft.com/kb/246299):
'Add a command button to a new document
Dim doc As Word.Document
Dim shp As Word.InlineShape
Set doc = Documents.Add
Set shp = doc.Content.InlineShapes.AddOLEControl(ClassType:="Forms.CommandButton.1")
shp.OLEFormat.Object.Caption = "Click Here"
shp.OLEFormat.Object.Left = 100
shp.OLEFormat.Object.Top = 100
shp.OLEFormat.Object.Width = 255
shp.OLEFormat.Object.Visible = True

I've figured resizing the command buttons to 0x0 provided a more elegant option that didn't require arrays and was much quicker.

Related

Dynamically Drop/Draw/Insert Command Button into Visio Page and set text using VBA

I'm trying to drop/draw/insert a command button into a Visio page and set its text using VBA.
Currently I'm able to insert the button using the following VBA, but I'm not finding any way to edit the text.
' Generate Button
Dim generateButton As Visio.Shape
Set generateButton = migrationPlanPage.InsertObject("{D7053240-CE69-11CD-A777-00DD01143C57}", 0)
Below are two unsuccessful methods I've tried to set the button text value.
generateButton.CellsSRC(visButtonIcon, 0, visButtonCaption).Formula = "Test"
generateButton.Caption = "Test"
You can try:
Dim obj As Shape
Set generateButton = ActivePage.InsertObject("{D7053240-CE69-11CD-A777-00DD01143C57}", visInsertNoDesignModeTransition)
generateButton.Object.Caption = "Hello"

MS Word VBA code to align image to top right corner

I was trying to write a VBA macro to align an image to the top right corner of the page and set text wrapping to "Behind Text" and "Fixed Position on Page."
Normally I select the image and do all those settings through dialog boxes. But it gets tedious after a while. I'm wondering if there's a way to do it programmatically. I'm hoping I could open the page header, paste in my header image, and then click a macro button to have the macro align the still-selected image.
I tried recording a macro of my operations, but the macro did not record any of my dialog actions (behind text, fixed page position, etc). So that method provided no solution. I tried it with images inside and outside of page headers, without success.
Is it possible to have some VBA code align the currently selected image object? Ideally, I would open up the page header, paste in my header image, and run a VBA macro to do the four operations above (behind text, fixed position on page, align top to page, align right side to page). I'm hoping someone can show me how or point me to some documentation or examples that show how to do it.
UPDATE
I couldn't post to the forum for some reason, so I worked on the problem for a couple of days and finally pieced together this solution for the next person. I wish I knew where to look in a manual or tutorial for this kind of thing.
But the only way seems to be to cobble solutions together from forums on the net. Here's my contribution! :-)
Sub AlignTopRight()
' Paste an image into Word so it is still selected
' Then invoke this macro to align it to the top right corner
' And to set it behind text, fixed position on the page
Application.ScreenUpdating = False
Dim Shp As Shape
On Error Resume Next
'I'm not sure if this block is required, but it works
Set Shp = Selection.InlineShapes(1)
If Not Shp Is Nothing Then
Set Shp = Selection.InlineShapes(1).ConvertToShape
Else
Set Shp = Selection.ShapeRange.Item(1)
End If
If Not Shp Is Nothing Then
With Shp
.LockAspectRatio = True
' for absolute positioning
'.Left = CentimetersToPoints(5.5)
'.Top = CentimetersToPoints(0.5)
'.Width = CentimetersToPoints(2.5)
'put the image behind text
.WrapFormat.Type = wdWrapBehind
'this was the tricky part, discovering this
.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
.RelativeVerticalPosition = wdRelativeVerticalPositionPage
.Top = wdShapeTop 'if you say =0, it sets the AbsolutePx in the dialog
.Left = wdShapeRight 'these wdShapeXX objects set the Align field in the dialog
End With
End If
Set Shp = Nothing
Application.ScreenUpdating = True
End Sub
Just discovered this feature to answer my own question. See the answer in the question posting.

Explain some of the parameters in this Word macro to me

I was using code at the bottom that I found on the Internet to add commands to the Word 2013 right-click menu. Now that I have used it I was hoping to understand it better and could someone explain some of the parameters to me. I want to understand it better and case I want to run it again to add more commands. The official Microsoft help reference only confuses me.
How does Before:=30 work? At first I thought it simply counted down from the top of the right-click menu, but when I did this my commands wound up in the wrong place. I think it must be counting commands that aren’t show all the time.
Are Tag:="Save" and .Tag = "Save" the same and what are they.
What is .Caption?
The above three parameters seem very similar.
Sub EditRightClickMenu()
'
'
'
Dim cb As CommandBar
Dim ctl As CommandBarButton
On Error GoTo bye
CustomizationContext = NormalTemplate
Set cb = CommandBars("Text")
Set ctl = cb.FindControl(Tag:="Save")
If ctl Is Nothing Then
Set ctl = cb.Controls.Add(Type:=msoControlButton, _
Before:=30, Temporary:=True)
With ctl
.Caption = "Save"
.Tag = "Save"
.FaceId = 3
.BeginGroup = True
.OnAction = "MySave"
End With
End If
bye:
End Sub
The Before:=30 is indeed the command on the menu before which you wish to insert the new control. If you remove the line On Error GoTo bye line from your code and run it on a normal word install you'll get an error trying to set the line:
Set ctl = cb.Controls.Add(Type:=msoControlButton, _
Before:=30, Temporary:=True)
This is because there aren't 30 controls on the default Text right click menu. Change it to 5 and it'll work fine.
Tag:="Save" and .Tag="Save" are slightly different. The Tag:= notation is used when specifying variable inputs to a method, in this case its the Tag input to the function of FindControl. If you press Shift+F2 on your keyboard when selecting FindControl in you editor it'll take you to the definition of the method and all the variables. The .Tag notation refers to an objects property, in this case the Tag is being set as "Save" so it can be found if the macro is run again.
Finally .Caption is merely the text displayed on the menu control once created.

Word crashes on removing a Shape with VBA from a header

(disclaimer: i'm not a VBA programmer by occupation)
Attached to buttons in the Ribbon I have code to toggle the company logo in a Word Document.
One button for the logo type A, a second button for logo type B and a third for no logo (logo is preprintend on paper)
First I remove the logo with removeLogo and then i add it the requested logo with setLogoAt.
The first button click is fine (e.g. for Logo Type A), a logo is added to the header of the document. When i click an other button (e.g for Logo Type B) Word crashes (probably on removing the current logo)
What is wrong with my code (or less probably: with Word?)
Sub setLogoAt(left As Integer, path As String)
Dim logoShape As Shape
Dim anchorLocation As Range
Dim headerShapes As Shapes
Set logoShape = ActiveDocument. 'linebreks for readability
.Sections(1)
.Headers(wdHeaderFooterPrimary)
.Shapes
.AddPicture(FileName:=path, LinkToFile:=False,
SaveWithDocument:=True, left:=0,
Top:=0, Width:=100, Height:=80)
logoShape.name = "CompanyLogo"
logoShape.RelativeHorizontalPosition = wdRelativeHorizontalPositionPage
logoShape.RelativeVerticalPosition = wdRelativeVerticalPositionPage
logoShape.Top = CentimetersToPoints(0.1)
logoShape.left = CentimetersToPoints(left)
End Sub
Sub removeLogo()
Dim headerShapes As Shapes
Set headerShapes = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Shapes
Dim shapeToDelete As Shape
If (headerShapes.Count > 0) Then
If Not IsNull(headerShapes("CompanyLogo")) Then
Set shapeToDelete = headerShapes("CompanyLogo")
End If
End If
If Not (shapeToDelete Is Nothing) Then
shapeToDelete.Delete
End If
End Sub
edit
I steped trough my code. All is fine until I reach the line shapteToDelete.Delete in removeLogo. Here Word crashes hard, even while debugging. I'm using Word 2007 (and that is a requirement)
edit2
I cleared all macros, all normals.dot, all autoloading templates, then created a new document with the two routines above and this test method:
Sub test()
setLogoAt 5, "C:\path\to\logo.jpg"
removeLogo
setLogoAt 6, "C:\path\to\logo.jpg"
End Sub
When I run test it crashes in removeLogo at shapeToDelete.Delete.
Edit 3
I 'solved' the problem by first making the headers/footers view the active view in Word, then deleting the Shape and then returning to normal view. Very strange. It works but as a programmer I'm not happy.
Another potential solution is to try and select the shape first and then delete the selection:
shapeToDelete.Select
Selection.Delete
You would probably want to switch off screen updating if this works, else you'll get flickering as Word moves around the document.
I've experienced this problem before and normally with an automation error: "The object invoked has disconnected from its clients". I haven't yet found a solution.
However a good workaround is to hide the shape rather than delete it.
So:
shapeToDelete.Visible = False
This works:
I only have 2 boxes to hide so this isn't generic
Private Sub btnPrint_Click()
Dim hdrShapes As Shapes
Dim S As Shape
Dim aTohide(2) As String
Dim iNdx, i As Integer
iNdx = 0
' Hide buttons and print
Set hdrShapes = ActiveDocument.Sections(1).Headers(wdHeaderFooterPrimary).Shapes
' GET BUTTON NAMES (ACTUALLY TEXT BOXES
For Each S In hdrShapes
If S.Type = msoTextBox Then
aTohide(iNdx) = S.Name
iNdx = iNdx + 1
End If
Next
' now hide , use the arrays as the for each statement crashes
For i = 0 To 1
hdrShapes(aTohide(i)).Visible = msoFalse
Next
' print it
With ActiveDocument
.PrintOut
End With
' and unhide the buttons
For i = 0 To 1
hdrShapes(aTohide(i)).Visible = msoTrue
Next
Set hdrShapes = Nothing
End Sub

Entering information into the Notes section of a PowerPoint slide using VBA

I am trying to find out how you write VBA to enter a text box into a slide, and enter text. I am also trying to find vba for entering text into the notes section of a PowerPoint slide.
Any help would be greatly appreciated. I have tried to find a site specifically for this, but have not been able to do so
Entering text into a PPT slide is about the same as entering into the notes section.
You have to start out with a Slide object reference, which represents the slide you're adding to; and you add a text box shape to the slides' shapes collection.
Example:
Sub AddTextBoxToSlide()
Dim oDestSlide As PowerPoint.Slide
Set oDestSlide = ActivePresentation.Slides(1)
Dim slideWidth As Single
Dim slideHeight As Single
slideWidth = oDestSlide.Parent.PageSetup.SlideWidth
slideHeight = oDestSlide.Parent.PageSetup.SlideHeight
Dim oTextBox As PowerPoint.Shape
Set oTextBox = oDestSlide.Shapes.AddTextbox( _
Orientation:=msoTextOrientationHorizontal, _
Left:=0, _
Top:=0, _
Width:=slideWidth, _
Height:=slideHeight / 12)
oTextBox.TextFrame.TextRange.Text = "Shape text here"
End Sub
All this does is adds a text box shape to the first slide in the active presentation at the top of the slide. It is as wide as the slide and 1/12th the height of the slide. The parameters for Shapes.AddTextbox() are pretty self-explanatory...
To add to the notes section, I just use the NotesPage object on the slide your notes page is in...so the above code would be about the same, except:
Set oTextBox = DestSlide.NotesPage.Shapes.AddTextbox(msoTextOrientat...
This is an old question, but since you can't record macros in PowerPoint, people will be searching for questions like this until you can.
I didn't need this for adding text to slides, but I tried it for adding text to Notes. However, in Outline View, nothing appeared in my Notes section. It wasn't until I went to View-->Notes Page, and I saw the message I'd added -- at the top of the screen.
You see, when you change Set oTextBox = oDestSlide.Shapes to Set oTextBox = oDestSlide.NotesPage.Shapes, you're not adding text to the Notes. You're adding a textbox to the notes. And that textbox appears only in Notes Page view (at the top of the screen, until you move it).
What we really want to do is add our text to Placeholder 2 (the notes area) on the notes page, like this:
oDestSlide.NotesPage.Shapes.Placeholders(2).TextFrame.TextRange.InsertAfter "Notes text here"