Word VBA: Sharing variables between documents - vba

I feel like this should be obvious, I'm just not finding the answer anywhere.
I have a Word document with several Public variables declared and defined in a variety of procedures. One procedure opens another Word document, which has a form that loads on open. For the life of me I cannot get that form in the second document to use values from the original document's variables. Am I misunderstanding the nature of Public variables? Everything I've found seems to indicate that those values should be visible to the newly opened document.
So to open the second document, I'm using the code below (some of it is declared and set elsewhere, but I think this is the relevant stuff:
Public iMarker as boolean
Sub OpenDoc()
If check_ExA.Value = True Then 'a checkbox on a userform
docName = docsPath & "/" & "seconddocumentpath.docm"
iMarker = True
formAddDocs.Hide
Set addDoc = Documents.Open(docName)
End Sub
from there, the new document has a form that shows on Open, and in the initialization, I want it to be able to see if the iMarker variable is true, among some other strings, etc.
Private Sub UserForm_Initialize()
If iMarker = True Then
'do some other stuff
End If
End Sub
I tried changing that Initialize sub to public and that did nothing. It won't see that iMarker is true when the second document opens. Any suggestions?

To make a public variable of doc01 ("source doc") available to doc02 ("target doc") document, go like follows:
open the "source doc"
open the "target doc"
click Tools-> References
from Available References listbox of the References dialog box click the "Project" of the "source doc"
You can recognize it from the path appearing near the dialog box bottom
Otherwise
close Reference dialog box
go to "source doc" and rename its project (Tools->project properties, edit "project name" textbox and click "OK") with a meaningful name (say "MainProject")
go back to "target doc" project
open References dialog box and now from Available References listbox click the "MainProject" reference
Save and close target doc

Related

CommandBars("Text").Controls not deleted when exiting the document - VBA word add-in

I'm trying to create a add in for MS Word with VBA.
It has a "AutoExec" procedure that creates a new item in the CommandBar("Text") collection (right click menu) and a "AutoExit" that deletes this created item.
As an example, I tried the code below that create an item "How Many Pages?", which executes a macro displaying the number of pages in the active document.
This is the AutoExec Code:
Public Sub AutoExec()
Dim objcommandbutton As CommandBarButton
Call MsgBox("AutoExec")
Set objcommandbutton = Application.CommandBars("Text").Controls.Add _
(Type:=msoControlButton, Before:=1)
objcommandbutton.Caption = "How Many Pages?"
objcommandbutton.OnAction = "HowManyPages"
End Sub
This is the AutoExit Code:
Public Sub AutoExit()
Dim objcommandbutton As CommandBarControl
Call MsgBox("AutoExit")
For Each objcommandbutton In Application.CommandBars("Text").Controls
If objcommandbutton.Caption = "How Many Pages?" Then
objcommandbutton.Delete
End If
Next objcommandbutton
End Sub
This is the Main Macro Code:
Public Sub HowManyPages()
If Documents.Count > 0 Then
Call MsgBox(ActiveDocument.BuiltInDocumentProperties("Number of Pages"))
Else
Call MsgBox("No document is currently active.")
End If
End Sub
When exiting the document, the Button previously added in CommandBars("Text") collection is not deleted. I see this when I open a new blank Word document and the button remains in the right click menu.
I know that the routine is performed correctly because there is a MsgBox instruction to verify it.
This only happen with the AutoExit subroutine of a add-in, that is, loaded as a add-in: running the code in a macro with vba module works fine.
Any help?
When working with the CommandBars object model in Word it's necessary to always specify the Application.CustomizationContext.
Word can save keyboard layouts and CommandBar customizations in various places: the Normal.dotm template, the current template or the current document. The default when you create a CommandBar addition may not be the3 same as the default when trying to delete something.
Since this is an add-in, I assume you want the change for the entire Word environment (any open document). In that case, use the context NormalTemplate. Use this before any calls to CommandBar:
Application.CustomizationContext = NormalTemplate
Note: for saving a customization in the current document: = ActiveDocument; for saving in the template attached to the current document: = ActiveDocument.AttachedTemplate.
I solved my problem with a workaround:
I was trying to "add" a template (.dotm) as a add-in (in the "Templates and Add-ins" window) to use my VBA project in a new document. That's why I was using the AutoExec() and AutoExit() procedures.
But only now I figure out that just "attaching" the .dotm template to the active document (in the same "Templates and Add-ins" window, as show in the figure below) makes the functions Private Sub Document_Open() and Private Sub Document_Close() to run normally. Which solves my problem.
Even so, I think there is a certain "issue" with the AutoExit() procedure when trying to change the CommandBars itens. But that's ok for now.
enter image description here

How to cycle between tabs on a tab?

My Access form "frmLoad" has five tabbed pages. One of those pages has a subform "frmClients" with a few dozen tabbed pages.
I need to cycle through each tabbed page on frmClients, Debug.Print the tab name, modify certain labels, and go on to the next.
(I don't have to access any other tabs on frmLoad; I only mention it in case we have to fully qualify everything.)
The documentation I've been reading is confusing. I'm not sure of the difference between a Page and a Tab, for one thing.
You can reference the Tab Pages from the frmClients' Controls collection.
Run this in a standard Module and it will Debug.Print the needed references.
Sub PrintLabelsReferences()
Dim ctrl As Object, pageCtrl As Object
For Each ctrl In Forms("frmLoad").Controls("frmClients").Controls
If TypeName(ctrl) = "Page" Then
For Each pageCtrl In ctrl.Controls
If TypeName(pageCtrl) = "Label" Then
Debug.Print "Me.Controls(""frmClients"").Controls("""; pageCtrl.Name; """).Caption ="""; pageCtrl.Caption; """"
Debug.Print "Forms(""frmLoad"").Controls(""frmClients"").Controls("""; pageCtrl.Name; """).Caption ="""; pageCtrl.Caption; """"
End If
Next
End If
Next
End Sub
Uses the Forms() reference if you want to modify the Label.Caption from outside of the form or use Me if you want to reference the Label.Caption from within the Form's code module.

How to add handwritten signature using Excel's Ink Tools?

I want to add a handwritten digital signature to some of my company's forms.
The goal is to, select a document, add a signature (through the use of a drawing pad, which can be done with Excel's Ink Tools) and store the file in the server as PDF. This would cut out the necessity of printing and then scanning the form back in to obtain a signature.
I'm using Excel for the main interface for file manipulation and search. I've not found any references/libraries for the use of Excel - Ink Tools through VBA.
How do I start Ink Tools Objects in VBA? Would I have to use a different software to get the signature?
Update:
After #Macro Man pointed me in the right direction I found some material that helped get the eSignature up and running.
I've found some material on MSDN Digital Ink Signatures - Concepts and Technologies and InkPicture Class that talk about the Ink collection on VB.net and C# through a PictureBox/Userform , this coupled with the InkEdit Control in another Stackoverflow response in which I realised that VBAs tool box had a InkPicture Control additional control that could be utilized to collect the handwritten eSignature through User form.
Please find below step by step:
In VBAs toolbox on additional control under Tools > Additional Controls there is the InkPicture Control which allows you to create a signature Userform.
Once Added InkPicture can be used as any other control on the toolbox.
Then its a case of initialising the UserForm for the Signature request. I'm using a drawing pad, but other hardware should work as well.
And storing or utilising the resultant image at need, in my case saving a temp version in the server to then resize and add to a Word document.
Edit:
After answering a similar question in here, on how to use Userform InkPicture to input image signature into a worksheet/specific cell, I thought I'd edit this answer for those interested.
The below code will allow you to, open the userform so the user can sign the ink field, save the image temperately, add the InkPicture to your worksheet and kill the temp image.
Set up your UserForm (mine is set up like this, with a couple extra options) the UserForm is named Signature_pad, the essential option you need is Private Sub Use_Click().
This is the code inside the Userform:
Private Sub Use_Click()
'dim object type and byte array to save from binary
Dim objInk As MSINKAUTLib.InkPicture
Dim bytArr() As Byte
Dim File1 As String
'get temp file path as $user\Temp\[file name]
FilePath = Environ$("temp") & "\" & "Signature.png"
' set objInk as image/strokes of InkPicture control form object
Set objInk = Me.SignPicture
'if object is not empty
If objInk.Ink.Strokes.Count > 0 Then
'get bytes from object save
bytArr = objInk.Ink.Save(2)
'create file for output
Open FilePath For Binary As #1
'output/write bytArr into #1/created (empty)file
Put #1, , bytArr
Close #1
End If
'set public File as file path to be used later on main sub
Signature.File = FilePath
Unload Me
End Sub
Private Sub Cancel_Click()
End
End Sub
Private Sub ClearPad_Click()
'delete strokes/lines of signature
Me.SignPicture.Ink.DeleteStrokes
'refresh form
Me.Repaint
End Sub
Below is the Main sub (Module called Signature) to call the userform and handle the signature, you can call this Sub with a button or form another Sub.
'public temp file path
Public File
Sub collect_signature()
'Dim and call userform
Dim myUserForm As Signature_pad
Set myUserForm = New Signature_pad
myUserForm.Show
Set myUserForm = Nothing
'insert image/signature from temp file into application active sheet
Set SignatureImage = Application.ActiveSheet.Shapes.AddPicture(File, False, True, 1, 1, 1, 1)
'scale image/signature
SignatureImage.ScaleHeight 1, True
SignatureImage.ScaleWidth 1, True
'image/signature position
SignatureImage.Top = Range("A1").Top
SignatureImage.Left = Range("A1").Left
'delete temp file
Kill File
End Sub
Be sure to rename either the Userform Name and Buttons Name Or the code to match the names of you buttons.
Is it the InkEdit Control you're after?
This is one of the standard libraries that you can find in Tools->References

customize shorcut (right-click) menu powerpoint

I want to make appear a new element on the shortcut menu, known also as right-click menu. I want this element to execute a macro that I made. I check on the web but I could find a solution that really work. I put here which one I tried:
Public Sub customizeRightClick()
Dim pic As IPictureDisp
Set pic = LoadPicture("C:\path\pic.jpg")
For Each oCmdBar In Application.CommandBars
If oCmdBar.Type = msoBarTypePopup Then
If oCmdBar.Name = "Shapes" Then
Set cmdButton = oCmdBar.Controls.Add(Type:=msoControlButton)
With cmdButton
.Caption = "Edit Element"
.Tag = "Edit"
.Picture = pic 'Object of type IPictureDisp
.OnAction = "editMag"
End With
End If
End If
Next
End Sub
I check in the Watches and it add the control but when I use right-click on a shape the options doesn't appear. Maybe I am not putting where it have to be but I cannot find anywhere an explanation about where is the correct place to set the new element.
David's correct re 2007, but it seems they've added the ability to customize context menus back in PPT 2010:
http://social.msdn.microsoft.com/forums/office/en-US/c1eb22ba-6ca8-4c21-8100-62185355aa53/customize-rightclick-context-menu-in-powerpoint-2010
OK I have confirmed that there is:
Limited support for shortcut menu customizations in PPT 2007+
specifically. ....You cannot add any item to the shapes shortcut menu
(unless it is an activex control) in PPT 2007+.
http://answers.microsoft.com/en-us/office/forum/office_2007-customize/customizing-right-click-menu/76aff9b3-9253-40cf-bd21-e1f832144ad8
You may be able to do this with Ribbon/XML interface, but again it may be subject to the annoying limitation that they put on certain context menus. It might simply not be possible to do what you want to do in this version of PowerPoint.
http://msdn.microsoft.com/en-us/library/gg469862.aspx#odc_xl_ta_CustomExcelContextMenus_AddDynamicMenu

VBA IE automation, To do events like displaying message,etc in excel when a link in webpage is clicked

My requirement is i need to have a VBA code in excel which runs to do some action in excel when a link in webpage is clicked.For example when i click a link "login" in webpage my VBA code should press printscreen button in keyboard(like we use sendkeys).
I have been searching for this solution since two weeks over google but failed to get one.This is urgent project requirement, please save my day,thank you very much in advance.
Here's an edited version of an answer I gave to a similar question (http://stackoverflow.com/questions/12877872/possible-to-intercept-onchange-event/12927960#12927960).
Project references set for "Microsoft HTML object library" and "Microsoft internet controls"
In a class module "clsEvents":
Option Explicit
Public WithEvents href As MSHTML.HTMLAnchorElement
'Note that having defined "href" as "WithEvents", if you choose "href"
' from the left-hand dropdown at the top of the class code module
' then the right-hand dropdown will populate with events you can select
' from to create an event-handling procedure in the class
Private Function href_onclick() As Boolean
Debug.Print "link clicked"
href_onclick = False 'cancels the navigation
End Function
In a regular module:
Option Explicit
Dim evt As clsEvents
Sub Setup()
Dim IE As New InternetExplorer
Dim el2 As Object
Set evt = New clsEvents
IE.Visible = True
IE.navigate "http://www.csee.wvu.edu/~riggs/html/select_example.html"
Do While IE.Busy
Loop
Set el2 = IE.document.getElementsByTagName("a")(1)
If Not el2 Is Nothing Then
Debug.Print "setting event capture on link:" & el2.innerText
Set evt.href = el2
End If
End Sub
If you run the Setup sub and then click the "Javascript" link on the page in IE you should see output in the Immediate window of the VB editor.
Hope that helps get you started.
There is nothing native you can do inside Internet Explorer to enable this functionality.
You would need to write an ActiveX control (using C#, C++, VB6, etc.), which would perform the Excel automation.
A few useful links:
How to automate Excel from VB6
How to write an updatable ActiveX control in VB6