I have this code in VBA for Word 2010:
Public LastBodyPage
Sub tryit()
Selection.GoTo What:=wdGoToBookmark, Name:="AppendixStart"
LastBodyPage = Selection.Information(wdActiveEndPageNumber)
End Sub
Sub vardel()
MsgBox Variables.item("LastBodyPage").Value
MsgBox LastBodyPage
End Sub
When the vardel procedure is run, the first message box displays "53" and the second time it displays "50".
Why am I getting different values??
You're looking at two different things:
The first message box displays something called Variables.item (your code does not compile, what is Variables.item?).
Anyway, the second message box displays something completely different, it displays LastBodyPage which you presumably set using tryit.
It looks like Variables.Items is part of the document variables that you can set up and assign values to.
LastBodyPage in your tryit procedure looks at the bookmark AppendixStart which I assume you also set up.
So...
AppendixStart is bookmarked on page 50
The code ThisDocument.Variables.Add ("LastBodyPage"), 53 is used to add the document variable somewhere in your code. This persists between opening & closing the document - so may have been added ages ago.
Your code uses ThisDocument.Variables.... rather than just Variables....
With those condition I got the same result as you.
Related
I am easily annoyed by word tracking format changes (even in text that is newly inserted in a revision), so I am using a macro to accept all format changes, once they summed up:
Sub AcceptAllFormatChanges()
Dim xRev As Revision
Dim count As Integer
count = 0
For Each xRev In ActiveDocument.Revisions
If Not xRev Is Nothing Then
If xRev.Type = wdRevisionProperty Then
count = count + 1
xRev.Accept
End If
End If
Next xRev
MsgBox ("Accepted " & count & " format changes")
End Sub
This works fine most of the time, but on some documents, it gives me a run-time error '5852' - Requested object is not available on the "If xRev.Type" line. I am looking for a way to check the object that is yielded by ActiveDocument.Revisions without it throwing a run-time error. Checking for Nothing is not enough. The issue also occures when removing the xRev.Accept or when looping backwards through the revisions.
Update: I tracked down the issue to a Word Bug today. If the macro strikes, I am also unable to iterate through changes in the document using the Next Change button on the review panel. Additionally, if I open the revision panel, the number of revisions jumps back and forth between two numbers. This helped me track down those ghost revisions to a few insertions which included fields (references to other sections). I am able to correct those by deleting/reinserting, so at least now I know how to fix my documents to make the macro work again. Unfortunately, I cannot reproduce the bug in order to actually file a bug report.
The VBA question though remains open: Is there a way for the macro to skip those ghost revisions without throwing a run-time error?
Use the WdRevisionType enumeration instead of cryptic numbers in the code for checking the Type property. Also you may try to check for Nothing before getting the Type property value. The following code works like a charm for me:
Public Sub AcceptSelection()
Dim rev As Revision
For Each rev In Selection.Range.Revisions
rev.Accept
Next rev
End Sub
And the last resort is to replace the for each loop with a reverse for loop.
My end goal was to generate text into a TextBox (let's call it TextBox06) based on the values inserted into a series of Textboxes -- let's name them TextBox01, TextBox02, TextBox03, TextBox04, TextBox05. These TextBoxes are in a Userform (let's call it Userform01).
These TextBoxes can have a lot of different values and combinations (over 50 values each, and depending on which order the values are placed in the textboxes there will be a different output). Moral of the story: code probably works, but gives "procedure too large" error with no real way around it (pretty sure I have shrunk the code as much as possible, but there just aren't any more generic statements that repeat, and most of it must be a bruteforce-style method of inserting most of the combinations individually).
So I went looking on the internet for a way to split the code. I tried using the "call procedure" feature. What I did was:
I created two new Modules (Module01 and Module02) in the same "project".
I split the big code half in Module01, and half in Module02. The Modules' content is something like this:
Sub Module01()
[half the code]
End Sub
I wrote the following lines of code in each sub of the textboxes involved (this is in Userform01).
Private Sub TextBox01_Change()
Application.Run ("Module01")
Application.Run ("Module02")
End Sub
[Then five more copies for Private Sub TextBox02_Change () until Private Sub TextBox06_Change () included]
Assuming this is even the correct way of doing it, I then hit a roadblock. Apparently, copy-pasting the big code in Module01 and Module02 wasn't enough. From what I understood, the program doesn't seem to understand what the TextBox01.Text (and the like) values in the code are. So I tried looking for a solution to THAT, and found several possible codes, none of which seems to have worked so far. The one that I currently have is this:
Sub Module01()
Dim Text01 As String
Set Text01 = TextBox01.Text
[repeat for Text02 to Text06 included]
[half the code]
End Sub
[repeat for Module02 with the other half of the code]
Assuming that I'm even on the right track when it comes to properly using the "call" function, what is the proper way to make this work (i.e. how do I correctly reference the TextBox01.Text content in the Module, so I can then call the Modules in the Userform01) ?
My code in vba for access was working fine, I had procedures that I wrote for different events that all worked. Then when I went to give my combo boxes and text boxes an assigned row source and now nothing works. I get this invalid outside procedure error. So after hours of trouble shooting I ended up deleting the entire form and then rebuilding it and I still get the same error. So now I just working with one event just until I can get things figured out.
Public Sub cb_op1_AfterUpdate()
tb_LbrRate1.Value = DLookup("LaborRate", "tbloperationsType", "[operationsID] = cb_op1.value")
End Sub
This use to work but now it won't?? tb_LbrRate1.value is a text box and cb_op1.value is a combo box.
I have tried this too
Public Sub cb_op1_AfterUpdate()
End Sub
I left everything blank and I still get the error when I change a value in my combo box?? I just don't get it!!!! any help would be appreciated.
Can you do this:
and check what you get?
This error in MS Access is usually because of code flying not between Sub and End Sub.
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 created my own Outlook form to use it as standard surface to enter certain orders instead of the normal message form. The creation, editing and sending works perfectly fine and in the next step I want to insert some code via VBA.
My problem is that I can´t access the objects of my form in the VBA editor. E.g. I want to show a message box when a certain checkbox is checked. According code would be:
Sub example()
If CheckBox1.Value = True Then
MsgBox("Checkbox 1 is checked.")
End If
End Sub
When I run the code I get the error that the object could not be found. The same goes for every other object, like textboxes or labels etc.
I guess the solution is pretty simple, like putting Item. or sth. like that in front of each object. But so far I wasn't able to find the solution.
I´m using Outlook 2010.
I know this is a year too late but you'll want to do something like this example below. It's kinda a work around but you can get whatever value was selected.
Sub ComboBox1_Click()
Set objPage = Item.GetInspector.ModifiedFormPages("Message")
Set Control = objPage.Controls("ComboBox1")
MsgBox "The value in the " & Control.Name & _
"control has changed to " & Control.Value & "."
End Sub
You should be able to get the value, just get a handle on the object you want using the Inspector
The following is an excerpt from here
When you use a custom form, Outlook only supports the Click event for
controls. This is a natural choice for buttons but not optimal for
controls like the combo box. You write the code by inserting it into a
form’s VBScript editor. You need to have the Outlook form open in the
Form Designer and click the View Code button found in the Form group
of the Developer tab.
Sub CheckBox1_Click()
msgbox "Hello World"
End Sub
The code page is fairly minimal with no syntax highlighting. I just tried this now and it does work. Dont forget to Publish your form to pick up the new changes.
I know this is almost 6 years late but, in VB and VBA, simply start with the form name. (And if that doesn't work, just keep going up a parent object and you'll get there.) So, your code becomes:
Sub example()
If MYFORMNAME.CheckBox1.Value = True Then
MsgBox("Checkbox 1 is checked.")
End If
End Sub
Of course, after typing "MYFORMNAME." you'll know if it will work because typomatic will kick in when the system recognizes "MYFORMNAME" after you hit the period.