Word.Range.TextVisibleOnScreen? - vba

Does the Word.Range.TextVisibleOnScreen property actually work?
Private Sub isVisTest()
Dim rng As Range: Set rng = oDoc.Bookmarks("_Toc#########").Range
'replace ######### with a good Heading bookmark number from your test document
Dim c As Integer
ActiveWindow.VerticalPercentScrolled = 0
ActiveWindow.HorizontalPercentScrolled = 0
oDoc.ActiveWindow.ScrollIntoView rng
Do
oDoc.ActiveWindow.SmallScroll Down:=6
Debug.Print rng.TextVisibleOnScreen
c = c + 1
If c > 10 Then Exit Do
Loop Until rng.TextVisibleOnScreen = 0
oDoc.ActiveWindow.SmallScroll Up:=6
End Sub
The abbreviated procedure uses Heading bookmark to display the corresponding Heading at the top of the screen simto Word's built-in Nav Pane behavior. The Do-Loop is a refinement to bring the Heading to top of page but I'm finding that the rng.TextVisibleOnScreen property never changes regardless of whether the rng object is actually visible onscreen or not; it's always -1. Thus the property seems disabled. However, MSDN doesn't report it as being disabled or deprecated.
The same test can be done by using a Selection and the IDE's Immediate window, i.e., ?Selection.Range.TextVisibleOnScreen. I get the same result; always -1.

As implied by the language reference
The TextVisibleOnScreen property returns 1 if all text in the range is
visible; it returns 0 if no text in the range is visible; and it
returns -1 if some text in the range is visible and some is not. Text
that is not visible could be, for example, text that is in a collapsed
heading.
this property lets you know whether a Range is visible or not due to a Heading style being collapsed or expanded. The capability to collapse/expand sections of text under a heading was introduced at the same time - in Word 2013.
It has nothing to do whether text is hidden or scrolled off the screen.
What is definitely odd / misleading is the statement that 1 is returned when something is visible and -1 when something is only partially visible. I believe this is a mistake in the documentation, possibly from the 2013 beta that never was corrected.
The following code returns 0 when the range (second paragraph in the document) is not visible because a heading style before it is collapsed:
Sub TestHiddenText
Dim rng as Word.Range
Set rng = ActiveDocument.Paragraphs(3).Range
Debug.Print rng.TextVisibleOnScreen
End Sub
When the heading is expanded, the above returns -1 (which traditionally has always been "true" in Word).
If I collapse that heading, but test the entire document, the mixed status returns what I'd expect from Word - undefined: 9999999
Sub TestHiddenText
Dim rng as Word.Range
Set rng = ActiveDocument.Content
Debug.Print rng.TextVisibleOnScreen
End Sub

Related

Remove extra line after adding/deleting a bookmark in VBA

In My Word Template I have few bullet points, and I will select the required points based on selection from the GUI and remove the rest of the points that are not selected from the code. So it depends on the user how many points that he would select.
I am Tall (bookmark1)
I am Dark (bookmark2)
I am 6.2 feet height (bookmark3)
I Have BMW (bookmark4)
I know 5 different languages (bookmark5)
I have created bookmarks for all these points as shown in the braces above.
Now the problem is, the user selects few number of bullet points from the above list and output would leave an extra blank line below.
I have tried many approaches from changing the selection of the bookmarks to adding bullet point form the code. I need to get rid of the extra blank line.
But nothing seems to work. I would appreciate the help in this. TIA
If .cboChanges1.Value = "No" Then
DeleteBookmark ("bookmark1")
Else
AddBullet ("bookmark1")
End If
If .cboChanges2.Value = "No" Then
DeleteBookmark ("bookmark2")
Else
AddBullet("bookmark2")
End If
etc.. where cboChanges1 and cboChanges2 are combo boxes to choose Yes/no.
Sub DeleteBookmark(strBookmark As String)
Dim rng As Range
Set rng = ActiveDocument.Bookmarks(strBookmark).Range
rng.Delete
Set rng = Nothing
End Sub
Before Screenshot
Output screen after first 3 options, you can see extra blank line as highlighted
I am adding the bullet point dynamically, as follows
Sub AddBullet(strBookmark As String)
ActiveDocument.Bookmarks(strBookmark).Select
Selection.Range.ListFormat.ApplyBulletDefault
End Sub
This is how the bookmarks are arranged,
A table cell always contains an end of cell marker which is a combination of paragraph and end of cell mark. This means that an empty cell always contains at least one paragraph.
As the end of cell marker cannot be deleted when you delete the text in the last bookmark you will get an empty paragraph because the previous bookmarked range ends with a paragraph mark.
You can deal with this in your DeleteBookmark routine by checking the length of the final paragraph of the cell. If it only contains two characters then it has no text and the preceding paragraph mark can be deleted.
Sub DeleteBookmark(strBookmark As String)
Dim rng As Range
Set rng = ActiveDocument.Bookmarks(strBookmark).Range
rng.Delete
Set rng = rng.Cells(1).Range.Paragraphs.Last.Range
If Len(rng.Text) = 2 Then
'paragraph contains no text so delete preceding paragraph mark
rng.Collapse wdCollapseStart
rng.MoveStart wdCharacter, -1
rng.Delete
End If
Set rng = Nothing
End Sub
If you are going to write code for Word you need to learn what the formatting marks are so that you can understand how a document is constructed.
FYI It is not necessary to select a range to apply bullets.
Sub AddBullet(strBookmark As String)
ActiveDocument.Bookmarks(strBookmark).Range.ListFormat.ApplyBulletDefault
End Sub

How to get a page / the beginning of a Section?

Good Day! I have a Word Document and a macro that takes content of that document and inserts it into another Document(with all boundaries, frames etc.), Basically unorganized into organized document.
I would like to check the first page of a section (and any section) and see if any table is present if so, exit the loop, and just readjust the page accordingly with our country document standards.
I have done mostly without checking a table on the first page of a new section.
If objSection.Index = 1 Then 'the first section
'I need to check if there is a table on the first page of a section
Checking page size and orientation for the first Section.'(this is done)
ElseIf objSection.Index > 1 Then 'other sections
'practically the same thing, checking if a table exists on the first page of a section
Checking page size and orientation for all other Sections.'(this is also done)
End If
Something like the following should get you there.
Function TableInFirstPageOfSection(sec As Section) As Boolean
Dim secRange As Range, secStart As Long
Dim tblRange As Range, tblStart As Long
TableInFirstPageOfSection = False
Set secRange = sec.Range
secRange.Collapse wdCollapseStart
secStart = secRange.Information(wdActiveEndPageNumber)
If sec.Range.Tables.Count > 0 Then
Set tblRange = sec.Range.Tables(1).Range
tblRange.Collapse wdCollapseStart
tblStart = tblRange.Information(wdActiveEndPageNumber)
If tblStart = secStart Then TableInFirstPageOfSection = True
End If
End Function

How to change an existing Tabstop in PowerPoint by VBA?

I have a VBA Code to resize objects in PowerPoint including Font size, margins and everything else. But I haven’t found a solution to update/change an existing TapStop. There is a the Ruler Object with different levels und a default value. I double checked also the TextRange Object with Characters.
Are there any ideas to update the TabStop size?
Here is an example of a TextBox, i would like to resize:
TextBox Example
Shape.textframe.ruler.tabstops.count is always 0, if I "take" just the shape by For-Each-Loop. If I select it manual, it's also 0 at the sub menu TabStops of Paragraph menu.
If I click inside the shape (blinking cursor) and open the TabStops menu again, I see one TabStopPosition.
How can I access this information by VBA?
I tried it already by Line.Selection and nothing works.
Thanks!
Moe
PowerPoint used to allow only one set of paragraph settings per textframe (ie, per shape). That changed in PPT2007; now each paragraph can have its own tab and other settings. Have a go with this:
Sub ShowMeTabs()
Dim X As Long
Dim lTabCount As Long
With ActiveWindow.Selection.ShapeRange(1).TextFrame2.TextRange
For X = 1 To .Paragraphs.Count
Debug.Print X
With .Paragraphs(X).ParagraphFormat
For lTabCount = 1 To .TabStops.Count
Debug.Print .TabStops(lTabCount).Position
Next ' Tab
Debug.Print "Level:" & .IndentLevel & " Position:" & .LeftIndent 'etc
End With
Next ' paragraph x
End With
End Sub

Using Cross Reference Field Code to move selection to Target of Field Code

OP Update:
Thanks for the code KazJaw, it prompted me to change the approach I am trying to tackle the problem with. This is my current code:
Sub Method3()
Dim intFieldCount As Integer
Dim i As Integer
Dim vSt1 As String
intFieldCount = ActiveDocument.Fields.Count
For i = 1 To intFieldCount
ActiveDocument.Fields(i).Select 'selects the first field in the doc
Selection.Expand
vSt1 = Selection.Fields(1).Code
'MsgBox vSt1
vSt1 = Split(vSt1, " ")(2) 'Find out what the (2) does
MsgBox vSt1
ActiveDocument.Bookmarks(vSt1).Select 'Selects the current crossreference in the ref list
Next i
End Sub
Ok the so the Code currently finds the first field in the document, reads its field code and then jumps to the location in the document to mimic a CTRL+Click.
However, It does this for all types of fields Bookmarks, endnotes, figures, tables etc. I only want to find Reference fields. I thought I could deduce this from the field code but it turns out figures and bookmarks use the same field code layout ie.
A Reference/Boookmark has a field code {REF_REF4123123214\h}
A Figure cross ref has the field code {REF_REF407133655\h}
Is there an effective way to get VBA to distinguish between the two? I was thinking as reference fields in the document are written as (Reference 1) I could find the field and then string compare the word on the left to see if it says "Reference".
I was thinking of using the MoveLeft Method to do this
Selection.MoveLeft
But I can't work out how to move left 1 word from the current selection and select that word instead to do the strcomp
Or perhaps I can check the field type? with...
If Selection.Type = wdFieldRef Then
Do Something
End If
But I am not sure which "Type" i should be looking for.
Any advice is appreciated
All REF fields "reference" bookmarks. Word sets bookmarks on all objects that get a reference for a REF field: figures, headings, etc. There's no way to distinguish from the content of the field what's at the other end. You need to "inspect" that target, which you can do without actually selecting it. For example, you could check whether the first six letters are "Figure".
The code you have is inefficient - there's no need to use the Selection object to get the field code. The following is more efficient:
Sub Method3()
Dim fld As Word.Field
Dim rng as Word.Range
Dim vSt1 As String
ForEach fld in ActiveDocument.Fields
vSt1 = fld.Code
'MsgBox vSt1
vSt1 = Split(vSt1, " ")(2) 'Find out what the (2) does
MsgBox vSt1
Set rng = ActiveDocument.Bookmarks(vSt1).Range
If Left(rng.Text, 6) <> "Figure" Then
rng.Select
End If
Next
End Sub

Word 2010 / 2013 VBA - set selection to be that of a named range

I've searched web without results for how to do a simple task.
Make the selection that of a named range. I keep getting a duplication of the text in the named range, not a selection. Code with comments:
Sub SetSelectionFromRange()
' Goal: Set current selection to be that of a named range
' text of doc is "One Two" and at start the insertion bar is between "w" and "o"
Dim myRange4 As Range
Set myRange4 = ActiveDocument.Range(Start:=0, End:=3)
Selection.Range = myRange4.Duplicate
' result expected is "One" selected and no change in text
' result actual is "One TwOneo" and insertion bar left after "w" (no selection)`
End Sub
Instead of:
Selection.Range = myRange4.Duplicate
Try:
myRange4.Select