VBA search and replace with wildcards: using \ (backslash) in replace string also containing numbers (error: 5623) - vba

Premiss:
I have a word document with a lot of { LINKS ... } to an excel document to be able to generate word documents easier. When i move these documents to a new directory i want to update all links with the new dir and possibly a new excel docname as well.
Problem:
I have found on stackoverflow and other sites a vba/macro that mostly does what i need. The problem arises when i do a wildcard .find .replace where the replace text contains \ and the dirname has numbers.
Code:
Public Sub planer_fix_data_link()
Dim rngStory As Word.Range
Dim pFindTxt As String
Dim pReplaceTxt As String
Dim lngJunk As Long
Dim oShp As Shape
'Pattern to find with wildcards as i don't always know the last location
pFindTxt = "LINK Excel.Sheet.12*xlsx"
TryAgain:
pReplaceTxt = InputBox("New excel filename", "Malldata filnamn")
If pReplaceTxt = "" Then
If MsgBox("Do you just want to delete the found text?", vbYesNoCancel) = vbNo Then
GoTo TryAgain
ElseIf vbCancel Then
MsgBox "Cancelled by User."
Exit Sub
End If
End If
currPath = ActiveDocument.Path
'links need double for some reason
currPath = Replace(currPath, "\","\\")
'text to replace with
pReplaceTxt = "LINK Excel.Sheet.12 """ & currPath & "\\" & pReplaceTxt & ".xlsx"
Application.ActiveWindow.View.ShowFieldCodes = True
'Fix the skipped blank Header/Footer problem
lngJunk = ActiveDocument.Sections(1).Headers(1).Range.StoryType
'Iterate through all story types in the current document
For Each rngStory In ActiveDocument.StoryRanges
'Iterate through all linked stories
Do
SearchAndReplaceInStory rngStory, pFindTxt, pReplaceTxt
On Error Resume Next
Select Case rngStory.StoryType
Case 6, 7, 8, 9, 10, 11
If rngStory.ShapeRange.Count > 0 Then
For Each oShp In rngStory.ShapeRange
If oShp.TextFrame.HasText Then
SearchAndReplaceInStory oShp.TextFrame.TextRange, pFindTxt, pReplaceTxt
End If
Next
End If
Case Else
'Do Nothing
End Select
On Error GoTo 0
'Get next linked story (if any)
Set rngStory = rngStory.NextStoryRange
Loop Until rngStory Is Nothing
Next
Application.ActiveWindow.View.ShowFieldCodes = False
ActiveDocument.Fields.Update
End Sub
Public Sub SearchAndReplaceInStory(ByVal rngStory As Word.Range, ByVal strSearch As String, ByVal strReplace As String)
With rngStory.Find
.ClearFormatting
'.Replacement.ClearFormatting
.MatchWildcards = True
.Text = strSearch
.Replacement.Text = strReplace
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
End Sub
current dir is something like C:\Users\\Dropbox\Project\1. planning\\
Easy reproduction
as my code uses the same engine as the standard search and replace one can easily reproduce the problem by starting a new word doc typing in
C:\\Users\\testuser\\Dropbox\\Project\\test\\testproject\\excelfile.xlsm
And the do a wildcard search and replace with
C:*.xlsm
as search and
C:\\Users\\testuser\\Dropbox\\Project\\1. Planning\\testproject\\excelfile.xlsm
as replace
I figure i need some way of escaping my backslashes but i just cant find a way to do that

Okay this gets a little more complex you need to replace the backslashes with the ascii eqivalent ^92. However as you have numbers as well then they become a problem if they follow a \ so need converting to ascii as well.
So use a function to convert the replacement string to the correct format like below
Function convert(inp As String) As String
Dim ret As String
Dim char As String
ret = ""
For i = 1 To Len(inp)
char = Mid(inp, i, 1)
If char = "\" Or (char >= "0" And char <= "9") Then
ret = ret + "^" + Format(Asc(char))
Else
ret = ret + char
End If
Next i
convert = ret
End Function

Related

Nested If Then and For Statements

I know how to fix the error in the macro below, but not the why behind the fix. Why is the " _" causing problems in the second If...Then statement?
I can fix it by either deleting the " _" or inserting a line below it. However, I can't move the For Statement to the end of the If...Then statement.
Sub Loop_Link_Change_ROE()
Dim MyPath As String
Dim MyFile As String
Dim sLink As String
Dim sNewName As String
Dim tNewName As String
Dim varLinks As Variant
Dim i As Integer
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.EnableEvents = False
MyPath = "P:\Department\Actuarial Archive\Reserves\2018Q2\Documentation\Data Recon\"
MyFile = Dir(MyPath)
Do While MyFile <> ""
If MyFile Like "*Analysis_Regions_Phys_CM_*.xl*" Then
Workbooks.Open Filename:=MyPath & MyFile, UpdateLinks:=0
varLinks = ActiveWorkbook.LinkSources(xlExcelLinks)
If Not IsEmpty(varLinks) Then _
For i = 1 To UBound(varLinks)
If InStr(1, varLinks(i), "4Q17") Then sNewName = Replace(varLinks(i), "4Q17", "2Q18")
If InStr(1, varLinks(i), "GA") Then tNewName = Replace(sNewName, "GA", "Mid(varLinks(i), 30, 2)")
If InStr(1, varLinks(i), "GA") Then ActiveWorkbook.ChangeLink Name:=varLinks(i), NewName:=tNewName, Type:=xlExcelLinks
ActiveWorkbook.Close True
Next
End If
End If
MyFile = Dir
Loop
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Application.EnableEvents = True
End Sub
Thanks in advance for any help!
There are two basic forms using If in VBA
All one one line:
If {test} Then {something}
...in which case subsequent lines have no connection with the If
Using End If and multiple lines:
If {test} Then
{something} 'one or more lines of code
End If
Your _ is not doing anything useful there
Underscore is a line continuation in vb so if you use it then you do not need an "end if" for that if statement because the for loop line below is treated as if it were part of the previous line.

Find and Replace Multiple Text Strings on Multiple Text Files from a folder

I'm working on the vba code to accomplish the following tasks
Word Document Open a Text file from the folder
Find and replace the text (multiple Text) based on a excel sheet (which have find what and replace with)
Process all text files in the folder and save it.
I would like to customize the below code for the above requirement,
I'm using Office 2016 and I think I have to replace Application.FileSearch in the script to ApplicationFileSearch for 2003 and prior office editions.
I try to accomplish using the word macro recorder and also used notepad++, I've recorded in Notepad++ also and it works for one file, I would like to do batch process all files in the folder and save it after replacing the text.
As there is too many lines there to replace more than 30 or more lines to replace, I would like the code to look for the text from a excel file like find what and replace with columns.
Sub FindReplaceAllDocsInFolder( )
Dim i As Integer
Dim doc As Document
Dim rng As Range
With Application.FileSearch
.NewSearch
.LookIn = "C:\My Documents"
.SearchSubFolders = False
.FileType = msoFileTypeWordDocuments
If Not .Execute( ) = 0 Then
For i = 1 To .FoundFiles.Count
Set doc = Documents.Open(.FoundFiles(i))
For Each rng In doc.StoryRanges
With rng.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "Dewey & Cheatem"
.Replacement.Text = "Dewey, Cheatem & Howe"
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With
Next rng
doc.Save
doc.Close
Set rng = Nothing
Set doc = Nothing
Next i
Else
MsgBox "No files matched " & .FileName
End If
End With
End Sub
Thanks
Jay
Borrowed from https://social.msdn.microsoft.com/Forums/en-US/62fceda5-b21a-40b6-857c-ad28f12c1b23/use-excel-vba-to-open-a-text-file-and-search-it-for-a-specific-string?forum=isvvba
Sub SearchTextFile()
Const strFileName = "C:\MyFiles\TextFile.txt"
Const strSearch = "Some Text"
Dim strLine As String
Dim f As Integer
Dim lngLine As Long
Dim blnFound As Boolean
f = FreeFile
Open strFileName For Input As #f
Do While Not EOF(f)
lngLine = lngLine + 1
Line Input #f, strLine
If InStr(1, strLine, strSearch, vbBinaryCompare) > 0 Then
MsgBox "Search string found in line " & lngLine, vbInformation
blnFound = True
Exit Do
End If
Loop
Close #f
If Not blnFound Then
MsgBox "Search string not found", vbInformation
End If
End Sub
This is simply just finding the match. You can use the built in function "Replace" which land the total fix. You would also have to fit in the "loop through files" code, which here is a snippet.
Dim StrFile As String
StrFile = Dir(pathtofile & "\*" & ".txt")
Do While Len(StrFile) > 0
Debug.Print StrFile
StrFile = Dir
Loop
I wouldve made this a comment, but it was too much text. This isnt meant to be a full blown answer, just giving you the pieces you need to put it all together on your own.
Thanks for all your help. I have found alternate solution using the below EXE. FART.exe (FART - Find and Replace Text). I have create a batch file with the below command example.
https://emtunc.org/blog/03/2011/farting-the-easy-way-find-and-replace-text/
http://fart-it.sourceforge.net/
Examples:
fart "C:\APRIL2011\Scripts\someFile.txt" oldText newText
This line instructs FART to simply replace the string oldText with newText.
fart -i -r "C:\APRIL2011\Scripts*.prm" march2011 APRIL2011
This line will instruct FART to recursively (-r) search for any file with the .prm extension in the \Scripts folder. The -i flag tells FART to ignore case-sensitivity when looking for the string.

Why does the .Find function appear to not work properly in this code?

The program is supposed to loop through a directory to find every occurrence of a word from a list that is in another word document and expand selection to the whole question. This program is supposed to allow you to compile a list of test questions from a test bank based on a list of highly relevant key terms. Eventually, once all the relevant questions are selected They would be copied to a new document.
Sub CompareWordList()
'program to loop through Directory to find every occurrence of a word from a list and expand selection to
'the whole question. This program is supposed to allow you to compile a list of test questions from a
'test bank based on a list of highly relevent key terms. Eventually, once all the relevent questions are selected
'They would be copied to a new document
'variables for directory looping
Dim vDirectory As String
Dim oDoc As Document
'generates file path
vDirectory = "D:\school\documents\MGT450\Test_Bank\TB - test\" 'set directory to loop through
vFile = Dir(vDirectory & "*.*") 'file name
'variables for selection
Dim sCheckDoc As String
Dim docRef As Document
'Dim docCurrent As Document
Dim wrdRef As Object
'list of words to look for
sCheckDoc = "D:\testlist.docx"
Set docRef = Documents.Open(sCheckDoc)
'docCurrent.Activate
docRef.Activate
'Directory Loop
Do While vFile <> ""
Set oDoc = Documents.Open(FileName:=vDirectory & vFile)
'document activation
oDoc.Activate
SendDocToArray_FindWords (sCheckDoc)
'Havent really worked on this area yet, as been focused on find issue
docRef.Close
'close document modification
oDoc.Close SaveChanges:=False
vFile = Dir
Loop
End Sub
'After every instance of a particular phrase is selected, select question
around said phrase
Function SelectQuestion(Index As Long)
'iniitial declaration
Dim linecount As Integer
Set mydoc = ActiveDocument
Dim oPara As word.Paragraph
'Dim oPara As selection
Dim ListLevelNumber As Integer
Dim holder As Long
'if list type is simple numbering
If selection.Range.ListFormat.ListType = wdListSimpleNumbering Or
wdListBullet Or wdListMixedNumbering Then
'Select Whole Question containing word
With selection
.StartIsActive = False
.Extend Character:=";"
.EndKey
.StartOf (wdLine)
End With
a = selection.MoveUntil(";", wdBackward)
b = selection.MoveDown(wdLine, 2, wdMove)
selection.StartOf (wdLine)
selection.Find.Execute "*^13^13", , , True
'some correction of range- remove last paragraph from selection
ActiveDocument.Range(selection.Start, selection.End - 1).Select
End If
End Function
Function GetParNum(r As Range) As Integer
'determines paragraph number
GetParNum = selection.Range.ListFormat.ListValue
End Function
Sub Test() 'testing function
CountWords
End Sub
Function SendDocToArray_FindWords(name As String) As Variant
'sends a document to an array split by newline
'the document that is send to the array is composed of the words that are
'being searched for.
Dim doc As Document
Set doc = Documents.Open(name)
Dim arr() As String
arr() = Split(doc.Content.Text, Chr(13))
Dim iCount As Integer
Dim targetRng As Range
For Each i In arr()
Dim r As Range
Dim j As Long
Set r = ActiveDocument.Content
With r.Find
'If I pass a variable to FindText it only finds the first instance of the word then
'prematurely exits loop or becomes an infinite loop
'strangely the function is only working when I hardcode the word such as
'FindText:= "International Business"
Do While .Execute(FindText:=i, Forward:=True, Wrap:=wdFindContinue) = True
If r.Find.Found = True Then
j = j + 1
End If
Loop
End With
MsgBox "The Word" & i & " was found " & j & " times."
Next i
MsgBox ("Finished Selecting")
End Function
'testing count words function
Function CountWords(c As String) 'ByRef word As Variant
'counts number of occurences of words in document
Dim r As Range
Dim j As Long
Set r = ActiveDocument.Content
'ResetFRParameters r
With r.Find
'.Wrap = wdFindContinue
Do While .Execute(FindText:=i, Forward:=True) = True
If r.Find.Found = True Then
j = j + 1
End If
Loop
End With
MsgBox "Given word(s) was found " & j & " times."
End Function
'testing count words function
Sub FindText()
Dim MyAR() As String
Dim i As Long
i = 0
selection.HomeKey Unit:=wdStory
selection.Find.Text = "International Business"
' selection.Range.Text
Do While selection.Find.Execute = True
ReDim Preserve MyAR(i)
MyAR(i) = selection
i = i + 1
Loop
If i = 0 Then
MsgBox "No Matches Found"
Exit Sub
End If
For i = LBound(MyAR) To UBound(MyAR)
MsgBox ("# of International Business occurrences " & i)
Next i
End Sub
I used three finds that I was trying to get to work correctly but they do not appear to search the whole document regardless how I use them. I have started wondering if the formatting of my document is to blame. I have attached both an image of the list of terms as well as document to search through.
This is the list of terms to search through
This is the document to search through
My ultimate question is how do I get around this problem and find all instances of the given search term in the document? As of now it either finds the first instance and breaks or becomes an infinite loop.
This is the final that works, although not he prettiest, for others who may be looking for similar code: (pasting it here as messed up the format a bit so youll need to fix those if you use it)
Sub TraversePath()
Dim fso As Object 'FileSystemObject
Dim fldStart As Object 'Folder
Dim fld As Object 'Folder
Dim fl As Object 'File
Dim Mask As String '.doc,.docx,.xlsx, etc
Set fso = CreateObject("scripting.FileSystemObject") ' late binding
'Set fso = New FileSystemObject 'or use early binding (also replace Object
types)
Set fldStart = fso.GetFolder("D:\school\documents\MGT450\Test_Bank\TB -
test\") ' Base Directory
Mask = "*.doc"
ListFiles fldStart, Mask
'for each file in folder
'For Each fl In fldStart
' ListFiles fld, Mask
MsgBox ("Fin.")
'Next
End Sub
Sub ListFiles(fld As Object, Mask As String)
Dim runTracker As Integer
runTracker = 0
Dim fl As Object 'File
x = NewDoc 'generate new processed study guide
Dim sCheckDoc As String
Dim docRef As Document
Dim vFile As String
Dim arr() As String
'list of words to look for
sCheckDoc = "D:\testlist.docx"
Set docRef = Documents.Open(sCheckDoc)
docRef.Activate
'send docref to array split by newline
arr() = Split(docRef.Content.Text, Chr(13))
'begin word array loop?
For Each fl In fld.Files
runTracker = runTracker + 1
If fl.name Like Mask Then
'-----------------------------------------------------------------run
program code
vFile = fl.name 'set vFile = current file name
a = Documents.Open(fld.path & "\" & fl.name) 'open current search
file
Documents(vFile).Activate 'activate current search file
For a = 0 To UBound(arr)
'reset selection
selection.HomeKey Unit:=wdStory, Extend:=wdMove
'Inform progress
StatusBar = "Running Find..."
Dim docB As String
docB = Documents("Processed_StudyGuide.docx")
Dim docA As String
docA = Documents(vFile)
Documents(docA).Activate
b = DoFindReplace_Bkmk(arr(a))
'print bookmarked values to new document
StatusBar = "Printing targeted paragraphs..."
PrintBookmarks (bookmarkName)
If b <> 0 Then
'notify how many were inserted
MsgBox ("Complete, inserted: " & b & " bookmarks of " &
arr(a))
End If
Next a
MsgBox ("finished find in: " & vFile)
Documents(vFile).Close (wdDoNotSaveChanges)
'-----------------------------------------------------------------end
code
End If
Next
MsgBox ("Finished all documents")
End Sub
Function SelectQuestion(Index As Long)
'iniitial declaration
Dim linecount As Integer
Dim oPara As word.Paragraph
'Dim oPara As selection
Dim ListLevelNumber As Integer
Dim holder As Long
'if list type is simple numbering
If selection.Range.ListFormat.ListType = wdListSimpleNumbering Or
wdListBullet Or wdListMixedNumbering Then
'Select Whole Question containing word
With selection
.StartIsActive = False
.Extend Character:=";"
.EndKey
.StartOf (wdLine)
End With
a = selection.MoveUntil(";", wdBackward)
b = selection.MoveDown(wdLine, 2, wdMove)
selection.StartOf (wdLine)
selection.Find.Execute "*^13^13", , , True
'some correction of range- remove last paragraph from selection
'ActiveDocument.Range(selection.start, selection.End - 1).Select
End If
End Function
Function GetParNum(r As Range) As Integer
'determines paragraph number
GetParNum = selection.Range.ListFormat.ListValue
End Function
Function NewDoc() As String
'Generate new document and save
a = Documents.Add(, , , True)
ActiveDocument.Content.Delete
ActiveDocument.SaveAs2 ("D:\Processed_StudyGuide")
End Function
Public Function GetName(num As Integer) As String
'names each bookmark
Dim t As String
Dim nameArr() As Variant
nameArr = Array("a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "aa",
"bb", "cc", "dd", "ee", "ff", "gg", "hh", "ii", "jj", "kk", "ll", "mm",
"nn", "oo", "pp", "qq", "rr", "ss", "tt", "uu", "vv", "ww", "xx", "yy",
"zz", "aaa", "bbb", "ccc", "ddd", "eee", "fff", "ggg", "hhh", "iii", "jjj",
"kkk", "lll", "mmm", "nnn", "ooo", "ppp", "qqq", "rrr", "sss", "ttt", "uuu",
"vvv", "www", "xxx", "yyy", "zzz", "aaaa", "bbbb", "cccc", "dddd", "eeee",
"ffff", "gggg", "hhhh", "iiii", "jjjj", "kkkk", "llll", "mmmm", "nnnn",
"oooo", "pppp", "qqqq", "rrrr", "ssss", "tttt", "uuuu", "vvvv", "wwww",
"xxxx", "yyyy", "zzzz", "aaaaa", "bbbbb", "ccccc", "ddddd")
t = nameArr(num)
GetName = t
End Function
Function PrintBookmarks(name As String) 'Add each selection to collection
'Declarations
selection.Collapse
Dim n As Integer
Dim docB As String
docB = Documents("Processed_StudyGuide.docx")
Dim docA As String
docA = ActiveDocument.name
Dim x As Integer
x = ActiveDocument.Bookmarks.Count
Dim a As String
For Each bkmark In Documents(docA).Bookmarks
'If # of bookmarks is greater than 0 select the one at x
If x > 0 Then
With ActiveDocument.Bookmarks(x)
BkMkName = .name
.Select
End With
End If
'selection.Bookmarks(a).Select
SelectQuestion (GetParNum(selection.Range))
selection.Copy
selection.Collapse (wdCollapseEnd)
Documents("Processed_StudyGuide.docx").Activate
selection.MoveEnd
selection.Paste
'reactivate last document
Documents(docA).Activate
x = x - 1
Next
'runs bookmark removal
removebookmarks (docA)
Documents(docB).Activate 'activate processed study guide
' If ActiveDocument.Bookmarks.Count > 0 Then
' FixRepeatedQuestions
' End If
removebookmarks (docB)
ActiveDocument.Save
Documents(docA).Activate
End Function
Sub removebookmarks(name As String)
'removes bookmarks from documents
Dim bkm As Bookmark
For Each bkm In ActiveDocument.Bookmarks
bkm.Delete
Next bkm
End Sub
Function DoFindReplace_Bkmk(ByRef FindText As Variant, Optional ReplaceText
As String) As Integer
Dim i As Integer
i = 0
Dim bkmark As String
With selection.Find
'set Find Parameters
.ClearFormatting
.Replacement.ClearFormatting
.Text = FindText
'If replacement text is not supplied replace with targetword to find
If ReplaceText = "" Then
.Replacement.Text = FindText
Else
.Replacement.Text = ReplaceText
End If
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
Do While .Execute
'Keep going until nothing found
.Execute Replace:=wdReplaceAll
'keep track of how many are replaced
'get bookmark name and add bookmark at location
bookmarkName = GetName(i)
ActiveDocument.Bookmarks.Add name:=bookmarkName, Range:=selection.Range
i = i + 1 'below because array starts at 0
Loop
'Free up some memory
ActiveDocument.UndoClear
End With
'return # of find/replacements
DoFindReplace_Bkmk = i
End Function
For Each i In arr() can't work.
Your Arr() is a string and the Each enumeration only works for objects. You would have to use
For i = 0 to Ubound(Arr)
Next i
Here is the complete code for repetitive searching. Note that the TestCount function prints its output to VBE's Immediate window. If you don't see it, press Ctl+G or select it from the View menu, or change the output to a MsgBox.
Sub TestCount()
' testing procedure
Dim MyPhrase As String
MyPhrase = "International business"
Debug.Print "My phrase was found " & CountWords(MyPhrase) & " times."
End Sub
Function CountWords(Phrase As String) As Integer
' 12 Apr 2017
' return the number of occurences of words in document
Dim Fun As Integer ' Function return value
Dim Rng As Range
Set Rng = ActiveDocument.Content
Do
With Rng.Find
.ClearFormatting
.MatchCase = False
.Text = Phrase
.Execute
If Not .Found Then Exit Do
Fun = Fun + 1
End With
Loop
CountWords = Fun
End Function
For your understanding:-
Find always starts the search at the beginning of the range you set. At the start of the procedure the range is defined as ActiveDocument.Content.
When a match is found, the range is reset to hold only the found phrase, meaning Rng isn't the same as it was before.
The loop now repeats the search with the changed Rng object, again starting at the beginning of that range to the end of the document.
When no more match is found the loop is exited. It's important, not to Wrap because that property instructs Find to continue looking for matches at the beginning of the document when no match is found before its end.
In between, in the place where you now see Fun = Fun + 1, you could execute any code you like - perhaps call a sub there which makes major changes or even copies parts of the document to another document. The important thing is that, after you come back from all that work, the Rng pointer still holds that part of the document from where you want to continue your search.
O hope this will speed you on your way.

VBA issue with operators

I am facin strange problem looks like = is not working as it should be. I got code below:
Dim lineText As String
For Each p In WordDoc.Paragraphs
lineText = p.Range.Text
If lineText = "" Then GoTo Dalej
.....
even if i do:
lineText = ""
If lineText = "" Then GoTo Dalej
its not going to Dalej but going next. Looks like its not problem with code but with operators i got similar problem with <>. I tried to workaround tht with InStr or StrComp but its doing completly not as it should be like something inside excel has been changed with application itself. Do you have any idea what this could be?
This is full code:
Sub Sprawdz_Pola_Korespondencji_Click()
Application.ScreenUpdating = True
Dim RowNr As Integer
Dim EWS As Worksheet
RowNr = 30
Set EWS = Sheets("Arkusz do wypełnienia")
Dim FileName As Variant, wb As Workbook
FileName = Application.GetOpenFilename(FileFilter:="Word File (*.docx),*.docx", Title:="Select File To Be Opened")
If FileName = False Then Exit Sub
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = False
Set WordDoc = WordApp.Documents.Open(FileName)
Dim p As Paragraph
If lineText = "" Then GoTo Dalej
If InStr(lineText, PoleExcel) Then
EWS.Cells(5, X).Interior.ColorIndex = 18
Else
EWS.Cells(5, X).Interior.ColorIndex = 3
End If
Dalej:
Next p
Nastepna:
Loop Until EWS.Cells(RowNr, X) = "KONIEC"
'EWS.Activate 'WordDoc.Activate '<============================================================
WordDoc.Close savechanges:=False 'or false
WordApp.Quit
Set WordDoc = Nothing
Set WordApp = Nothing
End Sub
Public Function ReplaceSpaces(strInput As String) As String
' Replaces spaces in a string of text with underscores
Dim Result As String
Result = strInput
If InStr(strInput, " ") > 0 Then
Result = Replace(strInput, " ", "_")
End If
ReplaceSpaces = Result
End Function
You need to write:
Next p
Dalej:
instead. (i.e. switch round the Next p and Dalej:). Currently the label is inside the for loop.
But, it would be far better to use Exit For instead of the GoTo. Doing this means you don't need to maintain a label.
GoTo statements are notoriously brittle.
To strip out the CR do this:
lineText = replace(lineText, chr(13), "")

Split document and save each part as a file

I have a Word file that contains multiple people and their details.
I need to split this file into single files for each person.
This is the code, most of it is from examples I found.
I need to split the file by the delimiter (Personal).
Each file needs to be named by their ID number situated just below the delimiter.
Sub SplitNotes (delim As String)
Dim sText As String
Dim sValues(10) As String
Dim doc As Document
Dim arrNotes
Dim strFilename As String
Dim Test As String
Dim I As Long
Dim X As Long
Dim Response As Integer
arrNotes = Split(ActiveDocument.Range, delim)
Response = MsgBox("This will split the document into " & UBound(arrNotes) + 1 & " sections.Do you wish to proceed?", 4)
If Response = 7 Then Exit Sub
For I = LBound(arrNotes) To UBound(arrNotes)
If Trim(arrNotes(I)) <> "" Then
X = X + 1
Set doc = Documents.Add
doc.Range = arrNotes(I)
'Find "EID: "
doc.Range.Find.Text = "EID: "
'Select whole line
Selection.Expand wdLine
'Assign text to variable
sText = Selection.Text
'Remove spaces
sText = Replace(sText, " ", "")
'Split string into values
sValues = Split(sText, ":")
strFilename = "Testing"
doc.SaveAs ThisDocument.Path & "\" & strFilename & Format(X, "Agent")
doc.Close True
End If
Next I
End Sub
Sub Test()
'delimiter
SplitNotes "Name:"
End Sub
The Word document is set out as follows:
Personal
Name: John Smith
EID: Alph4num3r1c (Not a set length as i know of)
Details follow on from here
My problem is getting the ID number and using it in the save as function.
I don't have a complete understanding of how the split function works.
Split function splits a string into array of strings based on a delimeter.
For eg:
Dim csvNames, arrNames
csvNames = "Tom,Dick,Harry"
arrNames = split(csvNames,",")
Now arrNames is an array containing 3 elements. You can loop through the elements like this:
Dim i
For i = 0 to UBound(arrNames)
response.write arrNames(i) & "<br />"
Next
Now applying split function to solve your problem.
Read the line you are interested in into a variable. Lets say we have,
Dim lineWithID, arrKeyValuePair
lineWithID = "EID: Alph4num3r1c"
Split it into an array using colon
arrKeyValuePair = Split(lineWithID,":")
Now, arrKeyValuePair(1) will contain your EID
If your question is still valid I have some solution regarding file name you search.
I didn't check all part of your code (so I did but I don't have your original document to make full analysis). Back to file name- you could use below simple logic to extract name from newly created doc:
'...beginning of your code here
'next part unchanged >>
For I = LBound(arrNotes) To UBound(arrNotes)
If Trim(arrNotes(I)) <> "" Then
X = X + 1
Set doc = Documents.Add
doc.Range = arrNotes(I)
'<<until this moment
'remove or comment your code here!!
'and add new part of the code to search for the name
Selection.Find.Execute "EID:"
Selection.MoveRight wdWord, 1
Selection.Expand wdWord
strFilename = Trim(Selection.Text)
'and back to your code- unchanged
doc.SaveAs ThisDocument.Path & "\" & strFilename & Format(X, "Agent")
doc.Close True
End If
Next I
'...end of sub and other ending stuff
I check it and works quite ok for me.