Getting wend without while error: I am trying to extract paragraph with particular keyword and Color from Doc to Excel.
Keywords for a paragraph is written in Sheet 1 row 2 to last row.
Next Paragraph with a keyword is extracted in Sheet2.
I will get a wend without while error when I try to get a paragraph with particular color after the keyword.
Code:
Sub LocateSearchItem()
Dim shtSearchItem As Worksheet
Dim shtExtract As Worksheet
Dim oWord As Word.Application
Dim WordNotOpen As Boolean
Dim oDoc As Word.Document
Dim oRange As Word.Range
Dim LastRow As Long
Dim CurrRowShtSearchItem As Long
Dim CurrRowShtExtract As Long
Dim myPara As Long
Dim myPara1 As Long
Dim I As Long
On Error Resume Next
Set oWord = GetObject(, "Word.Application")
Set oWord = New Word.Application
If Err Then
Set oWord = New Word.Application
WordNotOpen = True
End If
On Error GoTo Err_Handler
oWord.Visible = True
oWord.Activate
Set oDoc = oWord.Documents.Open("C:\CC-SyPRS\Automating Verification activity\Work in Progress\Test.docx")
Set shtSearchItem = ThisWorkbook.Worksheets(1)
If ThisWorkbook.Worksheets.Count < 2 Then
ThisWorkbook.Worksheets.Add After:=shtSearchItem
End If
Set shtExtract = ThisWorkbook.Worksheets(2)
LastRow = shtSearchItem.UsedRange.Rows(shtSearchItem.UsedRange.Rows.Count).Row
For CurrRowShtSearchItem = 2 To LastRow
Set oRange = oDoc.Range
With oRange.Find
.Text = shtSearchItem.Cells(CurrRowShtSearchItem, 1).Text
.MatchCase = False
.MatchWholeWord = True
While oRange.Find.Execute = True
oRange.Select
myPara = oDoc.Range(0, oWord.Selection.Paragraphs(1).Range.End).Paragraphs.Count
myPara1 = myPara + 1
Set objParagraph = oDoc.Paragraphs(myPara1).Range
For I = 1 To 5
If objParagraph.Font.ColorIndex = wdGreen Then
shtExtract.Cells(CurrRowShtExtract, 2) = oDoc.Paragraphs(myPara1).Range
Else
I = I + 1
myPara1 = myPara + I
End If
CurrRowShtExtract = CurrRowShtExtract + 1
oRange.Collapse wdCollapseEnd
Wend
End With
Next CurrRowShtSearchItem
If WordNotOpen Then
oWord.Quit
End If
'Release object references
Set oWord = Nothing
Set oDoc = Nothing
Exit Sub
Err_Handler:
MsgBox "Word caused a problem. " & Err.Description, vbCritical, "Error: " & Err.Number
If WordNotOpen Then
oWord.Quit
End If
End Sub
This is why proper indentation is really useful.
Sub LocateSearchItem()
Dim shtSearchItem As Worksheet
Dim shtExtract As Worksheet
Dim oWord As Word.Application
Dim WordNotOpen As Boolean
Dim oDoc As Word.Document
Dim oRange As Word.Range
Dim LastRow As Long
Dim CurrRowShtSearchItem As Long
Dim CurrRowShtExtract As Long
Dim myPara As Long
Dim myPara1 As Long
Dim I As Long
On Error Resume Next
Set oWord = GetObject(, "Word.Application")
Set oWord = New Word.Application
If Err Then
Set oWord = New Word.Application
WordNotOpen = True
End If
On Error GoTo Err_Handler
oWord.Visible = True
oWord.Activate
Set oDoc = oWord.Documents.Open("C:\CC-SyPRS\Automating Verification activity\Work in Progress\Test.docx")
Set shtSearchItem = ThisWorkbook.Worksheets(1)
If ThisWorkbook.Worksheets.Count < 2 Then
ThisWorkbook.Worksheets.Add After:=shtSearchItem
End If
Set shtExtract = ThisWorkbook.Worksheets(2)
LastRow = shtSearchItem.UsedRange.Rows(shtSearchItem.UsedRange.Rows.Count).Row
For CurrRowShtSearchItem = 2 To LastRow
Set oRange = oDoc.Range
With oRange.Find
.Text = shtSearchItem.Cells(CurrRowShtSearchItem, 1).Text
.MatchCase = False
.MatchWholeWord = True
While oRange.Find.Execute = True
oRange.Select
myPara = oDoc.Range(0, oWord.Selection.Paragraphs(1).Range.End).Paragraphs.Count
myPara1 = myPara + 1
Set objParagraph = oDoc.Paragraphs(myPara1).Range
For I = 1 To 5
If objParagraph.Font.ColorIndex = wdGreen Then
shtExtract.Cells(CurrRowShtExtract, 2) = oDoc.Paragraphs(myPara1).Range
Else
I = I + 1
myPara1 = myPara + I
End If
CurrRowShtExtract = CurrRowShtExtract + 1
oRange.Collapse wdCollapseEnd
' Oops! No closing tag for the 'For' statement. Add 'Next I' here
Wend
End With
Next CurrRowShtSearchItem
If WordNotOpen Then
oWord.Quit
End If
'Release object references
Set oWord = Nothing
Set oDoc = Nothing
Exit Sub
Err_Handler:
MsgBox "Word caused a problem. " & Err.Description, vbCritical, "Error: " & Err.Number
If WordNotOpen Then
oWord.Quit
End If
End Sub
The error message is quite misleading anyway, as #freeflow mentioned
By the way, you have a With on line 41, which is not closed on line 45. As you do not use the Find object anymore, you can close it and start the while loop separately.
Related
I have a Word file that has table with 5 columns: Step, Document, Doc #, Compo and Lot #, Sign, Date. I need to search for "Lot #" and "E#" in the word file then get the Step number, the text of row contains the string into an Excel file. I found a code that need to have the keywords in Sheet 1 of Excel then extract the data from Word into Sheet 2 with 1st column as keyword, 2nd column as row number in Word and 3rd column is the text of that row.
Is there any way I can hard code the keywords with options/message box to choose the keyword into VBA module instead of Sheet 1 and get the data in Sheet 1 with 1st column as keyword, 2nd column as the value in Step column in Word and 3rd column is the text of that row?
I'm pretty new to VBA so I don't know how to implement those.
Sub LocateSearchItem()
Dim shtSearchItem As Worksheet
Dim shtExtract As Worksheet
Dim oWord As Word.Application
Dim WordNotOpen As Boolean
Dim oDoc As Word.Document
Dim oRange As Word.Range
Dim LastRow As Long ' last row with data in shtSearchItem
Dim CurrRowShtSearchItem As Long ' current row in shtSearchItem
Dim CurrRowShtExtract As Long ' current row in shtExtract
Dim myPara As Long
On Error Resume Next
Set oWord = GetObject(, "Word.Application")
wdFileName = Application.GetOpenFilename("Word files (*.docx),*.docx", , _
"Browse for file containing table to be imported")
If wdFileName = False Then Exit Sub '(user cancelled import file browser)
Set oDoc = GetObject(wdFileName) 'open Word file
If Err Then
Set oWord = New Word.Application
WordNotOpen = True
End If
On Error GoTo Err_Handler
oWord.Visible = True
oWord.Activate
Set shtSearchItem = ThisWorkbook.Worksheets(1)
If ThisWorkbook.Worksheets.Count < 2 Then
ThisWorkbook.Worksheets.Add After:=shtSearchItem
End If
Set shtExtract = ThisWorkbook.Worksheets(2)
LastRow = shtSearchItem.UsedRange.Rows(shtSearchItem.UsedRange.Rows.Count).Row
For CurrRowShtSearchItem = 2 To LastRow
Set oRange = oDoc.Range
With oRange.Find
.Text = shtSearchItem.Cells(CurrRowShtSearchItem, 1).Text
.MatchCase = False
.MatchWholeWord = True
While oRange.Find.Execute = True
oRange.Select
myPara = oDoc.Range(0, oWord.Selection.Paragraphs(1).Range.End).Paragraphs.Count
CurrRowShtExtract = CurrRowShtExtract + 1
shtExtract.Cells(CurrRowShtExtract, 1).Value = .Text
shtExtract.Cells(CurrRowShtExtract, 2).Value = myPara
shtExtract.Cells(CurrRowShtExtract, 3) = oDoc.Paragraphs(myPara).Range
oRange.Collapse wdCollapseEnd
Wend
End With
Next CurrRowShtSearchItem
If WordNotOpen Then
oWord.Quit
End If
'Release object references
Set oWord = Nothing
Set oDoc = Nothing
Exit Sub
Err_Handler:
MsgBox "Word caused a problem. " & Err.Description, vbCritical, "Error: " & Err.Number
If WordNotOpen Then
oWord.Quit
End If
End Sub
What I got from the current code
I am trying to extract the page number from where a word is find. This is my current code:
Sub LocateSearchItem()
Dim shtSearchItem As Worksheet
Dim shtExtract As Worksheet
Dim oWord As Word.Application
Dim WordNotOpen As Boolean
Dim oDoc As Word.Document
Dim oRange As Word.Range
Dim LastRow As Long
Dim CurrentRowShtSearchItem As Long
Dim CurrentRowShtExtract As Long
Dim myPara As Long
On Error Resume Next
Set oWord = GetObject(, "Word.Application")
If Err Then
Set oWord = New Word.Application
WordNotOpen = True
End If
On Error GoTo Err_Handler
oWord.Visible = True
oWord.Activate
Set oDoc = oWord.Documents.Open("C:\Users\Moham\Desktop\mydocx.docx")
Set shtSearchItem = ThisWorkbook.Worksheets(1)
If ThisWorkbook.Worksheets.Count < 2 Then
ThisWorkbook.Worksheets.Add After:=shtSearchItem
End If
Set shtExtract = ThisWorkbook.Worksheets(2)
LastRow = shtSearchItem.UsedRange.Rows(shtSearchItem.UsedRange.Rows.Count).Row
For CurrRowShtSearchItem = 2 To LastRow
Set oRange = oDoc.Range
With oRange.Find
.Text = shtSearchItem.Cells(CurrRowShtSearchItem, 1).Text
.MatchCase = False
.MatchWholeWord = True
While oRange.Find.Execute = True
oRange.Select
'This is the important part
myPara = oDoc.Range(0, oWord.Selection.Paragraphs(1).Range.End).Paragraphs.Count
CurrRowShtExtract = CurrRowShtExtract + 1
shtExtract.Cells(CurrRowShtExtract, 1).Value = .Text
shtExtract.Cells(CurrRowShtExtract, 2).Value = myPara
shtExtract.Cells(CurrRowShtExtract, 3) = oDoc.Paragraphs(myPara).Range
oRange.Collapse wdCollapseEnd
Wend
End With
Next CurrRowShtSearchItem
If WordNotOpen Then
oWord.Quit
End If
Set oWord = Nothing
Set oDoc = Nothing
Exit Sub
Err_Handler:
MsgBox "Word caused a problem. " & Err.Description, vbCritical, "Error: " & Err.Number
If WordNotOpen Then
oWord.Quit
End If
End Sub
I am not able to find the page number element in oDoc.
How to get the page number of that paragraph? Also currently the paragraph counts even the titles. Is there a way to avoid counting titles as well as counting blank paragraphs?
For example, currently it says the "Hello daniel" to be in para 5.
HELLO ---> Format Title
hi there all ----> para 2
this is your professor ----->para 3
-------> para 4
say hello to him ------------->para 5
Hello Daniel --------------> para 6
It should actually say para 4 because the first line is title and there is one empty para above "say hello to him" para.
I found this VBA Outlook code that meets my purpose in theory. objHyperlink seems to return Nothing when I debug.
The outputs are always empty and during debug I get
Runtime error: "13" and Type mismatch
at the line - For Each objHyperlink In objMailDocument.Hyperlinks
Dim objExcelApp As Excel.Application
Dim objExcelWorkbook As Excel.Workbook
Dim objExcelWorksheet As Excel.Worksheet
Sub ExportAllHyperlinksInMultipleEmailsToExcel()
Dim objSelection As Selection
Dim objMail As MailItem
Dim objMailDocument As Document
Dim objHyperlink As Hyperlink
Dim i As Long
Set objSelection = Outlook.Application.ActiveExplorer.Selection
If Not (objSelection Is Nothing) Then
Set objExcelApp = CreateObject("Excel.Application")
Set objExcelWorkbook = objExcelApp.Workbooks.Add
Set objExcelWorksheet = objExcelWorkbook.Sheets(1)
objExcelApp.Visible = True
objExcelWorkbook.Activate
With objExcelWorksheet
.Cells(1, 1) = "Email"
.Cells(1, 2) = "Text"
.Cells(1, 3) = "Link"
.Cells(1, 4) = "Source"
End With
i = 0
For Each objMail In objSelection
Set objMailDocument = objMail.GetInspector.WordEditor
If objMailDocument.Hyperlinks.Count > 0 Then <- Correct # of links shown here
For Each objHyperlink In objMailDocument.Hyperlinks <- Debug highlights this
If InStr(objHyperlink.Address, "www.") > 0 Then
i = i + 1
Call ExportToExcel(i, objMail, objHyperlink)
End If
Next
End If
objMail.Close olDiscard
Next
objExcelWorksheet.Columns("A:D").AutoFit
End If
End Sub
Sub ExportToExcel(n As Long, objCurrentMail As MailItem, objCurrentHyperlink As Hyperlink)
Dim nLastRow As Integer
nLastRow = objExcelWorksheet.Range("A" & objExcelWorksheet.Rows.Count).End(xlUp).Row + 1
objExcelWorksheet.Range("A" & nLastRow) = n
objExcelWorksheet.Range("B" & nLastRow) = objCurrentHyperlink.TextToDisplay
objExcelWorksheet.Range("C" & nLastRow) = objCurrentHyperlink.Address
objExcelWorksheet.Range("D" & nLastRow) = objCurrentMail.Subject
End Sub
Thanks to #CDP1802 for pointing out a couple of changes to try. This does work with the following code:
Dim objExcelApp As Excel.Application
Dim objExcelWorkbook As Excel.Workbook
Dim objExcelWorksheet As Excel.Worksheet
Sub ExportAllHyperlinksInMultipleEmailsToExcel()
Dim objSelection As Selection
Dim objMail As MailItem
Dim objMailDocument As Word.Document << Added Word. here
Dim objHyperlink As Word.Hyperlink << Added Word. here
Dim i As Long
Set objSelection = Outlook.Application.ActiveExplorer.Selection
If Not (objSelection Is Nothing) Then
Set objExcelApp = CreateObject("Excel.Application")
Set objExcelWorkbook = objExcelApp.Workbooks.Add
Set objExcelWorksheet = objExcelWorkbook.Sheets(1)
objExcelApp.Visible = True
objExcelWorkbook.Activate
With objExcelWorksheet
.Cells(1, 1) = "Email"
.Cells(1, 2) = "Text"
.Cells(1, 3) = "Link"
.Cells(1, 4) = "Source"
End With
i = 0
For Each objMail In objSelection
Set objMailDocument = objMail.GetInspector.WordEditor
If objMailDocument.Hyperlinks.Count > 0 Then
For Each objHyperlink In objMailDocument.Hyperlinks
If InStr(objHyperlink.Address, "www.") > 0 Then
i = i + 1
Call ExportToExcel(i, objMail, objHyperlink)
End If
Next
End If
objMail.Close olDiscard
Next
objExcelWorksheet.Columns("A:D").AutoFit
End If
End Sub
Sub ExportToExcel(n As Long, objCurrentMail As MailItem, objCurrentHyperlink As Word.Hyperlink) << Added Word. here
Dim nLastRow As Integer
nLastRow = objExcelWorksheet.Range("A" & objExcelWorksheet.Rows.Count).End(xlUp).Row + 1
objExcelWorksheet.Range("A" & nLastRow) = n
objExcelWorksheet.Range("B" & nLastRow) = objCurrentHyperlink.TextToDisplay
objExcelWorksheet.Range("C" & nLastRow) = objCurrentHyperlink.Address
objExcelWorksheet.Range("D" & nLastRow) = objCurrentMail.Subject
End Sub
I am having an excel with two columns Requirement and Source. I have another Word document with Requirement which are there in excel. I want it to be matched. If it is matched then its corresponding source need to be sent to Requirement in word document.
The excel file data:
In the word document the data should be displayed like this:
enter image description here
I tried in this way:
Sub SearchItem()
Dim shtSearchItem As Worksheet
Dim shtExtract As Worksheet
Dim oWord As Word.Application
Dim WordNotOpen As Boolean
Dim oDoc As Word.Document
Dim oRange As Word.Range
Dim LastRow As Long
Dim CurrRowShtSearchItem As Long
Dim CurrRowShtExtract As Long
Dim myPara As Long
On Error Resume Next
Set oWord = GetObject(, "Word.Application")
If Err Then
Set oWord = New Word.Application
WordNotOpen = True
End If
On Error GoTo Err_Handler
oWord.Visible = True
oWord.Activate
Set oDoc = oWord.Documents.Open("File Location")
Set shtSearchItem = ThisWorkbook.Worksheets(1)
If ThisWorkbook.Worksheets.Count < 2 Then
ThisWorkbook.Worksheets.Add After:=shtSearchItem
End If
Set shtExtract = ThisWorkbook.Worksheets(2)
LastRow = shtSearchItem.UsedRange.Rows(shtSearchItem.UsedRange.Rows.Count).Row
For CurrRowShtSearchItem = 2 To LastRow
Set oRange = oDoc.Range
With oRange.Find
.Text = shtSearchItem.Cells(CurrRowShtSearchItem, 1).Text
.MatchCase = False
.MatchWholeWord = True
While oRange.Find.Execute = True
oRange.Select
If .Found Then
oRange.InsertAfter ("Reference" & ":") ' <= what need to be done?
End If
oRange.Start = oRange.End
oRange.End = ActiveDocument.Range.End
oRange.Collapse wdCollapseEnd
Wend
End With
Next CurrRowShtSearchItem
If WordNotOpen Then
oWord.Quit
End If
'Release object references
Set oWord = Nothing
Set oDoc = Nothing
Exit Sub
Err_Handler:
MsgBox "Word caused a problem. " & Err.Description, vbCritical, "Error: " & Err.Number
If WordNotOpen Then
oWord.Quit
End If
End Sub
Please Help. Thank You
Try something based on:
Sub SendRefsToDoc()
'Note: A reference to the Word library must be set, via Tools|References
Dim wdApp As New Word.Application, wdDoc As Word.Document, StrNm As String
Dim r As Long, xlFList As String, xlRList As String
StrNm = "C:\Users\" & Environ("UserName") & "\Documents\MyDocument.docx"
If Dir(StrNm) <> "" Then
With Worksheets("Sheet1")
For r = 2 To .Cells(.Rows.Count, 1).End(xlUp).Row
If .Range("A" & r).Text = "" Then
xlRList = xlRList & ", " & Trim(.Range("B" & r))
Else
xlFList = xlFList & "|" & Trim(.Range("A" & r))
xlRList = xlRList & "|" & Trim(.Range("B" & r))
End If
Next
End With
With wdApp
.Visible = False
Set wdDoc = Documents.Open(Filename:=StrNm, AddToRecentFiles:=False, Visible:=False)
With wdDoc
For r = 1 To UBound(Split(xlFList, "|"))
With .Range
With .Find
.Replacement.ClearFormatting
.Text = Split(xlFList, "|")(r)
.Replacement.Text = ""
.Forward = True
.Format = False
.Wrap = wdFindStop
End With
Do While .Find.Execute
.Paragraphs.First.Range.Characters.Last.InsertBefore vbCr _
& "Reference: " & Split(xlRList, "|")(r)
With .Paragraphs.First.Range.Font
.Bold = True
.Italic = True
End With
With .Paragraphs.Last.Range.Font
.Bold = False
.Italic = False
End With
.Collapse wdCollapseEnd
Loop
End With
Next
.Close True
End With
.Quit
End With
Else
MsgBox "File not found: " & vbCr & StrNm, vbExclamation
End If
Set wdDoc = Nothing: Set wdApp = Nothing
End Sub
I am working on an Excel workbook in which I would like the workbook to create a new sheet for each new row of data. The code below does do this, but the problem is that Excel uses the text in the first column of each row as the name for the new sheets. I would like to change this and make another column the source for the new sheet name. Please advise on which line(s) I would need to change to accomplish this. Thanks for the help!
Sub Parse_data()
Dim xRCount As Long
Dim xSht As Worksheet, xNSht As Worksheet
Dim I As Long
Dim xTRrow As Integer
Dim xCol As New Collection
Dim xTitle As String
Dim xSUpdate As Boolean
Set xSht = ActiveSheet
xRCount = xSht.Cells(xSht.Rows.Count, 1).End(xlUp).Row
'xTitle = "C1:C1"
'xTRrow = xSht.Range(xTitle).Cells(1).Row
For I = 2 To xRCount
On Error Resume Next
Call xCol.Add(xSht.Cells(I, 1), xSht.Cells(I, 1))
Next
On Error Resume Next
xSUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
For I = 1 To xCol.Count
Call xSht.Range(xTitle).AutoFilter(1, CStr(xCol.Item(I)))
Set xNSht = Nothing
Set xNSht = Worksheets(CStr(xCol.Item(I)))
If xNSht Is Nothing Then
Set xNSht = Worksheets.Add(, Sheets(Sheets.Count))
xNSht.Name = CStr(xCol.Item(I))
Else
xNSht.Move , Sheets(Sheets.Count)
End If
xSht.Range("A" & xTRrow & ":A" & xRCount).EntireRow.Copy xNSht.Range("A1")
xNSht.Columns.AutoFit
Next
xSht.AutoFilterMode = False
xSht.Activate
Application.ScreenUpdating = xSUpdate
End Sub
Try this. I added another collection, yCol, which contains data from a different column but which uses the same key as xCol.
Sub Parse_data()
Dim xRCount As Long
Dim xSht As Worksheet, xNSht As Worksheet
Dim I As Long
Dim xTRrow As Integer
Dim xCol As New Collection
Dim yCol as New Collection
Dim xTitle As String
Dim xSUpdate As Boolean
Set xSht = ActiveSheet
xRCount = xSht.Cells(xSht.Rows.Count, 1).End(xlUp).Row
'xTitle = "C1:C1"
'xTRrow = xSht.Range(xTitle).Cells(1).Row
For I = 2 To xRCount
On Error Resume Next
Call xCol.Add(xSht.Cells(I, 1), xSht.Cells(I, 1))
Call yCol.Add(xSht.Cells(I, 2), xSht.Cells(I, 1)) 'change 2 to whatever column you want as the name
Next
On Error Resume Next
xSUpdate = Application.ScreenUpdating
Application.ScreenUpdating = False
For I = 1 To xCol.Count
Call xSht.Range(xTitle).AutoFilter(1, CStr(xCol.Item(I)))
Set xNSht = Nothing
Set xNSht = Worksheets(CStr(xCol.Item(I)))
If xNSht Is Nothing Then
Set xNSht = Worksheets.Add(, Sheets(Sheets.Count))
xNSht.Name = CStr(yCol.Item(I)) 'here's my magic switcheroo
Else
xNSht.Move , Sheets(Sheets.Count)
End If
xSht.Range("A" & xTRrow & ":A" & xRCount).EntireRow.Copy xNSht.Range("A1")
xNSht.Columns.AutoFit
Next
xSht.AutoFilterMode = False
xSht.Activate
Application.ScreenUpdating = xSUpdate
End Sub