PDA

View Full Version : Hyperlink in docs plus Internet Explorer Save as



JohnnyBravo
10-04-2006, 09:16 PM
Someone sent several word documents to me which contain hyperlinks. Each document has tons of hyperlinks so it's rather time consuming to click on each hyperlink. We're probably talking about 80-100 links in total. So I recorded a simple macro that works if you assume the doc only has 7 hyperlinks. Each link opens in Internet Explorer.


Sub FollowHyperlink()
'
' FollowHyperlink Macro
' Macro recorded 10/4/2006 by John C
'
With ActiveDocument

Selection.Rows.Delete
Selection.Delete Unit:=wdCharacter, Count:=1
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.Range.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
Selection.GoTo What:=wdGoToGraphic, Which:=wdGoToNext, Count:=1, Name:=""
Selection.GoTo What:=wdGoToGraphic, Which:=wdGoToNext, Count:=1, Name:=""
Selection.Range.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
Selection.GoTo What:=wdGoToGraphic, Which:=wdGoToNext, Count:=1, Name:=""
Selection.Range.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
'Selection.Fields(1).DoClick
Selection.GoTo What:=wdGoToGraphic, Which:=wdGoToNext, Count:=1, Name:=""
Selection.Range.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
'Selection.Fields(1).DoClick
Selection.GoTo What:=wdGoToGraphic, Which:=wdGoToNext, Count:=1, Name:=""
Selection.Range.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
'Selection.Fields(1).DoClick
Selection.GoTo What:=wdGoToGraphic, Which:=wdGoToNext, Count:=1, Name:=""
Selection.Range.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True
'Selection.Fields(1).DoClick
Selection.GoTo What:=wdGoToGraphic, Which:=wdGoToNext, Count:=1, Name:=""
Selection.Range.Hyperlinks(1).Follow NewWindow:=False, AddHistory:=True

End With
End Sub



#1) I don't know how to write a looping statement so that it follows the hyperlink for ALL the links in the document

After I recorded my macro I opened up the editor and noticed the line: Selection.Fields(1).DoClick
But when I tried to re-run the macro, it kept stopping at that point. So I had to comment out the line and afterwards it ran fine. I have no idea why - strange.

#2) Once the URL opens up in Internet Explorer, I right click on the photo and select "Save Picture As..." in the context menu. The name of the file always starts with:

http://www.imagefap.com/image.php?id=xxxxx
(where xxxxx equals several digits).

Is there a way to automate this part? (Save Picture As) Since this involves IE, does it require writing some type of VB script? This is more for personal/ hobby and so it's not anything urgent. But I sure would like to shave some time off this very tedious process!

Using MS Word 2003/ IE 6.0

fumei
10-05-2006, 11:35 AM
#1. Use a Hyperlink objectDim oHyperlink As Hyperlink
For Each oHyperlink In ActiveDocument.Hyperlinks
oHyperlink.Follow NewWindow:=False, AddHistory:=True
NextNOTE! There is a bug in Word with NewWindow:=False. In theory this should force IE to load the URL in the same window (NewWindow:=False). However, there have been a number of threads regarding this, and NewWindow:= False does not seem to work properly. I still can't get it to work properly. It always opens new windows.

Which means of course if you have 100 links it will open 100 new windows. Which I doubt would work as you would run out of resources.
Selection.Rows.Delete
Selection.Delete Unit:=wdCharacter, Count:=1
Selection.MoveDown Unit:=wdLine, Count:=1 I am not sure what you are doing with this. In any case, you should use a With statement for all those Selection instructions. Why is the Row deleted?

#2. I can't help you with this. First of all I am not sure what you actually mean by "automate". I don't use IE, so it is beyond me.

JohnnyBravo
10-05-2006, 01:23 PM
Dim oHyperlink As Hyperlink
For Each oHyperlink In ActiveDocument.Hyperlinks
oHyperlink.Follow NewWindow:=False, AddHistory:=True
Next

Damn the fix was so simple....why didn't I think of that. I was up until 2:30 am last nite trying various commands like While; If / then; etc. Sleep deprivation is for the birds man!

Thanks very much for the revised code. As for the noted bug, in this case it works to my advantage because I want each image to load up in a new IE window. So that's fine. And it's not 100 links per doc... theres about 20 links x 5 documents total.

As for deleting the first row, I suppose that's not totally necessary. I've attached a screenshot of the original doc to show you what it looks like:

http://i5.photobucket.com/albums/y182/tushman/worddoclinks.jpg


#2. I can't help you with this. First of all I am not sure what you actually mean by "automate". I don't use IE, so it is beyond me.
Once the hyperlink is activated, it loads each image in Internet Explorer. Right now, I'm manually right clicking on each photograph and doing a Save Picture As... (as described in my original post). What I mean by "automate" is that I would ultimately like to have my VBA routine call up IE and integrate this step.

I've seen various examples around the internet where a VBA code is written with a few VB lines written into it. Of course since i'm such a newbie, I have no idea how to accomplish this.

fumei
10-05-2006, 08:29 PM
Try posting to another forum for IE code. "Automate" is a funny term. I am assuming you want each photograph to be named (SavedAs) a different name. So you will have to have something that will pass a string to whatever code you get for IE.

fumei
10-05-2006, 09:26 PM
As for simple fix...it REALLY helps to be able to think in terms of objects, rather than processes. As in...

Required: action on every paragraph.

Do not move through the document (that is, using Selection), paragraph by paragraph. You make a paragraph object, then loop through the paragraph Collection.Dim oPara As Word.Paragraph
For Each oPara In ActiveDocument.Paragraphs
' do something with oPara
Next oParaOr say you decide that you want ALL the styles in your document to have their font size increased by 1.Dim oStyle As Style
For Each oStyle In ActiveDocument.Styles
oStyle.Font.Size = oStyle.Font.Size + 1
NextFor Each is a very efficient way of looping through a Collection. In the last example, say you want every Style except...hmmm...MyHeading2...changed.Dim oStyle As Style
For Each oStyle In ActiveDocument.Styles
If oStyle.NameLocal <> "MyHeading2" Then
oStyle.Font.Size = oStyle.Font.Size + 1
End If
Next

MOST things in Word are in fact part of a Collection.

Hyperlinks are in the Hyperlinks Collection.
Paragraphs are in the Paragraph Collection.
All documents currently opened (active or not) are in the Documents Collection.
All FormFields are in the FormFields Collection.

You know the thing with writing code for formfields?ActiveDocument.FormFields("YaddaYadda").Resultfor example....

Making a FormField object of the Collections makes things much cleaner in code.Dim DocFF As FormFields
Set DocFF = ActiveDocument.FormFieldsThis creates an OBJECT that contains all the formfields in the active document. Now you can use:DocFF("YaddaYadda").ResultKeep in mind - always - what the object IS. In the above example DocFF is an object containing ALL the formfields. It is, in essense, the Collection, and can be coded as such.Dim DocFF As FormFields
Set DocFF = ActiveDocument.FormFields
DocFF.Add Selection.Range, Type:=wdFieldFormTextInputWhich adds a text formfield to the Collection, and is placed at the Selection point.

Again, in reference to what an object IS, keep in mind that:

Dim DocFF As FormFields

is VERY different from

Dim oFF As FormField - no plural

The first declares an object of a Collection. The second declares an object of an ITEM of a Collection. The methods, or actions, available are very very different. For example, the FormField Collection itself has no Range property. Therefore you can not cause any action on each formfield if that action requires the Range.

The following assumes a Character style named FormFieldStyle.Dim DocFF As FormFields
Dim oFF As FormField
Set DocFF = ActiveDocument.FormFields
For Each oFF In DocFF
oFF.Range.Style = "FormFieldStyle"
NextThis would make all the formfields, and ONLY the formfields, formatted to the FormField character style.

Note that in the above example you SET the collection object, but you do NOT need to SET the item object. In a way, the For Each logic makes a kind of in-house SET instruction.

Of course you can SET an item object.Dim Client As FormField
Set Client = ActiveDocument.FormFields("ClientName")
Msgbox Client.Resultwould display the text currently in the formfield ClientName.

You may ask why make an object of the formfield? You can get the text of the formfield into a string.Dim strClientName As String
strClientName = ActiveDocument.FormFields("ClientName").Result
Msgbox strClientName
' or even simply
Msgbox ActiveDocument.FormFields("ClientName").Result
The advantage of making, and using, an object is that it persists. If the user goes and changes the text in the formfield ClientName after you have made the string variable the text...unless you explicitly check and change the string variable, it will be the old text. Making an object of the formfield allows Client.Result to always be the current value.

Finally, while there is much debate - see a rather extended discussion in the Excel forum here - on whether you should explicitly destroy objects when you are done with them, I come down with the camp that does explicitly destroy objects.

When you are done with an object, use Set object = Nothing.Set DocFF = Nothing

Damn...should not have had the last coffee.....

JohnnyBravo
10-05-2006, 10:22 PM
LOL... think decaf my man. Wow talk about a chalk full of information! I'm such a newbie most of that is way over my head but I appreciate the effort you put into writing all that. Give me about 3 months to digest all that. hehe....

fumei
10-06-2006, 09:28 PM
yes...or perhaps a nice cup of mint tea.

fumei
10-06-2006, 09:29 PM
yes...or perhaps a nice cup of mint tea.