![]() |
|
#1
|
|||
|
|||
|
Hello all. I think that this should be fairly easy to do, but I cannot find the answer anywhere. I have a document with several tables in it, and each table has a unique bookmark name. From Access, I want to loop through all tables in my word document and look for a particular table with a certain bookmark name. Lets say that the bookmark name of the table is MyTable. I am writing some sample code below, but I know that it isn't correct. What is the correct structure?
Code:
For Each tbl In doc.Tables
If tbl.Rows.Count > 1 And tbl.Range.Bookmark.Text = "MyTable" Then
David |
|
#2
|
||||
|
||||
|
Instead of looking at the tables, look for the bookmark e.g.
Code:
Sub Macro1()
Dim wdApp As Object
Dim oDoc As Object
Dim oBM As Object
Dim bBM As Boolean
Dim oTable As Object
Const strBookmarkName As String = "MyTable"
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
If Err Then
Set wdApp = CreateObject("Word.Application")
End If
Set wdDoc = wdApp.Documents.Open("Full path of document")
For Each oBM In oDoc.Bookmarks
If oBM.name = strBookmarkName Then
If oBM.Range.Information(12) Then
Set oTable = oBM.Range.Tables(1)
bBM = True
'do what you want with oTable e.g.
oTable.Range.Select
End If
Exit For
End If
Next oBM
If Not bBM Then MsgBox ("Bookmark '" & strBookmarkName & "' not present in the document.")
lbl_Exit:
Set oBM = Nothing
Set oTable = Nothing
Set oDoc = Nothing
Set wdApp = Nothing
Exit Sub
End Sub
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
|
#3
|
|||
|
|||
|
Thanks so much. That does make sense. I also marked your response as answered at answers.microsoft.com.
|
|
#4
|
|||
|
|||
|
Graham,
Am I missing something? Why did you loop through the bookmarks? Code:
Sub Macro1()
Dim wdApp As Object
Dim oDoc As Object
Dim oBM As Object
Dim bBM As Boolean
Dim oTable As Object
Const strBookmarkName As String = "MyTable"
On Error Resume Next
Set wdApp = GetObject(, "Word.Application")
If Err Then
Set wdApp = CreateObject("Word.Application")
Err.Clear
End If
Set wdDoc = wdApp.Documents.Open("Full path of document")
Set oBM = oDoc.Bookmarks(strBookmarkName)
If Err.Number <> 0 Then
MsgBox ("Bookmark '" & strBookmarkName & "' not present in the document.")
Else
If oBM.Range.Information(12) Then
Set oTable = oBM.Range.Tables(1)
'do what you want with oTable e.g.
oTable.Range.Select
End If
End If
lbl_Exit:
Set oBM = Nothing
Set oTable = Nothing
Set oDoc = Nothing
Set wdApp = Nothing
Exit Sub
End Sub
|
|
#5
|
||||
|
||||
|
If you are looking for a bookmark then surely it makes sense to look in the bookmark list for that bookmark, then ask which table it is associated with, rather than trawl through an unknown number of tables looking for a table that contains a bookmark?
Either would work, but I would contend that looking for the bookmark name directly is potentially faster.
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
|
#6
|
|||
|
|||
|
Graham,
I don't think you read my suggested version of the code. I would no more want to trawl through and unknown number of bookmarks looking for one that might or might not be in a table anymore than I would want to trawl through an unknown number of tables. I suggest attempting to go to the bookmark explicitly. If it exists, fine see if it is in a table, if it doesn't it will error. |
|
#7
|
||||
|
||||
|
Greg
Sorry, I thought you had quoted my code sequence. Yes that's certainly a viable proposition, but I have a personal aversion to using error handling to address a problem that can be addressed without.
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com Last edited by gmayor; 06-06-2015 at 09:27 PM. |
|
#8
|
|||
|
|||
|
Graham,
Fair enough, in some future offline conversation I'll have to pick you and explore the reason for the aversion ;-) |
|
#9
|
||||
|
||||
|
OK, so why not use something like:
Code:
Const BmkNm as String = "MyTable"
With doc
If .Bookmarks.Exists(BmkNm) Then
'Do whatever you want with the bookmark and/or its table.
Else
MsgBox ("Bookmark '" & BmkNm & "' not present in the document.")
End If
End With
__________________
Cheers, Paul Edstein [Fmr MS MVP - Word] |
|
#10
|
|||
|
|||
|
I often forget bout .Exists. Looks good to me.
|
|
#11
|
||||
|
||||
|
Even better
Sometimes the most obvious answer eludes.
__________________
Graham Mayor - MS MVP (Word) (2002-2019) Visit my web site for more programming tips and ready made processes www.gmayor.com |
|
#12
|
|||
|
|||
|
Thanks for all of the responses. This definitely helps me to get a better understanding of Word VBA. I am pretty good at Access and Excel VBA, but I have no experience with word until now.
I am still going with the first suggestion. I have already implemented my sub based on that one and it works great. I misspoke when I said looking for a particular bookmark. In reality, what I really needed to do was loop through all of the tables. When I get back to work on Monday I will post my code. Inside the loop I have a select case that looks at the bookmark name. Thanks again, David |
|
#13
|
|||
|
|||
|
Here is the final code for the sub which reads Word tables and puts the data into Access tables.
Code:
Public Sub ReadTables()
On Error GoTo Err_Handler
If sPath = "" Then GoTo Err_Handler
Dim objwd As Word.Application
Dim doc As New Word.Document
Dim BM As Word.Bookmark
Dim tbl As Word.Table
Dim Row As Word.Row
Dim Col As Word.Column
Dim Cell As Word.Cell
Dim rowcount As Integer
Dim strBookMarkName As String
Dim strPartNumber As String
Dim strCAGE As String
Dim strNomenclature As String
Dim datStart As Date
Dim datEnd As Date
Dim strMainTask As String
Dim lngMainTaskID As Long
Dim lngDocID As Long
Dim bolDocHasData As Boolean
Dim bolTableHasData As Boolean
Dim bolRowHasData As Boolean
Dim strTaskName As String
Dim datMinDate As Date
Dim datMaxDate As Date
Dim datDocMinDate As Date
Dim datDocMaxDate As Date
Dim strSQL As String
Set objwd = New Word.Application
Set doc = objwd.Documents.Open(sPath)
For Each BM In doc.Bookmarks
strBookMarkName = BM.Name
If Left(strBookMarkName, 3) = "tbl" And BM.Range.Information(12) Then
Set tbl = BM.Range.Tables(1)
Debug.Print "Table: " & strBookMarkName
If tbl.Rows.Count > 1 Then
'CreateTempTable
Select Case strBookMarkName
Case "tblCalFailureModeAnalysis"
strMainTask = "Calibration Failure Mode Analysis"
Case "tblCalIntervalAnalysis"
strMainTask = "Calibration Interval Analysis"
Case "tblCalTrainingPlan"
strMainTask = "Calibration Training Plan and Site standup"
Case "tblCaStandardsForInitialCapability"
strMainTask = "Calibration standards for initial capability"
Case "tblCMRSReview"
strMainTask = "Calibration Measurement Requirements Summary (CMRS) Review"
Case "tblComSP"
strMainTask = "Commercial Service Provider (ComSP) Audit"
Case "tblCRATable"
strMainTask = "Calibration Requirements Analysis (CRA)"
Case "tblICP"
strMainTask = "Instrument Calibration Procedure (ICP) Review and Development"
Case "tblMeasurementTraceability"
strMainTask = "Measurement Traceability Report and Certification"
Case "tblResearchAndDevelopment"
strMainTask = "Research and Development"
End Select
'DoCmd.RunSQL "INSERT INTO tblTasks (FundingDocID, TaskName) SELECT " & lngFundingDocID & ", '" & strMainTask & "';"
lngMainTaskID = DMax("[ID]", "tblTasks")
datMinDate = #12:00:00 AM#
datMaxDate = #12:00:00 AM#
bolTableHasData = False
For Each Row In tbl.Rows
If Row.Index > 1 Then
strPartNumber = ""
strCAGE = ""
strNomenclature = ""
datStart = #12:00:00 AM#
datEnd = #12:00:00 AM#
bolRowHasData = False
For Each Cell In Row.Cells
'Debug.Print Cell.ColumnIndex = 1 through 5
Select Case Cell.ColumnIndex
Case 1
If Asc(Cell.Range.Text) <> 13 Then strPartNumber = Left(Cell.Range.Text, Len(Cell.Range.Text) - 2)
Case 2
If Asc(Cell.Range.Text) <> 13 Then strCAGE = Left(Cell.Range.Text, Len(Cell.Range.Text) - 2)
Case 3
If Asc(Cell.Range.Text) <> 13 Then strNomenclature = Left(Cell.Range.Text, Len(Cell.Range.Text) - 2)
Case 4
If Asc(Cell.Range.Text) <> 13 Then datStart = CDate(Left(Cell.Range.Text, Len(Cell.Range.Text) - 2))
Case 5
If Asc(Cell.Range.Text) <> 13 Then datEnd = CDate(Left(Cell.Range.Text, Len(Cell.Range.Text) - 2))
End Select
If strPartNumber <> "" Or _
strCAGE <> "" Or _
strNomenclature <> "" Or _
datStart <> #12:00:00 AM# Or _
datEnd <> #12:00:00 AM# Then bolRowHasData = True
If bolDocHasData = False And bolRowHasData = True Then
bolDocHasData = True
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO tblTasks (FundingDocID, TaskName) SELECT " & lngFundingDocID & ", '" & strTaskTitle & "';"
DoCmd.SetWarnings True
lngDocID = DMax("[ID]", "tblTasks")
End If
If bolTableHasData = False Then
If bolRowHasData Then
bolTableHasData = True
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO tblTasks (FundingDocID, TaskName, SuperTaskID) SELECT " & lngFundingDocID & ", '" & strMainTask & "', " & lngDocID & ";"
DoCmd.SetWarnings True
lngMainTaskID = DMax("[ID]", "tblTasks")
End If
End If
If bolTableHasData = True Then
If datStart <> #12:00:00 AM# Then
If datMinDate = #12:00:00 AM# Then datMinDate = datStart
If datDocMinDate = #12:00:00 AM# Then datDocMinDate = datStart
If datMinDate > datStart Then datMinDate = datStart
If datDocMinDate > datStart Then datDocMinDate = datStart
End If
If datEnd <> #12:00:00 AM# Then
If datMaxDate = #12:00:00 AM# Then datMaxDate = datEnd
If datDocMaxDate = #12:00:00 AM# Then datDocMaxDate = datEnd
If datMaxDate < datEnd Then datMaxDate = datEnd
If datDocMaxDate < datEnd Then datDocMaxDate = datEnd
End If
End If
Next Cell
If bolRowHasData = True Then
strTaskName = strNomenclature & "(Part# " & strPartNumber & " / CAGE " & strCAGE & ")"
DoCmd.SetWarnings False
DoCmd.RunSQL "INSERT INTO tblTasks (FundingDocID, SuperTaskID, TaskName, StartDate, FinishDate, Duration) SELECT " & lngFundingDocID & ", " & lngMainTaskID & ", '" & strTaskName & "', #" & datStart & "#, #" & datEnd & "#, " & Weekdays(datStart, datEnd) & ";"
DoCmd.SetWarnings True
End If
End If
Next Row
If bolTableHasData = True Then
DoCmd.SetWarnings False
DoCmd.RunSQL "UPDATE tblTasks SET tblTasks.StartDate = #" & datMinDate & "#, tblTasks.FinishDate = #" & datMaxDate & "#, tblTasks.Duration = " & Weekdays(datMinDate, datMaxDate) & " " & _
"WHERE (((tblTasks.ID)=" & lngMainTaskID & "));"
DoCmd.RunSQL "UPDATE tblTasks SET tblTasks.StartDate = #" & datDocMinDate & "#, tblTasks.FinishDate = #" & datDocMaxDate & "#, tblTasks.Duration = " & Weekdays(datDocMinDate, datDocMaxDate) & " " & _
"WHERE (((tblTasks.ID)=" & lngDocID & "));"
DoCmd.SetWarnings True
End If
End If
End If
Next BM
Exit_Sub:
On Error Resume Next
Set tbl = Nothing
Set BM = Nothing
doc.Close
Set doc = Nothing
Set objwd = Nothing
Exit Sub
Err_Handler:
bolImportFailed = True
Debug.Print Err.Number, Err.Description
Resume Exit_Sub
End Sub
|
|
| Tags |
| bookmarks, vba word, word 2010 |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
Bookmark Not Showing Bookmark
|
RegAudit | Word | 6 | 03-16-2015 11:08 PM |
Find what box in Find and replace limits the length of a search term
|
Hoxton118 | Word VBA | 7 | 06-10-2014 05:05 AM |
| vba to go to next bookmark | megatronixs | Word VBA | 2 | 06-08-2014 09:53 PM |
Bad view when using Find and Find & Replace - Word places found string on top line
|
paulkaye | Word | 4 | 12-06-2011 11:05 PM |
VBA to insert Bookmark
|
rockwellsba | Word VBA | 2 | 05-31-2011 01:07 AM |