Extract hyperlink address from HYPERLINK field code - ms-word

I would like to replace the text below with only http://www.someurl.com. I have Word mac 2011. To clarify, I do not actually want to return from the field code to the actual hyperlink (blue), I only want the address as text in the document.
{ HYPERLINK "http://www.someurl.com" }

Something like this (but notice it won't deal with nested fields), and unless you change Word preferences, Word will re-insert the links when you start editing the results:
Sub replaceHLs()
Dim hl As Word.Hyperlink
Dim i As Integer
Dim r As Word.Range
Dim strLinkText As String
For i = ActiveDocument.Hyperlinks.Count To 1 Step -1
With ActiveDocument.Hyperlinks(i)
Set r = .Range
strLinkText = .Address
' optional, should be OK for HTML links
If .SubAddress <> "" Then
strLinkText = strLinkText & "#" & .SubAddress
End If
r.Text = strLinkText
r.Font.Color = wdColorBlue
r.Font.Underline = wdUnderlineSingle
Set r = Nothing
End With
Next
End Sub

Related

Is there a way to count the number of actual replaces when using replaceAll in OO Basic?

Considering the example for search & replace of specific uk-to-us words from the Editing Text Documents OO Wiki:
Dim I As Long
Dim Doc As Object
Dim Replace As Object
Dim BritishWords(5) As String
Dim USWords(5) As String
BritishWords() = Array("colour", "neighbour", "centre", "behaviour", _
"metre", "through")
USWords() = Array("color", "neighbor", "center", "behavior", _
"meter", "thru")
Doc = ThisComponent
Replace = Doc.createReplaceDescriptor
For I = 0 To 5
Replace.SearchString = BritishWords(I)
Replace.ReplaceString = USWords(I)
Doc.replaceAll(Replace)
Next I
Question: is there a way to get the count of actual replacement that has been made ? (if any) I don't mind the individual count for each term, but just globally – i.e. if, say, the original text included 2 occurences for 'colour' and 1 for 'behaviour', in the end to get the number 3 (purpose: to report this number to user as info via MsgBox).
As shown in the example at https://www.openoffice.org/api/docs/common/ref/com/sun/star/util/XReplaceable.html, the number found is returned.
Dim TotalFound As Long
TotalFound = 0
...
TotalFound = TotalFound + Doc.replaceAll(Replace)
Next I
MsgBox "Replaced " & TotalFound & " occurrences"
Result: Replaced 3 occurrences

Finding text AND fields with variable content in Word

I need to find and delete every occurrence of the following pattern in a Word 2010 document:
RPDIS→ text {INCLUDEPICTURE c:\xxx\xxx.png" \*MERGEFORMAT} text ←RPDIS
Where:
RPDIS→ and ←RPDIS are start and end delimiters
Between the start and end delimiters there can be just text or text and fields with variable content
The * wildcard in the Word Find and Replace dialog box will find the pattern if it contains text only but it will ignore patterns where text is combined with fields. And ^19 will find the field but not the rest of the pattern until the end delimiter.
Can anyone help, please?
Here's a VBA solution. It wildcard searches for RPDIS→*←RPDIS. If the found text contains ^19 (assuming field codes visible; if objects are visible instead of field codes, then the appropriate test is text contains ^01), the found text is deleted. Note that this DOES NOT care about the type of embedded field --- it will delete ANY AND ALL embedded fields that occur between RPDIS→ and ←RPDIS, so use at your own risk. Also, the code has ChrW(8594) and ChrW(8592) to match right-arrow and left-arrow respectively. You may need to change that if your arrows are encoded differently.
Sub test()
Dim wdDoc As Word.Document
Dim r As Word.Range
Dim s As String
' Const c As Integer = 19 ' Works when field codes are visible
Const c As Integer = 1 ' Works when objects are visible
Set wdDoc = ActiveDocument
Set r = wdDoc.Content
With r.Find
.Text = "RPDIS" & ChrW(8594) & "*" & ChrW(8592) & "RPDIS"
.MatchWildcards = True
While .Execute
s = r.Text
If InStr(1, s, chr(c), vbTextCompare) > 0 Then
Debug.Print "Delete: " & s
' r.Delete ' This line commented out for testing; remove comments to actively delete
Else
Debug.Print "Keep: " & s
End If
Wend
End With
End Sub
Hope that helps.

LibreOffice Draw -add hyperlinks based on query table

I am using draw to mark up a pdf format index map. So in grid 99, the text hyperlinks to map99.pdf
There are 1000's of grid cells - is there a way for a (macro) to scan for text in a sheet that is like
Text in File | Link to add
99|file:///c:/maps/map99.pdf
100|file:///c:/maps/map100.pdf
and add links to the relevant file whenever the text is found (99,100 etc).
I don't use libre much but happy to implement any programatic solution.
Ok, after using xray to drill through enumerated content, I finally have the answer. The code needs to create a text field using a cursor. Here is a complete working solution:
Sub AddLinks
Dim oDocument As Object
Dim vDescriptor, vFound
Dim numText As String, tryNumText As Integer
Dim oDrawPages, oDrawPage
Dim oField, oCurs
Dim numChanged As Integer
oDocument = ThisComponent
oDrawPages = oDocument.getDrawPages()
oDrawPage = oDrawPages.getByIndex(0)
numChanged = 0
For tryNumText = 1 to 1000
vDescriptor = oDrawPage.createSearchDescriptor
With vDescriptor
'.SearchString = "[:digit:]+" 'Patterns work in search box but not here?
.SearchString = tryNumText
End With
vFound = oDrawPage.findFirst(vDescriptor)
If Not IsNull(vFound) Then
numText = vFound.getString()
oField = ThisComponent.createInstance("com.sun.star.text.TextField.URL")
oField.Representation = numText
oField.URL = numText & ".pdf"
vFound.setString("")
oCurs = vFound.getText().createTextCursorByRange(vFound)
oCurs.getText().insertTextContent(oCurs, oField, False)
numChanged = numChanged + 1
End If
Next tryNumText
MsgBox("Added " & numChanged & " links.")
End Sub
To save relative links, go to File -> Export as PDF -> Links and check Export URLs relative to file system.
I uploaded an example file here that works. For some reason your example file is hanging on my system -- maybe it's too large.
Replacing text with links is much easier in Writer than in Draw. However Writer does not open PDF files.
There is some related code at https://forum.openoffice.org/en/forum/viewtopic.php?f=20&t=1401.

Data validator VBA excel- compare a value within a string in one cell to a value in another

Have not been able to find anything that fits my needs.
I have two columns of values (L and U). Column L contains a file names that includes a date in MM-DD-YYYY format (example yadayadayada thru (03-15-2015).pdf) column U contains a date. What I need to do is have a macro compare the date within the file name to the date in the column U. Other dates may appear within the text in column L but the date I need to compare against is always after "thru" and in parentheses followed by the file extension. If they do not match, I need the value in column U highlighted and replaced with the text "FAIL". I'm going to continue searching but any help is greatly appreciated. Thanks!
Does it have to be VBA? This can be accomplished with Conditional Formatting.
Apply this conditional format formula to column U:
=AND(U1<>"",L1<>"",U1<>--TRIM(MID(SUBSTITUTE(TRIM(RIGHT(SUBSTITUTE(L1," ",REPT(" ",255)),255)),")",REPT(" ",255)),2,255)))
And set the number format to Custom "FAIL" with yellow (or the highlight color of your choice) fill.
EDIT
If it has to be VBA, then this should work for you:
Sub tgr()
Const HeaderRow As Long = 1 'Change to your actual header row
Dim ws As Worksheet
Dim rngFail As Range
Dim rngFiles As Range
Dim FileCell As Range
Dim dDate As Double
Set ws = ActiveWorkbook.ActiveSheet
Set rngFiles = ws.Range("L" & HeaderRow + 1, ws.Cells(Rows.Count, "L").End(xlUp))
If rngFiles.Row < HeaderRow + 1 Then Exit Sub 'No data
For Each FileCell In rngFiles.Cells
If Len(Trim(FileCell.Text)) > 0 Then
dDate = 0
On Error Resume Next
dDate = CDbl(CDate(Trim(Mid(Replace(Trim(Right(Replace(FileCell.Text, " ", String(255, " ")), 255)), ")", String(255, " ")), 2, 255))))
On Error GoTo 0
If dDate <> ws.Cells(FileCell.Row, "U").Value2 Then
Select Case (rngFail Is Nothing)
Case True: Set rngFail = ws.Cells(FileCell.Row, "U")
Case Else: Set rngFail = Union(rngFail, ws.Cells(FileCell.Row, "U"))
End Select
End If
End If
Next FileCell
If Not rngFail Is Nothing Then
rngFail.Value = "FAIL"
rngFail.Interior.ColorIndex = 6
End If
End Sub

Getting the text of all check boxes in a tabcontrol to a string

I am extremely new to all of this, and whilst I have tried searching I cant find anything that has helped me achieve what I am after.
I have a form in VB with the following:
1 x tabcontrol
10 x checkboxes which sit in various tabs on the tab control
1 x listbox
When i tick any of the check boxes, I want their text to be added to the listbox, and when I untick, their text to be taken from the listbox.
I can achieve this very easily using if statements for the changedcheck event for each checkbox but I have to do that for every single checkbox which isn't very efficient as potentially i could have 20,30 40+ check boxes. Plus if I add one at a later stage I would have to remember to add its code.
Ideally i want a method that's says: check all the checkboxes in tabcontrol if there value is true write their text to a string, if there value is false, take there text from the string. put the string in the listbox.
I started with something like this...
Dim chk As CheckBox
Dim txt As String = ""
For Each chk In TabControl1.Controls
If chk.Checked = True Then
txt = txt + chk.Text +vbCrLF
Else
txt = replace(txt, chk.text + vbCrLf, "")
End If
Next
End Sub
First problem is that the above obviously doesn't work! so any guidance there is appreciated - i put it together from reading scraps from other code.
Second problem is, i can't get my head round how the list box will be updated, as previously i was using the CheckedChanged event for each control, which if i do what i want, then there wont be a specific CheckedChanged event, as it could be any of the checkboxes (hopefully that makes sense!). I don't want to have to press a button to add the checked checkboxes to the listbox, i want it to be dynamic
any help is very much appreciated.
For your first problem add
Dim chk As Control
Dim txt As String = ""
For Each chk In TabControl1.Controls
If TypeOf chk Is CheckBox
If DirectCast(chk, CheckBox).Checked = True Then
txt = txt + chk.Text +vbCrLF
Else
txt = replace(txt, chk.text + vbCrLf, "")
End If
End If
Next
End Sub
For your second problem in CheckedChanged event you can do something like this:
Private Sub OnCheckedChanged(sender as Object, e as EventArgs) _
Handles CheckBox1.CheckedChanged
Dim chk As CheckBox = TryCast(s, CheckBox)
Dim txt as string
If c.Checked = True Then
txt = chk.Text
EndIf
End Sub