Word VBA updating LinkFormat.SourceFullName to update a graphic link - vba

When I use the following code
For Each s In ActiveDocument.InlineShapes
If InStr(s.LinkFormat.SourceFullName, searchFor) > 0 Then
s.LinkFormat.SourceFullName = "http://mynewlink.gif"
End If
Next
It executes without error but s.LinkFormat.SourceFullName remains unchanged. It is like it is locked or read only but I can't see anywhere where this can be.

You need to call
s.LinkFormat.Update

Related

Run-time error '5852' when iterating over revisions

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.

VB.Net equivalent for (CustomizationContext) in VBA

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).

QlikView ActiveDocument.NoOfSheets not working

I created a new qlikview doc and in the script I just wanted to know the no of sheets. So I wrote
iNumSheets = ActiveDocument.NoOfSheets;
iVar = 2;
FOR t = 0 to iNumSheets
iVar = 4;
NEXT
I get the following error
Script line error:
FOR t = 0 to iNumSheets
What am I missing? I am a programmers for years and these simple things often drive me nuts in qlikview. Please help.
It appears that you are using the Load Script editor for your code, rather than the Module Editor.
You can access the module editor using Ctrl+M.
You will need to remove the semicolons at the end of your code lines and also enclose your code with Sub and End Sub if you are using VBScript as the lanuage for the code.
Since the for loop counter is starting from 0 you'll have to do iNumSheets - 1 i.e., for t = 0 to iNumSheets - 1.
You can try the below code to loop over the visible sheets which avoids the additional step.
Code
for i = 0 to ActiveDocument.NoOfSheets - 1
your code...
next

Error on ActiveSelection.Tasks

Does anyone know what this means
Set oProjTasks = ActiveSelection.Tasks
I have a macro that generates status reports from MS project and exports them directly into MS Word. It is a slick tool when it works.
When I run it now it throws "runtime error '424': object required" at this point.
How do I fix this?
The code that you are displaying is a set statement, that is setting the object ProjTasks equal to the task that is selected in the message box. The ActiveSelection property returns a selection object that represents the active selection.
It could be that you are experiencing an issue where there are no items selected, in which case it will throw a trappable error code 424. There is a code snippet that you can modify from the MSDN that will work to prevent this type of error from occuring.
Here is the link to the MSDN article... just remember to not use this code verbatim, but modify it to work with your macro.
http://msdn.microsoft.com/en-us/library/aa169315%28v=office.11%29.aspx
You could try just wrapping the error check around the set statement. I've written a small macro on a non-empty project file:
Sub Testing()
On Error GoTo ActiveSelectionErrHandler:
Set oProjTasks = ActiveSelection.Tasks
If oProjTasks Is Nothing Then
MsgBox "No tasks in current project"
End If
ActiveSelectionErrHandler:
Set oProjTasks = ThisProject.Tasks 'or something like that
Resume Next
End Sub
This handles the error but as Steve has already expressed more work is required to integrate the code.
You will have to follow the code to make changes to handle oProjTasks being empty where it is expected to have some values. Otherwise you will see more errors perhaps where the oProjTasks is found to be empty.
Another alternative solution could be to launch the macro after selecting a project as the code you have quoted will work fine if something is selected.

How to check if a Paragraph is in a Table or not in MS-Word macro?

The paragraph object in the Word has a property called Range. Within this Range object has a property called Cells.
For paragraph that are not in a table, this property Paragraph.Range.Cells is set to "". This can be seen in the Watches window in debug mode.
For paragraph that are in a table, the property Paragraph.Range.Cells has other properties in it, for example it has a property called Count.
I am using this property of Paragraph.Range.Cells to determine if the paragraph is in a table or not. However, I cant seem to figure out how to test this.
For example, I cannot simply test like this...
If paragraph.Range.Cells <> Null Then.... or even
If IsNull(paragraph.Range.Cells) Then ...
It throws a Run-time error '5907' There is no table at this location
So, how would I test for this? thanks
You can use the Information property:
If Selection.Information(wdWithInTable) Then
'What ever you'd like to do
End If
Hence you don't need any manual error catching mechanisms.
You can't call the Cells method unless the paragraph is in a table. You need to use a different method to determine whether the range is in a table.
You can use either...
paragraph.Range.Tables.Count > 0
...or...
paragraph.Range.Information(wdWithinTable)
Note that the second one looks more obvious, but is actually slower (only a problem if you're doing this inside a loop).
*Edited (if Err=) changed to (If Err<>)
You can simply allow the error to happen and catch it using OnError statement
Dim ParagraphIsTable As Object
OnError Resume Next 'allows errors to happen but execute next instruction
ParagraphIsTable = paragraph.Range.Cells
If Err <> 5907 Then '(this is to check for a specific error that might have happened)
'No Error occured, this means that ParagraphIsTable variable must contain a value
' Do the rest of your code here
Else
' an Error occured, this means that this is not a table
' do whatever
End If
OnError Goto 0 ' This cancels the effect of OnError Resume Next
' Which means if new errors happen, you will be prompt about them