I have the following code to add a menu item on the Word 2013 right click menu:
Sub CreateMenuItem()
Dim MenuButton As CommandBarButton
With CommandBars("Text")
Set MenuButton = .Controls.Add(msoControlButton)
With MenuButton
.Caption = ChrW(&H2714) '"Correct"
.Style = msoButtonCaption
.OnAction = "InsertMark"
End With
End With
End Sub
The issue is that the new menu item is not displayed when I right click on a Text box or a table.
How do I remove a menu item that is not used by me, for example "Translate"
Please Assist
Thinus
Word provides a completely different CommandBar object for each context-sensitive menu, rather than dynamically changing the contents of a single menu. That means you need to make the change for each context in which your command should appear.
You can generate a list of CommandBars by looping the collection and writing the various properties out (for example, in a new document). Then you have to inspect that list, pick out the likely candidates, run your code then see if you guessed correctly.
You want to be very careful where these changes are SAVED in Word. If you don't specify it specifically, Word could save the change in one place and delete it (assuming you "undo" your changes) in a different one. This can really muck up the Word configuration and make users extremely unhappy. So always use Application.CustomizationContext at the beginning of code that changes the CommandBars. The CustomizationContext can be any Document or Template object.
NOTE: The CommandBars object is actually deprecated as of Word 2010. From Word 2013 onwards the context menus should be customized using Ribbon XML. Just saying... It's possible that in a future version your code will no longer work.
Related
I built a Microsoft Word template with a userform containing textboxes. I want to copy the data of two textboxes into the clipboard separately upon submitting the completed userform. Just to clarify I want each textbox to have its own entry into the clipboard for easy access in the future.
Below is the code I'm using but when I repeat the procedure it replaces the first textbox in the clipboard with the second. Any help would be greatly appreciated.
Sub ComandButton_click()
Dim clipboard As MSForms.DataObject
Set clipboard = New MSForms.DataObject
clipboard.SetText Me.TextBox1.value
clipboard.PutInClipboard
End Sub
EDIT (additional background):
For accessing the information put on the Clipboard I created a custom QAT. One of the buttons on the toolbar opens the clipboard so they can easily begin to paste the name they need at any one time. Most reports involve two people so I want to send the value of two textboxes into the clipboard as if you individually selected and copied each name. My first idea was to assign a keyboard shortcut to the value of the two textboxes but I settled on utilizing the clipboard tab.
Given what you've told us, I'm guessing you're calling up the Office Clipboard. This is different from the Windows Clipboard, which is what your code is using. The Office Clipboard is not exposed to the developer (for internal, MS use only). There is a way to put information on it, but I'm uncertain how reliable it is; YMMV (your mileage may vary).
The code for your UserForm to call a procedure responsible for writing the information:
PutContentOnOfficeClipboard Me.[textBoxName].Value
PutContentOnOfficeClipboard Me.[textBoxName].Value
The procedure writes the text to the end of the document, copies it, then deletes again. In my tests, this all shows up on the Office Clipboard:
Sub PutContentOnOfficeClipboard(s As String)
Dim rng As word.Range
Set rng = ActiveDocument.Content
rng.Collapse wdCollapseEnd
rng.Text = s
rng.Copy
rng.Delete
End Sub
If it turns out to be unreliable, then you need a different approach. Here are some thoughts on alternative methods...
A taskpane is optimal as it makes the information visibly available users. Unfortunately, task panes aren't available to the VBA Developer. They can be used from a VSTO solution or an Office-JS solution, but that may be more effort than you're willing/able to put into the project (steep learning curve, enterprise deployment requirement, etc.)
Besides keyboard shortcuts (which aren't a bad idea to have in addition to any visible interface):
A dropdown list on the QAT or the Ribbon
Two buttons on the QAT or the Ribbon
Modify the Right-click (context) menu with two controls to which you can write the names as needed. (Requires call-back macros to make the dynamic update)
Save the entries as AutoText/Building Blocks, possibly to use in conjunction
with a BuildingBlock content control (which can be filtered to show only your entries; AutoText can also be used selectively from the keyboard).
Make a small, non-modal UserForm with buttons. You could optionally use the Windows API to make it "always on-top".
I'm trying to create my own menu in Excel's (2010) Ribbon.
I wrote the following Sub to create a 'test' menu but I cannot find any evidence that the menu was created other than it being listed in the Controls Collection.
I feel like I've done everything correctly especially since I looked up bunch of code samples (example, this does not work for me either) from other people as well.
I guess my question is twofold, does the code below produce a new menu in YOUR Excel, and if so any idea why would this fail on my computer?
Sub CreateInterface()
Dim Controls As CommandBarControls
Dim CmdBar As CommandBarControl
Dim NewMenu As CommandBarControl
Set Controls = Application.CommandBars("Worksheet Menu Bar").Controls
Set NewMenu = Controls.Add(Type:=msoControlPopup, Temporary:=True, before:=Controls.Count)
NewMenu.Caption = "&Test"
NewMenu.Visible = True
For Each CmdBar In Controls
Debug.Print CmdBar.Caption & "|" & CmdBar.Tag
Next
End Sub
EDIT:
Thanks to D.O. I can see that the code is working it just isn't creating a new menu in the ribbon (like the default ones (Home, Insert, Page Layout, etc.)).
That being said to the best of my knowledge this was supposed to create a new menu, not an item in one of the menus, how can I actually create a new menu?
To the best of my knowledge, the old (pre-2007) CommandBars and Controls way is obsolete enough that it only adds buttons to the "Add-ins" ribbon tab. This is for backward compatibility with old Office solutions, so that they can still be used (somewhat) under 2007+ Office apps.
The way forward (if you plan on using Office 2007 and up) is to modify the ribbon itself. It's a completely new paradigm, and real-time customizations are done in a completely different way, but if you get the hang of it (it's not that difficult) it is quite useful.I suggest Googling some ribbon tutorials, and using the "Custom UI editor" tool to add your ribbon code to your Office files. Ron de Bruin's web site is always a good resource for more information.
I have an document in word, which has some fields to be filled, and an button to which I want to assign a macro. When that button is clicked, that same form with empty fields needs to be appended to the end of document, including the button (which can be clicked again and do the same thing).
Here is the document I have:
https://drive.google.com/file/d/0B_2kyqxMx5x4UkxfOHJhOGVPdnc/view?usp=sharing
The main problem with what you want to do is dynamically linking the button to the macro code to be executed. The most obvious type of button to use is the legacy ActiveX control in the Ribbon's Developer tab. But that requires its own procedure entry in the document's ThisDocument class module. While it's possible to add code to modules "on the fly" this involves disabling a security option.
A more straignt forward approach is to use the MacroButton field. This creates a clickable text within the document. It can display text or a graphic (so that it looks like a button) and is assigned the name of any public Sub that takes no parameters:
{ MACROBUTTON NameOfMacro Click here }
Ctrl+F9 to insert the field code brackets; Alt+F9 to toggle between field code and field result.
Graphics in Word 2010 and later:* The was a change to the graphics engine in Word 2010 which affects the behavior of graphics objects in the MacroButton field. Clicking the object triggers the Ribbon utility for working with graphics - the field code no longer "hides" the graphic. There are a number of ways you can work around this:
Use an IncludePicture field (which works with the old graphics format) to bring in an outside picture file. Once the linked picture is in the field it can be converted to a static picture by selecting the IncludePicture field and pressing Ctrl+Shift+F9. Word respects the old graphic format and the picture is click-able.
{ MacroButton NameOfMacro {IncludePicture "C:\\Path\\picture.jpg" } }
Use the old *.doc file format. Note that this will restrict some of the things that can be done with the document, but it will force use of the old graphics engine.
Instead of a MacroButton field, use the WindowBeforeDoubleClick event or WindowSelectionChange event to run the code.
*With the exception of unlinking the IncludePicture field (which I discovered myself), this information came from this discussion on the Microsoft Answers site
If you want to run the macro with a single rather than a double-click (the default) you need to run the following line of code. This applies to the entire Word application and needs to be run everytime Word restarts. You could put it in an AutoNew macro in the template / AutoOpen macro in the document:
Application.Options.ButtonFieldClicks = 1
The simplest way to store the entire content you want to insert repeatedly is as a Building Block (formerly known as AutoText).
BuildingBlocks are stored in templates. If your document is being created from a template, that would be the logical place. Another possibility would be a special template you use for this purpose. Normal.dotm can also be used but keep in mind this does sometimes get removed.
(Note: if you're using a template for the document that would also be the best place to store the macro attached to the macro button.)
Once this is set up, all your code needs to do is insert the BuidlingBlock at the end of the document.
Is it possible to create a custom layout, existing ones are:
Print layout
Full Screen reading
Web layout
Outline
Draft
These can be found in the View Ribbon under the group Document Views.
My aim is to get my own layout button in either the existing View Ribbon (if it is possible to modify it) or add a new layout to my custom Ribbon.
Thanks in advance!
This answer is going to provide information on how to change standard settings of any view type control and associate these changes with certain document. This will not work with all documents and will not change the control action for whole Word Application but for one document. Operation could be repeated for few document and almost all Word button.
Important! I'm not using English version of Office application therefore some description will not match exactly to what you have. Tried and tested for Word 2010.
There are following steps to go:
Open new document- one where control should work according to your private expectations.
Go to View >> Macros >> Show list of macros
In the combo-box below middle of the Macro window choose something like Word application commands (or Word macros or similar). As a result you get list of lots of macros names.
You need to guess which of the macro is associated with ribbon control you are going to change. Use common sense and logic to find it. Sometimes two or three seems to match and possibly you will need to make a try.
A) let's try to change behaviour of draft/pending/working view ribbon control. one rounded red below:
B) find macro ViewNormal (but not ViewDraft)
C) select this macro on the list
Change back on the combo-box list to your document (while keeping your chosen macro selected)
Press Create button on the right in the macro window. You will be moved to VBA Editor to the following code:
Sub ViewNormal()
'
' ViewNormal Makro
' Zmienia widok edycji na normalny
'
If ActiveWindow.View.SplitSpecial = wdPaneNone Then
ActiveWindow.ActivePane.View.Type = wdNormalView
Else
ActiveWindow.View.Type = wdNormalView
End If
End Sub
This code is responsible for working of chosen ribbon control.
First, let's check if we can take control of ribbon button- add MsgBox "Control taken" at the end of the code, before End sub. Back to Word App and press button on the ribbon which result should be- setting of chosen view and our message box.
Now you need to change your code accordingly to set your view as you need. Use VBA for that.
Save document as .Docm and all the changes will be applied to the document each time you press chosen ribbon button.
I have a word document on which I have created a checkbox from the Control Toolkit. I have added a text box to the word document that I want visible only when the check box is clicked. I have the code I need to make the text box visible based on the checkmark from another similar piece of code.
What I need is the name of the text box that I put on the document so I can refer to it in my code...the other text box is 27, do I just need to try incrementing numbers until I get lucky or is there some method to the madness where I can look to see what the number is?
Private Sub OtherChk_Click()
If OtherChk = False Then
ActiveDocument.Shapes("Text Box ??").Select
Selection.ShapeRange.Visible = msoTrue
Else
ActiveDocument.Shapes("Text Box ??").Select
Selection.ShapeRange.Visible = msoFalse
End If
End Sub
Since with word you can be talking about Content controls, Form fields or Older style activex controls, each of which have their own quirks, it's tough to answer a question like this directly.
For instance, I created a new word doc (word 2010), clicked the developer tab and dropped down the "control toolbar" button in the ribbon, there's "Legacy forms" and "activex controls" listed,
I clicked the DESIGN MODE button, then chose the Textbox activex control, dropped on on the form, right clicked it and selected "Properties"
that pops up the VERY old school looking properties browser (I don't think that code has been touched in word in years), but, at the top, you have the controlname, defaulted to TextBox1
You can change that name to whatever you want, and then reference the control via that name.
You MAY need to do a for-next through all the controls checking the NAME property (I'm not sure off hand if the indexed collection will index on name or just on the index number).