MS Word batch hyperlink - ms-word

I would like to know if there is a way to create hyperlinks from a text in bulk.
I have the following text:
www. abc .com/pictures/T_1.jpg
www. abc. com/pictures/T_2.jpg
www. abc. com/pictures/T_3.jpg
www. abc. com/pictures/T_4.jpg
Each text is a link in its own right, but if I select all and press Ctrl+K, I cannot create a hyperlink that takes the text as a weblink. I can do it one by one. If I select any of the text and press Ctrl+K, it'll give me www.abc.com/pictures/T_1.jpg as the web address for that link, but not in bulk. How to do it?
Note: spaces in the links to avoid posting errors.

Please try this,
Paste links in word and separate them by a paragraph,
Select the links and Insert -> Table -> Convert to Table,
View -> Macros -> View Macros and create the following macro named BH
Sub BH()
Dim Rng As Range, TblCell As Cell, StrTxt As String
With Selection
If .Information(wdWithInTable) = False Then Exit Sub
For Each TblCell In .Cells
Set Rng = TblCell.Range
With Rng
.End = .End - 1
StrTxt = .Text
.Text = ""
End With
ActiveDocument.Hyperlinks.Add Anchor:=Rng, _
Address:="Address", SubAddress:="SubAddress", _
ScreenTip:="", TextToDisplay:=StrTxt, Target:="_blank"
Next
End With
End Sub

For what you have described:
Sub ConvertURLTextsToHyperlinksInDoc()
Application.ScreenUpdating = False
With ActiveDocument.Range
With .Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "[wh][wt][wtps]{1,3}[./][!^13^t^l ^s]{1,}"
.Replacement.Text = ""
.Forward = True
.Format = False
.Wrap = wdFindStop
.MatchWildcards = True
.Execute
End With
Do While .Find.Found
If .Characters.Last Like "[:;.,(?)!})]" Then .End = .End - 1
.Hyperlinks.Add .Duplicate, .Text, , , .Text
.Start = .Hyperlinks(1).Range.End
.Find.Execute
Loop
End With
Application.ScreenUpdating = True
End Sub
The text you posted, though, does not include valid URLs - there are spaces either side of abc...

Related

Microsoft Access - Loop through all forms and controls on each form

Okay so when I press a specific button I want to loop through all forms, then find every control in each form with the tag 'TESTING'. If the tag = 'TESTING' then I want to change the caption of the object to 'abc123'.
The only objects with the tag 'TESTING' will be labels, so they will have the caption property.
So far I have this as the function:
Public Function changelabel()
On Error Resume Next
Dim obj As AccessObject, dbs As Object
Dim ctrl as Control
Set dbs = Application.CurrentProject
For Each obj In dbs.AllForms
DoCmd.OpenForm obj.Name, acDesign
For Each ctrl In Me.Controls
If ctrl.Tag = "TESTING" Then
ctrl.Caption = "abc123"
End If
Next ctrl
Next obj
End Function
Then this as the button code:
Public Sub TestButton_Click()
Call changelabel
End Sub
So it executes the first for loop and opens all the forms in design view correctly. The problem lies with the second for loop. None of the label captions that have the tag property as 'TESTING' are changed to 'abc123'.
So what do I need to change to get the second for loop to work?
Public Sub GetForms()
Dim oForm As Form
Dim nItem As Long
Dim bIsLoaded As Boolean
For nItem = 0 To CurrentProject.AllForms.Count - 1
bIsLoaded = CurrentProject.AllForms(nItem).IsLoaded
If Not bIsLoaded Then
On Error Resume Next
DoCmd.OpenForm CurrentProject.AllForms(nItem).NAME, acDesign
End If
Set oForm = Forms(CurrentProject.AllForms(nItem).NAME)
GetControls oForm
If Not bIsLoaded Then
On Error Resume Next
DoCmd.Close acForm, oForm.NAME
End If
Next
End Sub
Sub GetControls(ByVal oForm As Form)
Dim oCtrl As Control
Dim cCtrlType, cCtrlCaption As String
For Each oCtrl In oForm.Controls
If oCtrl.ControlType = acSubform Then Call GetControls(oCtrl.Form)
Select Case oCtrl.ControlType
Case acLabel: cCtrlType = "label": cCtrlCaption = oCtrl.Caption
Case acCommandButton: cCtrlType = "button": cCtrlCaption = oCtrl.Caption
Case acTextBox: cCtrlType = "textbox": cCtrlCaption = oCtrl.Properties("DataSheetCaption")
Case Else: cCtrlType = ""
End Select
If cCtrlType <> "" Then
Debug.Print oForm.NAME
Debug.Print oCtrl.NAME
Debug.Print cCtrlType
Debug.Print cCtrlCaption
End If
Next
End Sub
Something like this
Public Function changelabel()
Dim f As Form
Dim i As Integer
Dim c As Control
For i = 0 To CurrentProject.AllForms.Count - 1
If Not CurrentProject.AllForms(i).IsLoaded Then
DoCmd.OpenForm CurrentProject.AllForms(i).Name, acDesign
End If
Set f = Forms(i)
For Each c In f.Controls
If c.Tag = "TESTING" Then
c.Caption = "TESTING"
End If
Next c
Next i
End Function
You'll need to add a bit of house-keeping to set the objects used to nothing etc..

Modification to Ron De Bruins Email Different Files (?)

I'm using Ron de Bruins code for emailing many different files to different people, as shown below. But the issue I have is, if an email address exists in column B and the corresponding workbook doesn't exist it still creates an email but with no attachment, as there isn't one. Would anyone know how to modify the code so that if a workbook didn't exist it doesn't create the email?
Sub Send_Files()
'Working in Excel 2000-2013
'For Tips see: http://www.rondebruin.nl/win/winmail/Outlook/tips.htm
Dim OutApp As Object
Dim OutMail As Object
Dim sh As Worksheet
Dim cell As Range
Dim FileCell As Range
Dim rng As Range
With Application
.EnableEvents = False
.ScreenUpdating = False
End With
Set sh = Sheets("Sheet1")
Set OutApp = CreateObject("Outlook.Application")
For Each cell In sh.Columns("B").Cells.SpecialCells(xlCellTypeConstants)
'Enter the path/file names in the C:Z column in each row
Set rng = sh.Cells(cell.Row, 1).Range("C1:Z1")
If cell.Value Like "?*#?*.?*" And _
Application.WorksheetFunction.CountA(rng) > 0 Then
Set OutMail = OutApp.CreateItem(0)
With OutMail
.to = cell.Value
.Subject = "Testfile"
.Body = "Hi " & cell.Offset(0, -1).Value
For Each FileCell In rng.SpecialCells(xlCellTypeConstants)
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
.Send 'Or use .Display
End With
Set OutMail = Nothing
End If
Next cell
Set OutApp = Nothing
With Application
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
You can set a flag to go to the next item if the file does not exist:
Dim noFile as Boolean
noFile = True
For Each FileCell In rng.SpecialCells(xlCellTypeConstants)
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
noFile = False
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
if Not noFile then .Send
There are other ways to do this (see for example Sidharth Rout's suggestion which checks for the existence of files before even starting to create the email); I chose the above because it minimizes the amount of change needed in your existing code (just three lines, easy to see what they do).
Some people would prefer to invert the logic, with a hasFile boolean:
Dim hasFile as Boolean
hasFile = False
For Each FileCell In rng.SpecialCells(xlCellTypeConstants)
If Trim(FileCell) <> "" Then
If Dir(FileCell.Value) <> "" Then
hasFile = True
.Attachments.Add FileCell.Value
End If
End If
Next FileCell
if hasFile then .Send

Modify VBA macro to delete unneeded text

I have a .txt file that needs to be cleaned up. It needs to have a page break before the word "Individual" on every page. It also needs to be Courier New 8.5pts, top and bottom margin of 0.5in, left and right margin of 1in. I modified another script I found (shown below) and it almost gets me there. the problem is there is some unneeded text before "Individual", which is the number 1 followed by several spaces and 3 carraige returns. I need to delete this text. Below is the script as it is currently:
Sub InsertPageBeforeDate()
Dim lngPos As Long
Application.ScreenUpdating = False
Selection.HomeKey Unit:=wdStory
Selection.WholeStory
Selection.Font.Name = "Courier New"
Selection.Font.Size = 8.5
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "Individual"
.Format = False
.MatchCase = False
.MatchWholeWord = True
.MatchWildcards = False
Do While .Execute
If Selection.Information(wdFirstCharacterLineNumber) > 1 Then
lngPos = Selection.Start
Selection.MoveLeft Unit:=wdWord, Count:=2, Extend:=True
If LCase(Selection.Text) <> "of " Then
Selection.Collapse Direction:=wdCollapseEnd
Selection.InsertBreak Type:=wdPageBreak
End If
ActiveDocument.Range(Start:=lngPos + 4, End:=lngPos + 4).Select
End If
Loop
End With
Application.ScreenUpdating = True
End Sub

Need validation code so only 1 of 3 Boolean fields can be true

Access 2010: I have a table that includes 3 Boolean fields - call them Field_A, Field_B, and Field_C.
On the data entry form, a user should be able to check (make the value TRUE) any one of those options, but only one option can be TRUE at any time. If Field_B is already true and the user wants to change it so Field_C is the option selected to be TRUE, he should first have to unselect Field_B (reset it to FALSE) before he can check the box on the form for Field_C.
So I need some validation code for each of these fields which, if the user tries to set one field to TRUE, checks the status of the other two fields. If both other fields are currently FALSE, it allows the current field to be changed to TRUE. But if either of the other fields is currently TRUE, it should create a popup message saying there's already another selection and the other field must first be changed to FALSE before he can proceed.
I tried this using the numerical values for the Yes/No option, setting a conditional validation that required the sum of the other two values to be zero before allowing the field of interest (e.g. Field_A) to be changed to TRUE (value = -1) (just something like ([Field_B] + [Field_C]) =0, but I kept getting syntax errors. I'm new enough to this that I don't know if it really is just a simple syntax problem, or if a completely different approach is needed.
Last piece of info-- it's acceptable to have all 3 fields set to FALSE, so I don't want something that forces one of them to become TRUE if another is changed back from TRUE to FALSE.
You have two acceptable combinations for those 3 check boxes:
all are False (unchecked)
only one can be True (checked)
So that means the sum of those check box values must be either 0 or -1.
? False + False + False
0
? False + False + True
-1
You can add a function in the form's code module ...
Private Function checkBoxProblem() As Boolean
Dim blnReturn As Boolean
Dim intSum As Integer
Dim strPrompt As String
intSum = Nz(Me.Field_A, 0) + Nz(Me.Field_B, 0) + Nz(Me.Field_C, 0)
If Not (intSum = 0 Or intSum = -1) Then
strPrompt = "only one box can be checked"
MsgBox strPrompt
blnReturn = True
Else
blnReturn = False
End If
checkBoxProblem = blnReturn
End Function
Then call the function from the before update events of each of those 3 check boxes.
Private Sub Field_A_BeforeUpdate(Cancel As Integer)
Cancel = checkBoxProblem
End Sub
Private Sub Field_B_BeforeUpdate(Cancel As Integer)
Cancel = checkBoxProblem
End Sub
Private Sub Field_C_BeforeUpdate(Cancel As Integer)
Cancel = checkBoxProblem
End Sub
A bit of code behind your data-entry form should do the trick. Try something along these lines:
Option Compare Database
Option Explicit
Private Sub Field_A_BeforeUpdate(Cancel As Integer)
Const ThisField = "Field_A"
If Me.Field_A.Value Then
If Me.Field_B.Value Then
ShowMyMessage "Field_B", ThisField
Cancel = True
ElseIf Me.Field_C.Value Then
ShowMyMessage "Field_C", ThisField
Cancel = True
End If
End If
End Sub
Private Sub Field_B_BeforeUpdate(Cancel As Integer)
Const ThisField = "Field_B"
If Me.Field_B.Value Then
If Me.Field_A.Value Then
ShowMyMessage "Field_A", ThisField
Cancel = True
ElseIf Me.Field_C.Value Then
ShowMyMessage "Field_C", ThisField
Cancel = True
End If
End If
End Sub
Private Sub Field_C_BeforeUpdate(Cancel As Integer)
Const ThisField = "Field_C"
If Me.Field_C.Value Then
If Me.Field_B.Value Then
ShowMyMessage "Field_B", ThisField
Cancel = True
ElseIf Me.Field_A.Value Then
ShowMyMessage "Field_A", ThisField
Cancel = True
End If
End If
End Sub
Private Sub ShowMyMessage(OtherField As String, CurrentField As String)
MsgBox _
"You must un-select """ & OtherField & """" & _
" before you can select """ & CurrentField & """", _
vbExclamation, _
"Mutually exclusive options conflict"
End Sub

Excel: How to convert text to number formats for multiple workbooks

I have about 40 workbooks with 1000+ columns and near 1 million records.
Unfortunately, most of the data was imported as a text format, and I am trying to convert particular columns to a number format.
Aside from manually editing every file using the paste special > multiply technique, is there a way to macro this so that it would iterate through all the excel files in a particular folder?
You know the columns and numbers to change. You can record a macro of that and insert it into this basic DIR() technique:
Option Explicit
Sub LoopThroughFolder()
Dim fPATH As String, fNAME As String
Dim wb As Workbook
fPATH = "C:\Path\To\My\Files\" 'remember the final \
fNAME = Dir(fPATH & "*.xl*") 'get first filename from fPATH
Application.ScreenUpdating = False 'speed up execution
Do While Len(fNAME) > 0
Set wb = Workbooks.Open(fPATH & fNAME)
'your code here to format that activesheet
wb.Close True 'save and close the edited file
fNAME = Dir 'get the next filename
Loop
Application.ScreenUpdating = True
End Sub
Option Compare Database
Public Function format(filepath, sheetname, sheetpath)
Set xls = CreateObject("EXCEL.APPLICATION")
xls.screenupdating = False
xls.displayalerts = False
xls.Visible = True
xls.workbooks.Open filepath
Set xlsdd = xls.ActiveWorkbook
'deleting headers
xls.Range("1:1").Select
xls.Selection.Delete Shift:=xlUp
'adding one column
xls.Columns("A:A").Select
xls.Selection.Insert Shift:=xlToRight, CopyOrigin:=xlFormatFromLeftOrAbove
'adding 5 rows
'ActiveWorkbook.Sheets("sheet1").Select
xls.Rows("1:5").Insert Shift:=xlDown
' fetching rows from access and putting them into excel
' strsql = "select top 5 " & sheetname & ".* into top5_records from " & sheetname
' DoCmd.RunSQL strsql
' outputFileName = "C:\Users\hp\Desktop\top5_records.xls"
' DoCmd.TransferSpreadsheet acExport, acSpreadsheetTypeExcel9, "top5_records", outputFileName, True
'then open that excel and copy the rows
Set xls2 = CreateObject("EXCEL.APPLICATION")
xls2.screenupdating = False
xls2.displayalerts = False
xls2.Visible = True
xls2.workbooks.Open sheetpath
Set xlsdd2 = xls2.ActiveWorkbook
xls2.Rows("1:5").Select
xls2.Selection.Copy
xls.Cells(1, 1).Select
xls.activesheet.Paste
'making first 6th row to be bold
xls.Rows("6:6").Select
With xls.Selection.Font
.Bold = True
.Name = "Arial"
.Size = 10
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
End With
'autofit the data
xls.Sheets(sheetname).Cells.Columns.autofit
xls.CutCopyMode = False
'making both the excel objects to be free
With xlsdd
.Save
.Close
End With
xls.Visible = False
Set xlsdd = Nothing
Set xls = Nothing
With xlsdd2
.Save
.Close
End With
xls2.Visible = False
Set xlsdd2 = Nothing
Set xls2 = Nothing
End Function