How can I reuse this code to create multiple buttons at run time? - vba

I want to have multiple simple buttons in my document when it loads:
Add Patient details
Add history
Print note
Save note
I know the VBA I want to attach to each one of those buttons. But how do I use the code here to make these multiple buttons and assign events to them?
`Sub Test()
'Add a command button to a new document
Dim doc As Word.Document
Dim shp As Word.InlineShape
Set doc = ActiveDocument
Set shp = doc.Content.InlineShapes.AddOLEControl(ClassType:="Forms.CommandButton.1")
shp.OLEFormat.Object.Caption = "Click Here"
'Add a procedure for the click event of the inlineshape
'**Note: The click event resides in the This Document module
Dim sCode As String
sCode = "Private Sub " & shp.OLEFormat.Object.Name & "_Click()" & vbCrLf & _
" MsgBox ""You Clicked the CommandButton""" & vbCrLf & _
"End Sub"
doc.VBProject.VBComponents("ThisDocument").CodeModule.AddFromString sCode
End Sub`

Consider using ribbon controls instead. If you deal with open XML documents in Word you can insert the ribbon XML markup inside the document and just have event handlers in VBA. You just need to edit the source Office (Word in your case) file.
You can read more about ribbon XML markup in the following articles:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

Related

Custom property Visio - VBA

First of all, I'm a newbie in VBA, and I'm trying to write some scripts for existing Visio document for automation purposes.
I see that my Visio file has objects with custom properties, and I want to play with those custom properties. (I know that seperate add-in is written for custom properties.)
Here I took a screenshot in my Visio file to show how Custom properties menu look like. This menu is accessed via custom add-in in Visio file.
Based on research, I wrote a simple macro as you see below.
For testing purposes I added shp.Name which works fine but shp.CellsU("Prop.Type").ResultStr("") fails.
I want to access and update custom properties of my shape as you see above.
My script file:
Sub Macro4()
Dim doc As Visio.Document
Dim pge As Visio.Page
Dim shp As Visio.Shape
For Each doc In Application.Documents
'Debug.Print "* " & doc.Name
For Each pge In doc.Pages
'Debug.Print "....s* " & pge.Name
If pge = "134-1" Then
For Each shp In pge.Shapes
Debug.Print "........* " & shp.Name
Debug.Print "........* " & shp.CellsU("Prop.Type").ResultStr("")
Next shp
End If
Next pge
Next doc
End Sub
If you help me with these, I would be appreciated!
At your picture we can see properties Labels (1st row), not their real Names (2nd row) !
Please check property Name!

MS Word filename from bookmarks with VBA

Assuming I have:
a word template including macro: custom_template.dotm;
two bookmarks in this template: 'first_name" and "last_name".
I would like that on "Save" event, in the dialog box, the application proposes to user, instead of "document1", and only if relative bookmarks exist, the filename "Document of first_name second_name.docx".
Can anybody explain me how to achieve this with VBA?
Thanks.
=== UPDATE ===
Now I've this code, working well when I execute it.
I would like it runs automatically when user clicks on "save document".
Sub Demo()
Dim sFlNm As String
With ActiveDocument
sFlNm = "Document of " & .Bookmarks("first_name").Range.Text & " " & .Bookmarks("last_name").Range.Text
End With
With Dialogs(wdDialogFileSaveAs)
.Name = sFlNm
.Show
End With
End Sub
For a macro to run at the client's end, you would have to send a macro-enabled template or document. Many people who are running anti-virus software will get a warning of a possible Word virus. Then the user will have to manually enable the macros. Are they going to bother?
Making it run automatically with a Save command may have unintended consequences. You'll have to check whether the bookmarks have actually been filled, and using the Save command while you're revising the document can save it with a new file name. But you asked, so here's how: rename the macro as FileSave. Then when you choose Ctrl + S or File>Save in Word, the dialog will automatically pop up:
Sub FileSave()
Dim sFlNm As String
With ActiveDocument
sFlNm = "Document of " & .Bookmarks("first_name").Range.Text & " " & .Bookmarks("last_name").Range.Text
End With
With Dialogs(wdDialogFileSaveAs)
.Name = sFlNm
.Show
End With
End Sub
In Word, to create a macro that runs automatically when you choose a Word command, follow these steps:
Choose Developer>Macros.
Change the Macros in dropdown to Word commands.
Choose the command name you want to re-purpose.
Change the Macros in dropdown back to the macro-enabled document or template that you're developing.
Click on the Create button. A new macro is created in the VBE with the correct command name. Fill in the macro with whatever you want the macro to do.

Working with Ribbon controls defined in a VSTO add-in using VBA

I'm trying to create a ribbon for Office Word 365 with two editboxes and a checkbox.
I have a macro I would like to use that input afterwards.
So far I have used the Ribbon Designer in Visual Studio to create an Add-in ribbon.
The Add-in shows in Word and it looks like it's supposed to. I just can't figure out how to get the input from the editboxes and checkbox to vba.
The VBA code I have looks like this:
Sub PasteAndSelectPicture()
Application.ScreenUpdating = False
Dim ils As Word.InlineShape
Dim shp As Word.Shape
Dim lNrIls As Long
Dim lNrShp As Long
Dim rngDoc As Word.Range
Dim rngSel As Word.Range
Set rngDoc = ActiveDocument.Content
Set rngSel = Selection.Range
rngDoc.End = rngSel.End + 1
'Get an InlineShape
lNrIls = rngDoc.InlineShapes.Count
Selection.PasteSpecial Link:=False, DataType:=wdPasteEnhancedMetafile, Placement:=wdInLine, DisplayAsIcon:=False
Debug.Print rngDoc.InlineShapes.Count, lNrIls
Set ils = rngDoc.InlineShapes(lNrIls + 1)
ils.Width = Application.CentimetersToPoints(VAR1)
Set shp = ils.ConvertToShape
shp.IncrementRotation VAR2
shp.ConvertToInlineShape
Application.ScreenUpdating = True
End Sub
I'd like the VAR1 and VAR2 to be inputs from the two editboxes.
By design, it's not possible to access Ribbon controls from a project that does not contain that Ribbon's XML. While the VSTO Ribbon Designer is "nice to have" you cannot use it with VBA code - only with code in the VSTO project that contains the Ribbon.
That means you either need to write VB.NET code in the VSTO project, or you need to create the Ribbon XML differently.
If you want to use VBA then you need the Ribbon XML (there is an "Export" option in VSTO). Using the Custom UI Editor the Ribbon XML can be incorporated into a Word docm or dotm file.
The information in the series of articles Customizing the 2007 Office Fluent Ribbon for Developers describes how to write VBA code that uses controls in the Ribbon XML. There are also lots of articles, discussions and examples on the Internet, plus a really good book on the subject (RibbonX Customizing the Office 2007 RIbbon).

How to add a macro to mutiple excel files using VBA

Is there any way to write a VBA Macro to input another VBA Macro into multiple excel workbooks? If so, how do I start?
Any and all help is greatly appreciated.
you'll need a reference first
Microsoft Visual Basic For Applications Extensibility 5.3
And here you go. Have fun
Public Sub AddNewModule()
Dim proj As VBIDE.VBProject
Dim comp As VBIDE.VBComponent
Set proj = ActiveWorkbook.VBProject
Set comp = proj.VBComponents.Add(vbext_ct_StdModule)
comp.Name = "MyNewModule"
Set codeMod = comp.CodeModule
With codeMod
lineNum = .CountOfLines + 1
.InsertLines lineNum, "Public Sub ANewSub()"
lineNum = lineNum + 1
.InsertLines lineNum, " MsgBox " & """" & "I added a module!" & """"
lineNum = lineNum + 1
.InsertLines lineNum, "End Sub"
End With
End Sub
You can also just use the workbook with the code in it as a reference as well. Then you can call the module remotely.
As #BruceWayne mentioned, there is also sotring it in the personal book.
tl;dr - there's a few options that can get you there.
I recommend storing them in the Personal.xslb file which is accessible across Excel.
See this page or this page for more detail, but generally a quick way to get started is:
Press ALT+F11 to open the VBEditor.
Right click the "VBAProject (PERSONAL.XLSB)" and Add a new module
Add your code in the module.
Now, when you go to View --> Macros, you can choose to see those stored in the Personal.xlsb file:
(I "whited out" my macros for privacy, but they'll be listed by name)
Note: If you do not have a "Personal.xlsb", then you must create it. Simply record a new macro, but choose to store it in "Personal Macro Workbook". Then you should see it in the VBEditor.
I would think the easiest way to have the same code in slightly different Excel files is to have one 'template' and save it several times as several slightly different files. Or, if you want to get fancy, you can create an AddIn to make an Excel Macro available to all workbooks.
Option Explicit
Dim cControl As CommandBarButton
Private Sub Workbook_AddinInstall()
On Error Resume Next 'Just in case
'Delete any existing menu item that may have been left.
Application.CommandBars("Worksheet Menu Bar").Controls("Super Code").Delete
'Add the new menu item and Set a CommandBarButton Variable to it
Set cControl = Application.CommandBars("Worksheet Menu Bar").Controls.Add
'Work with the Variable
With cControl
.Caption = "Super Code"
.Style = msoButtonCaption
.OnAction = "MyGreatMacro"
'Macro stored in a Standard Module
End With
On Error GoTo 0
End Sub
Private Sub Workbook_AddinUninstall()
On Error Resume Next 'In case it has already gone.
Application.CommandBars("Worksheet Menu Bar").Controls("Super Code").Delete
On Error GoTo 0
End Sub
This code will be all you need to add a single menu item (called Super Code) to the end of the existing Worksheet Menu Bar as soon as the Add-in is installed by the user via Tools>Add-ins. When the Super Code menu item is clicked a macro (that is within a standard module of the add-in) is run. As mentioned earlier, the above code MUST be placed in the Private Module of ThisWorkbook for the Add-in.
If you want the Super Code menu item added, say before the Format menu item, you could use some code like this.
Option Explicit
Dim cControl As CommandBarButton
Private Sub Workbook_AddinInstall()
Dim iContIndex As Integer
On Error Resume Next 'Just in case
'Delete any existing menu item that may have been left
Application.CommandBars("Worksheet Menu Bar").Controls("SuperCode").Delete
'Pass the Index of the "Format" menu item number to a Variable.
'Use the FindControl Method to find it's Index number. ID number _
is used in case of Customization
iContIndex = Application.CommandBars.FindControl(ID:=30006).Index
'Add the new menu item and Set a CommandBarButton Variable to it.
'Use the number passed to our Integer Variable to position it.
Set cControl = Application.CommandBars("Worksheet Menu Bar").Controls.Add(Before:=iContIndex)
'Work with the Variable
With cControl
.Caption = "Super Code"
.Style = msoButtonCaption
.OnAction = "MyGreatMacro"
'Macro stored in a Standard Module
End With
On Error GoTo 0
End Sub
There would be no need to change the Workbook_AddinUninstall() code in this case.
We have covered ID numbers while working with CommandBars etc in a P rior Newsletter Issue The link to the Microsoft site that has a BIG list of all the ID numbers for working with CommandBars can be Found Here
The above examples actually have the all the menu item code in the Workbook_AddinInstall and Workbook_AddinUnInstall Not a problem when the code is only adding one menu item. If however, you will be adding more then one and perhaps even Sub menus, you should place it in a Procedure (or 2) inside a standard Module. Then use some code as shown below
Private Sub Workbook_AddinInstall()
Run "AddMenus"
End Sub
Private Sub Workbook_AddinUninstall()
Run "DeleteMenu"
End Sub
Then in the standard module put some code perhaps like this
Sub AddMenus()
Dim cMenu1 As CommandBarControl
Dim cbMainMenuBar As CommandBar
Dim iHelpMenu As Integer
Dim cbcCutomMenu As CommandBarControl
'(1)Delete any existing one.We must use On Error Resume next _
in case it does not exist.
On Error Resume Next
Application.CommandBars("Worksheet Menu Bar").Controls("&NewMenu").Delete
'(2)Set a CommandBar variable to Worksheet menu bar
Set cbMainMenuBar = Application.CommandBars("Worksheet Menu Bar")
'(3)Return the Index number of the Help menu. We can then use _
this to place a custom menu before.
iHelpMenu = cbMainMenuBar.Controls("Help").Index
'(4)Add a Control to the "Worksheet Menu Bar" before Help
'Set a CommandBarControl variable to it
Set cbcCutomMenu = cbMainMenuBar.Controls.Add(Type:=msoControlPopup, Before:=iHelpMenu)
'(5)Give the control a caption
cbcCutomMenu.Caption = "&New Menu"
'(6)Working with our new Control, add a sub control and _
give it a Caption and tell it which macro to run (OnAction).
With cbcCutomMenu.Controls.Add(Type:=msoControlButton)
.Caption = "Menu 1"
.OnAction = "MyMacro1"
End With
'(6a)Add another sub control give it a Caption _
and tell it which macro to run (OnAction)
With cbcCutomMenu.Controls.Add(Type:=msoControlButton)
.Caption = "Menu 2"
.OnAction = "MyMacro2"
End With
'Repeat step "6a" for each menu item you want to add.
'Add another menu that will lead off to another menu
'Set a CommandBarControl variable to it
Set cbcCutomMenu = cbcCutomMenu.Controls.Add(Type:=msoControlPopup)
' Give the control a caption
cbcCutomMenu.Caption = "Next Menu"
'Add a control to the sub menu, just created above
With cbcCutomMenu.Controls.Add(Type:=msoControlButton)
.Caption = "&Charts"
.FaceId = 420
.OnAction = "MyMacro2"
End With
On Error GoTo 0
End Sub
Sub DeleteMenu()
On Error Resume Next
Application.CommandBars("Worksheet Menu Bar").Controls("&NewMenu").Delete
On Error GoTo 0
End Sub
You can find all details here.
http://www.ozgrid.com/VBA/excel-add-in-create.htm

Adding Macro Code to Word Documents using VB.Net

Ok so let me explain in detail.
Suppose there is a word file called "Word.doc"
What I want to do is basically use VB.NET for doing the following things :
Open the word document
Add a macro code
For e.g
Add the following macro code to the Word Document
Sub AutoOpen()
Msgbox
End Sub
And then save this document.
Just remember that I want to insert macro code to a word document not retreive an already present macro code from a document
Here is a simple VBA macro that shows how to use the Word object model to add a macro to a document (VB.NET code will be almost identical).
Sub NewDocWithCode()
Dim doc As Document
Set doc = Application.Documents.Add
doc.VBProject.VBComponents("ThisDocument").CodeModule.AddFromString _
"Sub AutoOpen()" & vbLf & _
" MsgBox ""It works""" & vbLf & _
"End Sub"
End Sub
Note that running this code requires that access to the VBA project object model is trusted (this needs to be enabled in the trust center in the the Word options).
Working with objects in the VBA Editor through the object model requires a reference to the Microsoft Office VBA Extensibility 5.3 object model which you can find in the COM tab of Project/Add References in Visual Studio.
I like to add an Imports statement to the top of the code so that I don't have to always write out the full namespace qualification:
Imports VBE = Microsoft.Vbe.Interop
An AutoOpen macro needs to be a "public" Sub in a normal code module. Assuming you want to add a new code module to the document, use the VBComponents.Add method and specify the enumeration type vbext_ct_StdModule.
By default, the VBE will name the new module "Module#" - an incrementing number. If you ever need to programmatically address this module again (to see if it exists, for example) it would probably be better to assign a name to it.
Code as a string is added using the AddFromString method.
If you're adding code to a document the possibility exists that the document is of type docx, meaning it cannot contain macro code. A document must have the extension docm in order to contain macro code. So you may need to use the SaveAs method on the document to change the file type and the name!
Private Sub InsVbaCode_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles InsVbaCode.Click
'Helper method to get current Word instance or, if none, start one
GetWordProcess()
Dim doc As Word.Document = WordApp.ActiveDocument
Dim vbModule As VBE.VBComponent = doc.VBProject.VBComponents.Add(VBE.vbext_ComponentType.vbext_ct_StdModule)
vbModule.Name = "basAddedCode"
vbModule.CodeModule.AddFromString( _
"Sub AutoOpen()" & vbLf & _
" MsgBox ""Document "" & ActiveDocument.FullName & "" has been opened successfully!""" & vbLf & _
"End Sub")
'doc.Save() or doc.SaveAs to change file type and/or name
End Sub