Auto-updatable links - vba

Is there a way to apply "auto-updatable" style for hyperlink?
I believe, this question is not trivial.
When you normally click on hyperlink, it will change it's color to violet. Next, if you save, close, and then reopen the document, the link will be updated back to blue. This is default behaviour of Word, and there is no need to use any macros for it.
I'm trying to replicate this behaviour with VBA. Here is the code:
Sub Test1()
Selection.Range.Hyperlinks(1).Range.Fields(1).Result.Style = Word.WdBuiltinStyle.wdStyleHyperlinkFollowed
End Sub
To make it work, simply put caret into the link, run macro, and see the results:
This works fine, except such visited links will not be auto-updated after you save, close, and then reopen the document. See the difference in the picture below. The link "Google" was opened normally, using the mouse Ctrl-click; the link "StackOverflow" was opened using the macro:
As I already said, I want to make my VBA-opened links (StackOverflow) auto-updatable as well (as Google).
Yes, I understand, there is a workaround - simply create another macro, which will be started every time the document opened and change all violet hyperlinks back to blue. However, this is just workaround, and I don't like it. Using it, we use conversion from "permanent violet" to "permanent blue", instead of using "temporary violet" (that's mean, auto-updatable without any additional efforts).
Hope everything is clear. Thanks in advance.
Update (was added after several answers were already posted).
Yes, I understand, this will work:
Sub Test1()
On Error Resume Next 'To avoid an error in case if the link isn't reachable
Selection.Hyperlinks(1).Follow
End Sub
But I want just simulate following, without really opening the link in the browser. That's why, I can't use Selection.Hyperlinks(1).Follow.

you need to remove the line, the link will change once followed and change back once the doc is reopened.
Selection.Range.Hyperlinks(1).Range.Fields(1).Result.Style = Word.WdBuiltinStyle.wdStyleHyperlinkFollowed

this does it for me
Sub resetHyperlinks()
Dim hLink As Hyperlink
For Each hLink In ActiveDocument.Hyperlinks
hLink.Address = hLink.Address ' this works
' hLink.ScreenTip = hLink.ScreenTip ' this works also
Next hLink
End Sub

You don't need to change the style with code to make the link purple. Just use the Follow method. This will click the link and turn it purple and then it will be reset to blue upon opening the document again.
Sub Test1()
Selection.Range.Hyperlinks(1).Follow
End Sub

You can reset link styles with VBA code that runs at startup, i.e. is a part of Document_Open() routine in ThisDocument VBA module.
The Hyperlink class doesn't have any .Visited property or anything relevant (i.e. you cannot even see if it was visited), so there's no other way beside .Follow() that also opens the link as it should.
You're basically trying to falsify the information that the document provides about its state: make a link appear visited when it actually wasn't.
The fact that the class doesn't even provide a property means that Word's designers do not consider the visited status a part of the editor's functionality (i.e. it effectively doesn't exist as far as the program's job is concerned).
This evidence suggests that Word doesn't, and is not designed to, have any specialized facility to switch link status other than .Follow(). Which means, any way that you find that happens to have the desired effect in bound to be what you're calling a "workaround".

The "temporary" color of a followed hyperlink is an embedded (and not directly accessible) feature of the built-in Hyperlink character style. It is not exposed through the normal UI's Style tools, nor through the object model.
You can readily compare all formatting between two selections using the Reveal Formatting pane (Shift+F1) in the document window in Word.
If you compare a normally followed hyperlink with a hyperlink affected by your snippet, you'll see that the followed hyperlink still has the Hyperlink style, while your simulated follow has changed the style of the second hyperlink.
If you compare a never-followed hyperlink and a normally followed hyperink, Word identifies their formatting as exactly the same. Word does not acknowledge that any aspect of formatting (style, font color, etc.) has changed.
It seems likely that the Word.WdBuiltinStyle.wdStyleHyperlinkFollowed you are using exists explicitly to address this gap (which is somewhat disappointing).
I recommend using your existing approach, and then reverting the style in a procedure triggered by the Before Save and Before Close events of the document. Using those events will prevent the followed style from saving at all, and so avoid issues caused by someone opening the document without enabling macros.

Option Explicit
Sub test()
Dim HL As Hyperlink
For Each HL In Sheet1.Hyperlinks
HL.Range.Style.Font.Color = vbBlue
Next
End Sub
Can't you simply make it any colour you want without invoking it. As others have stated above whatever you you I think will be a work around as it's not an intended function.

Related

How to create a macro to jump to the end of a document in Libre Office Basic

Each time I open my Libre Office document to add updates, I have to press CTRL+END to jump to the bottom of the document. I thought of adding a button to jump-to-the-bottom, but the Basic it uses is not VBA, so I'm in a pickle. Can anyone give me a sub?
As an after-thought; can I add an instruction to the document-startup?? to cursor-jump-to-the-bottom of the file? Please forgive my pants naming conventions, I'm still green!
I tried the offline help to no avail. Next I tried Google but could not find an exact sub to match. I then subscribed to the TheDocumentFoundation and was presented with an SO-like Q&A forum. The discobot did not help!
I also tried recording a macro which does work ok. The sub code is:
sub Main
rem define variables
dim document as object
dim dispatcher as object
rem get access to the document
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
dispatcher.executeDispatch(document, ".uno:GoToEndOfDoc", "", 0, Array())
end sub
I cannot however add the commands to the document.init or startup.
In fact, the macro for moving the cursor to the end of the document is a little easier to write. Each document has a controller. The text document controller has a "view cursor". You can control this cursor using its methods, in this case you need the .gotoEnd() method.
So the code can be like this: "if this document is a text document, then get its controller, take the cursor from the controller, make the cursor jump to the end of the text"
Sub jumpToEnd(Optional oEvent As Variant)
If ThisComponent.SupportsService("com.sun.star.text.TextDocument") Then
ThisComponent.getCurrentController().getViewCursor().gotoEnd(False)
EndIf
End Sub
The best place for this macro is some module in the Standard library under "My Macros" - this library will be loaded immediately after starting the office and macros will be available for execution at any time. (If you want to run this macro only for one document, then you can place it in the Standard library of this document)
To run the macro automatically, use the Tools - Customize - Events tab
This is where you specify whether the macro should be executed when you open one specific document or when you open any document.
Now that you know how to do this, you will probably agree that pressing Ctrl+End is much easier.

Using VBA to allow a checkbox to hide/show content in Microsoft Word

I've gone through a number of tutorials and instructional videos trying to achieve my intended result of simply allowing a checkbox in my form to hide content when selected, or re-show it when being de-selected, but nothing seems to be working.
Currently, I've created a bookmark for the content I want hidden, and try to call his this in VBA with the following statement - which a number of resources indicated as the solution:
Private Sub CheckBox1_Click()
ActiveDocument.Bookmarks("bookmark").Range.Font.Hidden = CheckBox1.Value
End Sub
But despite doing this, selecting the checkbox has no affect on the content.
Is there something additional I'm missing (I'm using Microsoft Word 2013).
Your code worked fine when I tested it, but I ran into a few issues since I've never messed with userforms/checkboxs in Word VBA and I suspect you may have the same.
For instance, the first thing I did was create Insert --> Module. This is incorrect. What you want to do is Insert --> Userform then drag a checkbox over from the ToolBox
https://smallbusiness.chron.com/use-check-boxes-word-54673.html
Then double click the checkbox to bring up the "module" it would run, notice there is no module in the side pane! Edit the module, then go back to the userform and press F5. You should be presented with a checkbox that will hide/unhide your text.
Here is my module:
Public Sub CheckBox1_Click()
ActiveDocument.Bookmarks("bookmark").Range.Font.Hidden = CheckBox1.Value
End Sub
Here is an image:
Note: I didn't test how to insert the checkbox into the word doc, I'll leave you some of the learning!
Update:
This sub will make the CheckBox appear when run, but I'm not sure the logic you would use to call it, perhaps an event like opening of document?
Sub Loadform()
Load UserForm1
UserForm1.Show
End Sub
This could be called via a keyboard shortcut or event, but this will cause a "pop-up window". If you want an inform checkbox you may need to look into using this Legacy Form/Checkbox. I was following the URL from above but I think it's dated.
Update:
You could also add this easily to a toolbar, but that isn't likely what you want. I found the best way is to use a "field code" see --> https://word.tips.net/T001571_Assigning_a_Macro_to_a_Button_in_Your_Text.html
I was able to get this to work by pressing CTRL + F9 then typing { MacroButton Loadform ClickMe} then clicking this text. This may be the best bet as using an image seems not to be a great idea.. (https://answers.microsoft.com/en-us/msoffice/forum/all/using-graphic-with-macrobutton/a9c1ef3b-cf1f-48ba-92a8-c44bffcdc131) & (http://www.addbalance.com/usersguide/parts/macrobutton_fields.htm#Different_behavior)
Gif Example:

MS Office - ActiveX Buttons switching places

There are several instances of this problem, but this one is predominant. This is in relation to updates (our most notable problem child being KB2726958). We have a Leave Spreadsheet that looks like this:
Leave Spreadsheet example
By pressing the grey Leave button, you end up here:
Leave Word doc
All the programming for these is written in VBA (i've never worked with VBA before, I can understand it to a degree).
Now, the issue is that using the ActiveX button in the 'Leave Spreadsheet example' causes the 2 buttons 'Send by Email' and 'Save' to switch functions; Send by email attempts to save and save opens up Outlook and creates the email message.
Both functions have completely retained functionality, just on the wrong buttons.
The thing I find weird is that a hyperlink to the very same file works; the buttons aren't switched and have full functionality. The only hint that I have towards resolution is that when using a hyperlink, it's directly opening the file. When using the ActiveX button, it seems to be creating a new file based off the file it's linking to. For example, the hyperlink directly opens C:\Report.dotm but the ActiveX button opens Document1.doc with a template based on Report.dotm.
I'm considering that maybe the activeX button is opening up Word with an incorrect extension? But i'm not sure how to figure this out (code below shows that the linked file on the activeX control is a .dotm).
What further throws a spanner into the mix is that it only affects some computers... Considering on-site we all use the same type of PC with the same image... :(
My question is, does anyone know why they may be swapping? They're located on the same network drive albeit different directories. They require the same permissions to access. The code for the buttons is as follows:
Excel Button:
Private Sub CommandButton1_Click()
' This button links the excel spreadsheet to the word doc
Dim wrdApp As Object
Dim wrdDoc As Object
Dim i As Integer
Set wrdApp = CreateObject("Word.Application")
wrdApp.Visible = True
Set wrdDoc = wrdApp.Documents.Add("\\networkdrive\directories\Request for Leave.dotm")
End Sub
Word buttons 1 and 2:
Private Sub cmdSend_Click()
' This is the code for the button 'Send by Email'
MsgBox "Send the following email to your Team Leader/Line Manager", vbInformation
SendDocumentAsAttachment "", "IPL Request for Leave"
End Sub
Private Sub cmdSave_Click()
' This is the code for 'Save'
modSend.SaveLeaveForm
End Sub
Please Note: The comments above are not in the code in VBA, i've written them in myself in this question to provide clarity.
Troubleshooting that i've done:
Removing all .exd files
Running the MS Hotfix (removes all .exd files in a GUI)
The next step would be to try running all 6 patches related to fixing ActiveX controls with the particular patches we've done to see if that fixes the problem. The reason I haven't done this yet is because of ITIL (Change management) although I may try testing this later today.
What is the outcome i'm after?
Ideally, I want to understand what is causing these buttons to, from what it looks like, swap their functions. I have different scenarios of button swaps, some of which are remedied by removing the .exd files, and some that aren't.
By understanding what is happening, I hope that I can apply the knowledge to the other scenarios (same problem, different coding).
Then, I'll be able to document my findings so that when we perform the next round of patching that is known to break ActiveX controls, my organization will know how to deal with it.
So the patch mentioned below has fixed this issue. There's still some other issues that I need to test this patch against, but I definitely should have started there. Lesson learnt.
From my work email:
I’ve just tried using the patch related to the ActiveX controls breaking, KB2920754. I’ve used it on two PC’s here in the training room; both had different issues:
- The first one had buttons that had switched around (save attempted to email, email attempted to save)
- The second one couldn’t use the buttons at all.
This patch cured both w/o requiring a restart or logging out and back in. I didn’t remove any .exd files, either.
It does state, however:
“Important For this fix to be fully effective, you also have to apply the other patches for Office 2013 that are listed in the "Resolution" section of the following Microsoft Knowledge Base article”
There are 6 in total.
Patches:
1. KB2920754 – (the one I’ve used successfully)
2. KB2956145
3. KB2956163
4. KB2965206
5. KB2956176
6. KB2956155

Excel: Fixed Button Position

Needing some help attaching an Excel/VBA button on an Excel sheet. I need it to stay in the same position on the screen regardless of how I scroll or zoom. Preferably, I need this on the bottom left or right of the screen.
I have tried adding a button. Then, I right clicked on the button. Clicked on Format Controls -> Properties -> selected Don't Move or Size With Cells. Am I missing something that's making this not work?
Thanks!
I know this post is old, but here's to anyone it could be useful. The VisibleRange property of ActiveWindow can solve this problem. Use something like this:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
With ActiveSheet.OLEObjects("MY_BUTTON'S_NAME")
.Top = ActiveWindow.VisibleRange.Top + ActiveWindow.VisibleRange.Height - 5
.Left = ActiveWindow.VisibleRange.Left + ActiveWindow.VisibleRange.Width - .Width - 5
End With
End Sub
Here is the idea that I put across the comment earlier today :) Typically we can get a Floating User Form by setting the Modal property of the form to be 0 which is indeed a Modeless state.
Basic Points to consider:
Look & Feel of the form to make it look like a Button (Not show title bar/Not Resizable/
Hidden Close Button etc)
Setting the position of the Button
Which Event should trigger the form-button (WorkBook Open)
What would you do with Form Initialize Event
Whcih Events should keep it stick to the same position alive
Further Points to consider:
You might only want to keep this button vissible for the workbook you are working, and if you open another instance of a workbook, do you still want to keep the button
If you minimize the Excel Window instance, how do you plan to manage the state of the button and keep it visible
Post about keep displaying a form even the workbook is minimized.
One other great reference I happend to see, (little bit technical) but worth the shot - at least to get to know the certain properties/methods that you could make use: Extending VBA User Form Control.
The article include the following info, and please note the last line as well :)
They give you access to capabilities that are not available from VBA or from the objects (UserForms, Workbooks, etc.,) that make up a VBA Project. When you call an API, you are bypassing VBA and calling directly upon Windows. This means that you do not get the safety mechanisms such as type checking that VBA normally provides. If you pass an invalid value to an API or (a very common mistake) use a ByRef parameter instead of a ByVal parameter, you will most likely completely and immediately crash Excel and you will lose all your unsaved work. I recommend that until you are confident that your API calls are solid you save your work before calling an API function.
Add new Row on the beginning of your WorkSheet and set your button on it, then:
Freeze Top Row
Right click → properties → placement → change to 3.

VBA MS Word: Trigger event when text changes

I'd like to trigger an event as soon as the text in the (active) document changes. As I understand it, WindowSelectionChange is most suitable for this. Is this indeed the case? If so, how exactly can I use it? I've read the documentation here but I can't get my head around it, especially about which code goes in which file. Right now, I've all my code in the default module file in the "Modules" folder in the project.
FYI: I'm not really typing in the document, instead I only do Ctr+A, to select the existing content, and Ctrl+V, to replace it by new content. At that moment, I want the event to be triggered.
Although I wasn't able to find a solution for my specific question, I did find something that gave me results I wanted:
Sub EditPaste()
Selection.Paste
'Other code
End Sub
It's not quite the same as a 'text changed' event, but for me it is, because I only change the text by pasting new text. Because I named the Sub the same way as the actual paste event, this Sub is called whenever I paste something. Then, it's only a matter of adding the actual paste operation and then add your own code.
In short: instead of creating an event for an operation it's much easier to redefine the operation.