- Remove From My Forums
-
Question
-
Is there any way to «Name» a table in a Word Document, so that it can easily be referred to later, either directly or by searching?
I see that the ID property can be set (i.e. Tables(1).ID = «Table1»), but after doing so, can the table be searched for, or do I have to iterate through each table in the document to try to find the table with ID = «Table1»?
Is there no way to refer to a Table through a name [i.e. Tables(«Table1»)], just as one would reference a worksheet in an Excel workbook? [i.e. Sheets(«Sheet1»)] Or is there some other way to name/locate a particular table besides using «brute force»?
Many thanks!
DragonForest
Answers
-
To expand on the bookmark route, and it is what I use.
If you bookmark ANY table, you can then use it as a name. The advantage is that you can move the table anywhere you like, change the rows…whatever, and it does not affect the ability to use a name. Normally if you move a table (or add another
table before it), the index number changes. this makes using an index number veryb unreliable.So. You bookmark a table with the name «ClientData». Now you can use a Table object and set it to THAT table, no matter where it is in the document.
Sub GetClientData()
Dim file
Dim path As String
Dim oTable As Table
Dim WriteToDoc As Document
Dim SourceDoc As Document
path = «X:YaddaBlah»
Set WriteToDoc = ActiveDocumentfile = Dir(path & «*.doc»)
Do While file <> «»
Set SourceDoc = Documents.Open(FileName:=path & file)
Set oTable = SourceDoc.Bookmarks(«ClientData»).Range.Tables(1)
WriteToDoc.Range.InsertAfter oTable.Cell(3, 1).Range.Text & vbCrLf
SourceDoc.Close
Set oTable = Nothing
Set SourceDoc = Nothing
file = Dir()
Loop
End SubThis code runs through all .doc files in a folder, opening each, setting a table object for a bookmarked table named ClientData, getting the text from cell row3,column1, and putting that text into a document.
Bookmarking tables allows use of names for that table. It is a very powerful tool. I name all my tables.
-
Edited by
Sunday, April 22, 2012 1:23 AM
-
Marked as answer by
DragonForest
Sunday, April 22, 2012 7:55 AM
-
Edited by
-
«Brute force» seems to be the way to go:
Sub FindTable() Dim tbl As Table For Each tbl In ActiveDocument.Tables If tbl.ID = "MyID" Then Exit For End If Next tbl If Not tbl Is Nothing Then ' ... End If End Sub
Regards, Hans Vogelaar
-
Marked as answer by
DragonForest
Friday, April 20, 2012 4:48 PM
-
Marked as answer by
-
The Tables(index).ID property is designed for Internet/HTML/XML purposes.
If you want to use it in Word, you have to use something like this:
——
Selection.Tables(1).ID = «My Crazy Table»
——
and then:
——
Dim tbl As Table
For Each tbl In ActiveDocument.Range.Tables
If tbl.ID = «My Crazy Table» Then
tbl.Select
Exit For
End If
Next——
Or else, use bookmarks:
——
Selection.Tables(1).Range.Bookmarks.Add «Crazy_Table»
——and then:
——
ActiveDocument.Bookmarks(«Crazy_Table»).Range.Select
——
-
Marked as answer by
DragonForest
Friday, April 20, 2012 4:47 PM
-
Marked as answer by
Hi hklein,
To add a title programmatically, you could use code like:
Code:
Sub Demo1() ActiveDocument.Tables(1).Title = "MyTableTitle" End Sub
However, if you know which table to add the title to programmatically without selecting it, you probably don’t need to give it a title.
Alternatively, if you want to add a title to a selected table, you can do that through the user interface, or with code like:
Code:
Sub Demo2() If Selection.Information(wdWithInTable) = False Then Exit Sub Selection.Tables(1).Title = "MyTableTitle" End Sub
Ultimately, though you’ll want to do something programmatically with the titled table, for which you’ll need more sophisticated code, like:
Code:
Sub Demo3() Dim oTbl As Table For Each oTbl In ActiveDocument.Tables If oTbl.Title = "MyTableTitle" Then 'Do something with the table Exit For End If Next End Sub
This is how a table looks like in XML (3*3):
<w:tbl>
<w:tblPr>
<w:tblStyle w:val="Grilledutableau"/>
<w:tblW w:type="auto" w:w="0"/>
<w:tblLook w:firstColumn="1" w:firstRow="1" w:lastColumn="0" w:lastRow="0" w:noHBand="0" w:noVBand="1" w:val="04A0"/>
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="3070"/>
<w:gridCol w:w="3071"/>
<w:gridCol w:w="3071"/>
</w:tblGrid>
<w:tr w:rsidR="00153204" w:rsidTr="00153204">
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3070"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3071"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3071"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
</w:tr>
<w:tr w:rsidR="00153204" w:rsidTr="00153204">
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3070"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3071"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3071"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
</w:tr>
<w:tr w:rsidR="00153204" w:rsidTr="00153204">
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3070"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3071"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:type="dxa" w:w="3071"/>
</w:tcPr>
<w:p w:rsidR="00153204" w:rsidRDefault="00153204"/>
</w:tc>
</w:tr>
</w:tbl>
They are some IDs here, but these IDs will change if the user adds a table, moves it, …
What you could do is to add that identifier yourself:
Add a particular replacement string to the tables (for example ID:1)
This adds this id in the w:tblCaption
attribute:
<w:tblPr>
<w:tblStyle w:val="Grilledutableau"/>
<w:tblW w:type="auto" w:w="0"/>
<w:tblLook w:firstColumn="1" w:firstRow="1" w:lastColumn="0" w:lastRow="0" w:noHBand="0" w:noVBand="1" w:val="04A0"/>
<w:tblCaption w:val="ID:1"/>
</w:tblPr>
To add this caption in word: Right-Click on the table->Properties->Text/Replacement
Put some text element before each table you want to identify
This adds the following xml before the table
<w:p w:rsidR="006B0CC1" w:rsidRDefault="006B0CC1">
<w:r>
<w:t>ID :1</w:t>
</w:r>
<w:bookmarkStart w:id="0" w:name="_GoBack"/>
<w:bookmarkEnd w:id="0"/>
</w:p>
I would go with the first possibility as it’s easy to read those properties and they are inside the table, so you only have to parse the table elements.
In this article, we are glad to show you 3 quick ways to find specific text in your Word tables only.
Utilizing the “Find and Replace”, a built-in function in Word, you can search for and find a specific text in a long document. As you see, this is based on the entire document. How about we limit the searching range to Word tables only? Read on to see details.
Method 1: Find Text in Selection
- First of all, manually select one or more tables in document.
- Then click drop-down button next to “Find” command under “Home” tab.
- Choose “Advanced Find” to open “Find and Replace” dialog box.
- Enter finding text in “Find what” text box.
- Click “Find In” tab and choose “Current Selection”.
Word will find text in your selection only.
Method 2: Find Text in a Table
Besides the usual way, you can choose to run macro to do more customized tasks.
- First off, put cursor inside a table where you want to find text.
- Then press “Alt+ F11” to open VBA editor.
- Click “Normal” on the left column.
- Then click “Insert” and choose “Module”.
- Next double click the module to open it.
- Paste following codes into module:
Sub FindInATable() Dim strText As String strText = InputBox("Enter finding text here: ") Application.ScreenUpdating = False If Selection.Information(wdWithInTable) = True Then With Selection.Tables(1).Range With .Find .ClearFormatting .Text = strText .Forward = True .Wrap = wdFindStop .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False .Execute End With Do While .Find.Found .Cells(1).Shading.BackgroundPatternColorIndex = wdBrightGreen On Error GoTo handler .Collapse wdCollapseEnd .Find.Execute Loop End With Else MsgBox ("Put cursor inside a table first.") Exit Sub End If handler: Exit Sub Application.ScreenUpdating = True End Sub
- Lastly, click “Run”. Enter a text inside the input box and click “OK” to proceed.
Method 3: Find Text in All Tables in a Document
- First and foremost, repeat steps in method 2 to install and run a macro.
- Next replace that macro with this one:
Sub FindTextsInAllTables() Dim strText As String strText = InputBox("Enter finding text here: ") Application.ScreenUpdating = False With Selection .HomeKey Unit:=wdStory With Selection.Find .ClearFormatting .Text = strText .Forward = True .Wrap = wdFindStop .Format = False .MatchCase = False .MatchWholeWord = False .MatchWildcards = False .MatchSoundsLike = False .MatchAllWordForms = False .Execute End With Do While .Find.Found = True If .Information(wdWithInTable) = True Then .Cells(1).Shading.BackgroundPatternColorIndex = wdBrightGreen End If .Collapse wdCollapseEnd .Find.Execute Loop End With Application.ScreenUpdating = True End Sub
- Similarly, type searching text inside the input box. And click “OK” to proceed.
Rescue Your Data in Time
Once you get compromised data, keep in mind that they are recoverable. So never give up before trying. Under such circumstances, you need to check your latest backup, if any. There is a good chance to have some of your data back. Besides, you can always resort to doc fix tool to recover data.
Author Introduction:
Vera Chen is a data recovery expert in DataNumen, Inc., which is the world leader in data recovery technologies, including damaged xls and pdf repair software products. For more information visit www.datanumen.com
Office Open XML
Office Open XML is introduced by Microsoft to work with documents. For e.g.: — read/write MS word documents.
Prerequisites
- Visual Studio
- MS Word Document
- Open XML SDK
Execute below command to Install DocumentFormat.OpenXml SDK in your project
- Install-Package DocumentFormat.OpenXml Install-Package DocumentFormat.OpenXml
In this example, I am using a windows form application to interact with word document and display the result on the screen.
How to find first table from word document?
- Table table = doc.MainDocumentPart.Document.Body.Elements<Table>().First();
Here .First() is extension method to find first table from word document.
The WordprocessingDocument Methods
EXTENSION METHOD |
DESCRIPTION |
.Elements<Table>().First() |
To get the first table from the word document |
.Elements<Table>().Last() |
To get the last table from the word document |
.Elements<Table>().FisrtOrDefault() |
To get the first table from the word document or return the default value if the document does not contain table. |
.Elements<Table>().LastOrDefault() |
To get the Last table from word document or return the default value if the document does not contain table. |
.Elements<Table>().ElementAt(Index) |
To get the exact table from the word document by index number. Default index number is 0. |
Table.Elements<TableRow>().ElementAt(index) |
To get the exact table row from selected table by index number. Default index number is 0. |
Row.Elements<TableCell>().ElementAt(Index) |
To get the exact row cell from selected row by index number. Default index number is 0. |
Execute the following code to read the first table from the word document,
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Linq;
- using System.Windows.Forms;
- using DocumentFormat.OpenXml.Packaging;
- using DocumentFormat.OpenXml.Wordprocessing;
- namespace ReadTable
- {
- public partial class Form1 : Form
- {
- public Form1()
- {
- InitializeComponent();
- }
- private void btnBrowse_Click(object sender, EventArgs e)
- {
- DialogResult result = this.openDB.ShowDialog();
- if (result == DialogResult.OK)
- {
- txtBrowse.Text = openDB.FileName;
- }
- }
- private void btnReadTable_Click(object sender, EventArgs e)
- {
- using (var doc = WordprocessingDocument.Open(txtBrowse.Text.Trim(), false))
- {
- DataTable dt = new DataTable();
- int rowCount = 0;
- Table table = doc.MainDocumentPart.Document.Body.Elements<Table>().First();
- IEnumerable<TableRow> rows = table.Elements<TableRow>();
- foreach (TableRow row in rows)
- {
- if (rowCount == 0)
- {
- foreach (TableCell cell in row.Descendants<TableCell>())
- {
- dt.Columns.Add(cell.InnerText);
- }
- rowCount += 1;
- }
- else
- {
- dt.Rows.Add();
- int i = 0;
- foreach (TableCell cell in row.Descendants<TableCell>())
- {
- dt.Rows[dt.Rows.Count — 1][i] = cell.InnerText;
- i++;
- }
- }
- }
- dgvTable.DataSource = dt;
- }
- }
- }
- }
Output
In the above example, I have used .First() extension method to get the first table from word document. You can use other extension methods to find exact table or you can use for/foreach loop to find the exact table from the word document.
Summary
In this session, I discussed how to read the table from the word document using c#. I hope the above session will help you to read the table from the word document using C#.