#1
|
|||
|
|||
Iterating through tables to find a bookmark
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 |
Thread Tools | |
Display Modes | |
|
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 |