Access table object based on current paragraph - vba

I am iterating through all paragraphs in a document and want to identify their indent level. While this works most of the time using Paragraph.Format.LeftIndent, it does not work for paragraphs within tables. In particular in cases when the paragraph itself is not indented but the table has a left indent.
Is there any way to navigate from the currelty selected paragraph to the table where it is located in? I know there is the property "wdWithInTable" but this is not enough for me because I need the Table object to check its LeftIndent property.

Go get table from current selection use this logic:
Sub GetTable()
Dim currentTable As Table
Set currentTable = Selection.Tables(1)
'test purpose only
Debug.Print currentTable.Rows.Count, currentTable.Columns.Count
'and to get table indention try with this
Debug.Print currentTable.Range.ParagraphFormat.LeftIndent
End Sub

Related

Using VBA to Change Text Style in All Tables in a Word Document

I am trying to change the text style inside all tables in a document, and then bold the text in all columns of the first row. I currently have the following...
Sub AutoTableFormat()
Dim tbl As Table
For Each tbl In ActiveDocument.Tables
txt.Text.Style = ActiveDocument.Styles("Table Text")
Next
End Sub
The following give me an error saying Run-time error '5849': Could not apply the style. I am very new to VBA(just started today) and was hoping for some help. Honestly dont even know where to start with the bolding thing either. Thank you.
The Visual Basic Editor provides you with three tools to help with coding:
Intellisense - shows you the available properties and methods for objects as you type.
Object Browser - allows you to browse or search the object model
Online help
Although you start out well with a loop through the tables the line inside the loop is completely illogical. What exactly is the variable txt supposed to represent? Where is it declared? What relation does it have to tbl?
Had you used the tools at your disposal you would have discovered that a Table object has a Range which has a Style property. This would have given you:
Sub AutoTableFormat()
Dim tbl As Table
For Each tbl In ActiveDocument.Tables
tbl.Range.Style = ActiveDocument.Styles("Table Text")
Next
End Sub
Setting the format of the first column is awkward as the Column object does not have a Range. This means you have to loop through each cell of the first column to apply the formatting. A more efficient way of achieving your goal would be to create a table style with all your required formatting and then apply that.
Sub AutoTableFormat()
Dim tbl As Table
For Each tbl In ActiveDocument.Tables
tbl.Style = ActiveDocument.Styles("My Table Style")
tbl.ApplyStyleFirstColumn
Next
End Sub

Move the line before the table along with the table if the line appears on the page preceding the table

We have captions for tables in our Word documents that do not behave like captions and act as "Normal" word styles. These captions sometimes appear on the preceding page of the table.
There are hundreds of documents and may be a million instances of captions in those documents. The documents were imported from an old source system to a new source system using a script, which didn't do the job as expected.
I would like if such captions exist on the preceding page, they are removed from the page and shown before the table on the same page.
The logic that I want to use:
Find a table
Find the page number of the table
Find the first instance of "Normal" paragraph style just before the table
Find the page number of the "Normal" Paragraph style
Only if the page number of the first instance of the "Normal" Paragraph style is less than the page number of the table by 1, then move the entire instance to the next page just before the table
Do this for all tables.
So far I could only manage to write this code:
Dim tblNew As Table
Dim oPara As Paragraph
Dim oRng As Range
Dim PageNo As Integer
Dim PageNoCap As Integer
For Each tblNew In ActiveDocument.Tables
PageNo = tblNew.Range.Information(wdActiveEndPageNumber)
I would approach this by fixing the incorrect use of styles. The code below applies the Caption style to demonstrate the principle.
Using code to compensate for not using Word correctly in the first place is a bad idea, but if you have existing documents that you need to correct could be a useful temporary measure.
Sub ApplyStyleToTableCaptions()
Dim tbl As Table
Dim oRng As Range
With ActiveDocument.Styles(wdStyleCaption).ParagraphFormat
If Not .KeepWithNext Then .KeepWithNext = True
End With
For Each tbl In ActiveDocument.Tables
Set oRng = tbl.Range
oRng.Collapse wdCollapseStart
oRng.Move wdParagraph, -1
oRng.Paragraphs(1).Range.Style = wdStyleCaption
Next tbl
End Sub

MS Word - Hiding a Row in a Table depending on Content Control value

I have a very long word file, containing several tables.
Each table contains a list of items that may or may not be applicable to the user.
I am trying to find a way of hiding/masking rows that have not been filled by the user.
To do so, I was thinking of writing a sub that go through the entire document lookinf for content controls, then checks if the contentcontrol.text="NULL" and then deletes the table row (or hides it by setting the row height to 0).
Any ideas?
Below my partial attempt
Sub HideRows()
Dim d As Document
Set d = ActiveDocument
Dim cc As ContentControl
For Each cc In d.ContentControls
If cc.Range.Text = "NULL" Then
'Delete the table row where this content control is located
End If
Next
End Sub
Assuming that:
each ContentControl covers the whole single row
you do not use nested tables in document
you can place this code inside your if statement:
CC.Range.Tables(1).Rows(CC.Range.Information(wdEndOfRangeRowNumber)).Delete

Copy certain table row from one table to another

I have a word document with several tables.
The first table in the document is supposed to be a summary table containing copies of certain rows of the other tables in the document.
How would I have to tackle the automated population of the summary table with the specific rows of the other tables?
I assume there is no built in function and I'd have to use VBA.
I'd think I have to mark the rows to be copied with some marker (e.g.: "###") for the code to detect. Then the code would have to go through the document, find all the "###", mark them as "dealt with" (e.g., with "##-") and copy/append the respective row into the first table, and then loop through the document again.
You can mark the row(s) using bookmarks; name them with a special prefix. Loop through the bookmarks collection, check the prefix and if it's the correct one, append the row to the sumamry table. You can delete the bookmark in the process, if you wish.
Here's some sample code which works for me in a quick test. The boomkark prefix is "tbl"; if you don't want it to be visible to the user, start the name with an underscore (_).
The target range for the summary table is at the start of the document. Change the assignment to the rng object if you need it elsewhere.
Dim doc As word.Document
Dim rng As word.Range
Dim rwSource As word.Row
Dim bkm As word.Bookmark
Set doc = ActiveDocument
Set rng = doc.Range(0, 0)
For Each bkm In doc.Bookmarks
If Left(bkm.Name, 3) = "Tbl" Then
rng.FormattedText = bkm.Range.FormattedText
rng.Collapse wdCollapseEnd
End If
Next
Note: I tried using REF fields to pick up the bookmarked rows, without needing VBA. This inserted an empty row between each REF field, however, so I don't think it can be done without VBA.

Get all cross references in word with VBA

I have quite a large word document (> 400 pages) with lots of cross references to headings. So far, I have always referred to the title of the heading, but now I would like to change that and refer to the page the heading resides on.
I didn't find a solution to this via the GUI (except manual treatment, of course), so I was looking into writing some VBA. Unfortunately, I have only found a way to list all targets that can be cross referenced (via GetCrossReferenceItems), but I need a way to access the actual cross reference field.
Can you help me with that? Is a cross reference field the same as a hyperlink?
Cross-references are fields in a Word document, and can be accessed via the Fields collection (ActiveDocument.Fields). You can loop through them like any other collection and check their types to see if it's one you want to work on. It looks like cross-references to text are type 3 (wdFieldRef) and cross-references to page numbers are type 37 (wdFieldPageRef). Changing fields can be a little tricky; the following should get you started:
Sub ChangeFields()
Dim objDoc As Document
Dim objFld As Field
Dim sFldStr As String
Dim i As Long, lFldStart As Long
Set objDoc = ActiveDocument
' Loop through fields in the ActiveDocument
For Each objFld In objDoc.Fields
' If the field is a cross-ref, do something to it.
If objFld.Type = wdFieldRef Then
'Make sure the code of the field is visible. You could also just toggle this manually before running the macro.
objFld.ShowCodes = True
'I hate using Selection here, but it's probably the most straightforward way to do this. Select the field, find its start, and then move the cursor over so that it sits right before the 'R' in REF.
objFld.Select
Selection.Collapse wdCollapseStart
Selection.MoveStartUntil "R"
'Type 'PAGE' to turn 'REF' into 'PAGEREF'. This turns a text reference into a page number reference.
Selection.TypeText "PAGE"
'Update the field so the change is reflected in the document.
objFld.Update
objFld.ShowCodes = True
End If
Next objFld
End Sub