![]() |
#1
|
|||
|
|||
![]()
I used attached vba for multiple Find and Replace, but unfortunately this does not work with Word 2013.
This is the link of the vba: http://gregmaxey.com/word_tip_pages/...d_replace.html I also tried the codes that you reported (https://www.msofficeforums.com/word-...html#post34254) but does not work with Word 2013. Could you please help with the correction of attached vba or your vba code so that it is compatible with Word 2013? Thank you and kind regards, Far |
#2
|
||||
|
||||
![]()
There is nothing about the code in either link you posted that is incompatible with Word 2013 - both work just fine with it.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#3
|
|||
|
|||
![]()
thank you very much.
I think I have configured it properly. When I run the macro, for a moment the excel file appears and then closes and then I asked the folder. I choose the folder, after a while I see that the files are up to date because the date and time is changed but when I check the word files I find no words changed! Perhaps there is some problem with the language or utf-8? The language of the word file is Persian. Thanks again Far |
#4
|
||||
|
||||
![]()
I believe the issues you are having with my macro are that the Excel data are stored for the Find/Replace as ASCII characters, but Persian requires the use of non-ASCII Unicode characters. You may get better results with:
Code:
Sub BulkFindReplace() Application.ScreenUpdating = True Dim strFolder As String, strFile As String, wdDoc As Document Dim StrWkBkNm As String, StrWkSht As String Dim xlApp As Object, xlWkBk As Object, xlWkSht As Object Dim bStrt As Boolean, bFound As Boolean, lRow As Long, i As Long StrWkBkNm = "C:\Users\" & Environ("Username") & "\Documents\Workbook Name.xls" StrWkSht = "Sheet1" If Dir(StrWkBkNm) = "" Then MsgBox "Cannot find the designated workbook: " & StrWkBkNm, vbExclamation Exit Sub End If 'Get the folder to process strFolder = GetFolder If strFolder = "" Then Exit Sub strFile = Dir(strFolder & "\*.doc", vbNormal) ' Test whether Excel is already running. On Error Resume Next bStrt = False ' Flag to record if we start Excel, so we can close it later. Set xlApp = GetObject(, "Excel.Application") 'Start Excel if it isn't running If xlApp Is Nothing Then Set xlApp = CreateObject("Excel.Application") If xlApp Is Nothing Then MsgBox "Can't start Excel.", vbExclamation Exit Sub End If ' Record that we've started Excel. bStrt = True End If On Error GoTo 0 'Check if the workbook is open. bFound = False With xlApp 'Hide our Excel session If bStrt = True Then .Visible = False For Each xlWkBk In .Workbooks If xlWkBk.FullName = StrWkBkNm Then ' It's open Set xlWkBk = xlWkBk bFound = True Exit For End If Next ' If not open by the current user. If bFound = False Then ' Check if another user has it open. If IsFileLocked(StrWkBkNm) = True Then ' Report and exit if true MsgBox "The Excel workbook is in use." & vbCr & "Please try again later.", vbExclamation, "File in use" If bStrt = True Then .Quit Exit Sub End If ' The file is available, so open it. Set xlWkBk = .Workbooks.Open(FileName:=StrWkBkNm) If xlWkBk Is Nothing Then MsgBox "Cannot open:" & vbCr & StrWkBkNm, vbExclamation If bStrt = True Then .Quit Exit Sub End If End If Set xlWkSht = xlWkBk.Worksheets(StrWkSht) lRow = xlWkSht.UsedRange.Cells(.Rows.Count, 1).End(-4162).Row ' -4162 = xlUp End With 'Process each document in the folder While strFile <> "" Set wdDoc = Documents.Open(FileName:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False) 'Process each word from the F/R List For i = 1 To lRow With wdDoc.Range With .Find .ClearFormatting .Replacement.ClearFormatting .MatchWholeWord = True .MatchCase = True .Wrap = wdFindStop .Text = Trim(xlWkSht.Range("A" & i).Value) .Replacement.Text = Trim(xlWkSht.Range("B" & i).Value) .Execute Replace:=wdReplaceAll End With End With Next 'Close the document wdDoc.Close SaveChanges:=True 'Get the next document strFile = Dir() Wend If bFound = False Then xlWkBk.Close False If bStrt = True Then xlApp.Quit ' Release Excel object memory Set xlWkBk = Nothing: Set xlApp = Nothing Application.ScreenUpdating = True End Sub Function GetFolder() As String Dim oFolder As Object GetFolder = "" Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0) If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path Set oFolder = Nothing End Function Function IsFileLocked(strFileName As String) As Boolean On Error Resume Next Open strFileName For Binary Access Read Write Lock Read Write As #1 Close #1 IsFileLocked = Err.Number Err.Clear End Function
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#5
|
|||
|
|||
![]()
Ok. Now I tried again and it worked, but it works partially. Attached sending the cases that do not work. When at the beginning or at the end there is "No-width optional break" and does not work with numbers.
|
#6
|
||||
|
||||
![]()
At least some of the issues you're having, especially with numbers, are because the code uses ".MatchWholeWord = True". Without this, there would be a significant risk that some of your other Find/Replace expressions would be updating parts of words. That may also explain why it doesn't work with "No-width optional break" text. I don't understand why you'd bother with rows 5-11, since the Find & Replace text is the same for each of them. For the remainder, you might use a separate worksheet and run a separate Find/Replace without the ".MatchWholeWord = True".
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#7
|
|||
|
|||
![]()
Thank you Paul.
Ok. The items within the lines 5 and 11 are not the same. Line 5 is to remove the white space at the end of a paragraph, and line 11 is to remove the white space between the opening parenthesis and the blank space before the closing parenthesis. Another question: I often have to do Find & Replace only within the file that is opend, I would like to know how I could modify the code without saving the file and then go on to do Find & Replace? Thanks |
#8
|
||||
|
||||
![]()
Try replacing the previous code with the following, which should suffice for doing bulk replacements or just the active document, plus the data on both worksheets:
Code:
Option Explicit Dim strFolder As String, strFile As String, wdDoc As Document, i As Long Dim xlApp As Object, xlWkBk As Object, bStrt As Boolean, bFound As Boolean Dim xlFList1, xlRList1, xlFList2, xlRList2, lRow As Long, StrWkBkNm As String Const StrWkSht1 As String = "Sheet1": Const StrWkSht2 As String = "Sheet2" Sub ActiveDocFindReplace() Application.ScreenUpdating = False StrWkBkNm = "C:\Users\" & Environ("Username") & "\Documents\BulkFindReplace.xls" If Dir(StrWkBkNm) = "" Then MsgBox "Cannot find the designated workbook: " & StrWkBkNm, vbExclamation Exit Sub End If 'Get the Find/Replace Data Call GetData 'Process the document Call UpdateDoc(ActiveDocument) Application.ScreenUpdating = True End Sub Sub MultiDocFindReplace() Application.ScreenUpdating = False StrWkBkNm = "C:\Users\" & Environ("Username") & "\Documents\BulkFindReplace.xls" If Dir(StrWkBkNm) = "" Then MsgBox "Cannot find the designated workbook: " & StrWkBkNm, vbExclamation Exit Sub End If 'Get the folder to process strFolder = GetFolder If strFolder = "" Then Exit Sub strFile = Dir(strFolder & "\*.doc", vbNormal) 'Get the Find/Replace Data Call GetData 'Process each document in the folder While strFile <> "" Set wdDoc = Documents.Open(FileName:=strFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False) Call UpdateDoc(wdDoc) 'Close & save the document wdDoc.Close SaveChanges:=True 'Get the next document strFile = Dir() Wend Application.ScreenUpdating = True End Sub Function GetFolder() As String Dim oFolder As Object GetFolder = "" Set oFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Choose a folder", 0) If (Not oFolder Is Nothing) Then GetFolder = oFolder.Items.Item.Path Set oFolder = Nothing End Function Function IsFileLocked(strFileName As String) As Boolean On Error Resume Next Open strFileName For Binary Access Read Write Lock Read Write As #1 Close #1 IsFileLocked = Err.Number Err.Clear End Function Private Sub GetData() ' Test whether Excel is already running. On Error Resume Next bStrt = False ' Flag to record if we start Excel, so we can close it later. Set xlApp = GetObject(, "Excel.Application") 'Start Excel if it isn't running If xlApp Is Nothing Then Set xlApp = CreateObject("Excel.Application") If xlApp Is Nothing Then MsgBox "Can't start Excel.", vbExclamation Exit Sub End If ' Record that we've started Excel. bStrt = True End If On Error GoTo 0 'Check if the workbook is open. bFound = False With xlApp 'Hide our Excel session If bStrt = True Then .Visible = False For Each xlWkBk In .Workbooks If xlWkBk.FullName = StrWkBkNm Then ' It's open Set xlWkBk = xlWkBk bFound = True Exit For End If Next ' If not open by the current user. If bFound = False Then ' Check if another user has it open. If IsFileLocked(StrWkBkNm) = True Then ' Report and exit if true MsgBox "The Excel workbook is in use." & vbCr & "Please try again later.", vbExclamation, "File in use" If bStrt = True Then .Quit Exit Sub End If ' The file is available, so open it. Set xlWkBk = .Workbooks.Open(FileName:=StrWkBkNm) If xlWkBk Is Nothing Then MsgBox "Cannot open:" & vbCr & StrWkBkNm, vbExclamation If bStrt = True Then .Quit Exit Sub End If End If 'Initialize the F/R Lists xlFList1 = "": xlRList1 = "": xlFList2 = "": xlRList2 = "" ' Process the workbook. With xlWkBk.Worksheets(StrWkSht1).UsedRange ' Find the last-used row. lRow = .Rows.Count ' Output the captured data. For i = 1 To lRow ' Skip over empty fields to preserve the underlying cell contents. If Trim(.Range("A" & i)) <> vbNullString Then xlFList1 = xlFList1 & "|" & Trim(.Range("A" & i)) xlRList1 = xlRList1 & "|" & Trim(.Range("B" & i)) End If Next End With With xlWkBk.Worksheets(StrWkSht2).UsedRange ' Find the last-used row. lRow = .Rows.Count ' Output the captured data. For i = 1 To lRow ' Skip over empty fields to preserve the underlying cell contents. If Trim(.Range("A" & i)) <> vbNullString Then xlFList2 = xlFList2 & "|" & .Range("A" & i) xlRList2 = xlRList2 & "|" & .Range("B" & i) End If Next End With If bFound = False Then xlWkBk.Close False If bStrt = True Then .Quit End With ' Release Excel object memory Set xlWkBk = Nothing: Set xlApp = Nothing End Sub Sub UpdateDoc(wdDoc As Document) With wdDoc.Range.Find .ClearFormatting .Replacement.ClearFormatting .MatchWholeWord = True .MatchCase = True .Wrap = wdFindContinue 'Process each word from the 1st F/R List For i = 1 To UBound(Split(xlFList1, "|")) .Text = Split(xlFList1, "|")(i) .Replacement.Text = Split(xlRList1, "|")(i) .Execute Replace:=wdReplaceAll Next .MatchWholeWord = False .MatchCase = False 'Process each word from the 2nd F/R List For i = 1 To UBound(Split(xlFList2, "|")) .Text = Split(xlFList2, "|")(i) .Replacement.Text = Split(xlRList2, "|")(i) .Execute Replace:=wdReplaceAll Next 'Process digits For i = 0 To 9 .Text = Chr(48 + i) .Replacement.Text = ChrW(1776 + i) .Execute Replace:=wdReplaceAll Next End With End Sub There are now just two subs that you run, either (a) ActiveDocFindReplace; or (b) MultiDocFindReplace.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#9
|
|||
|
|||
![]()
Thank you Paul.
It works magnificently. Thanks |
#10
|
|||
|
|||
![]()
Hello Paul,
I have some problems with this code: 1 - it is possible that the language in the code is configured to arbic language? Because I do not change the letter K. In Arabic is ك but in Persian is ک and the code does not replace it. 2 - The code is very heavy and it takes a long time to process the file. I would also like to know how I can modify the code to be able to do Find & Replace in the html files? Thank you very much |
#11
|
||||
|
||||
![]()
Hi Far,
1. I am not aware of anything to do with the use of Arabic or Persian that would affect the macro. In any event, when I run the macro with the workbook you supplied, ك is replaced by ک. 2. If you have many terms and a large document, processing may seem slow, but there is nothing that can be done to make the code run faster, except for getting a faster computer. The code is already about as efficient as it is possible to make it. 3. Except for the file extension, the code should not need any modification to work with html files. If you want to be able to process files that don't have a .doc, .docx or .docm extension, change '.doc' in 'strFile = Dir(strFolder & "\*.doc", vbNormal)' to match whatever file type you want to process. For example, 'strFile = Dir(strFolder & "\*.html", vbNormal)'.
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
#12
|
|||
|
|||
![]()
Thank you very much.
yes, you're right. The code also works with K. I made a mistake with a setting of the file. Cheers |
![]() |
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
![]() |
Roscoe | Word VBA | 7 | 07-31-2017 04:02 PM |
Find and replace No longer work | TJH | Word | 3 | 03-25-2014 11:33 PM |
![]() |
paddit | Outlook | 1 | 11-06-2013 02:39 PM |
![]() |
dalyght | Word | 8 | 05-29-2013 12:19 PM |
![]() |
redhin | Word VBA | 5 | 03-05-2013 05:42 AM |