PDA

View Full Version : [SOLVED:] Wordcount of Word table - column only



davidov
09-07-2017, 08:52 AM
The code below nicely provides a word count for a whole table.



Set myRange = ActiveDocument.Tables(1).Range
wordCount = myRange.ComputeStatistics(Statistic:=wdStatisticWords)
MsgBox "The range contains " & wordCount & " words."

I now need a word count only for Column 3. How to specify the column?
I thought I should just be able to add '.Column(3)' after 'Tables(1)', but it seems they didn't want to make it that intuitive.

Cheers.

Kilroy
09-07-2017, 12:56 PM
This is a slight variation of a code written by Macropod.


Sub WordCount()
Dim i As Long, j As Long, Rng As range
ActiveDocument.Tables(1).Select
With Selection.Tables(1)
For i = 3 To 3
.Columns(i).Select
With Selection
If .Information(wdWithInTable) = True Then
For s = 1 To .Cells.Count
Set Rng = .Cells(s).range
With Rng
.End = .End - 1
j = j + .ComputeStatistics(wdStatisticWords)
End With
Next
Else
j = .range.ComputeStatistics(wdStatisticWords)
End If
End With
MsgBox j
Next
End With
End Sub

Kilroy
09-07-2017, 01:18 PM
Here is another version that lets you pick which table and which column. I've tried both codes on different tables and it works great but when you get to 25+ pages it really slows down.


Sub WordCount()
Dim i As Long, j As Long, Rng As range
ActiveDocument.Tables((InputBox("Which Table to search", "Table Number"))).Select
With Selection
.Columns((InputBox("Enter column to search", "Must be in column range or an error will occur"))).Select
With Selection
If .Information(wdWithInTable) = True Then
For s = 1 To .Cells.Count
Set Rng = .Cells(s).range
With Rng
.End = .End - 1
j = j + .ComputeStatistics(wdStatisticWords)
End With
Next
Else
j = .range.ComputeStatistics(wdStatisticWords)
End If
End With
MsgBox j
End With
End Sub

gmaxey
09-07-2017, 04:25 PM
Not very elegant, but fast:


Sub ScratchMacro()
'A basic Word macro coded by Greg Maxey, http://gregmaxey.com/word_tips.html, 9/7/2017
Dim oDocTemp As Document
Application.ScreenUpdating = False
ActiveDocument.Tables(1).Columns(3).Select
Selection.Copy
Set oDocTemp = Documents.Add(, , , False)
oDocTemp.Range.Paste
MsgBox oDocTemp.Range.ComputeStatistics(wdStatisticWords)
oDocTemp.Close wdDoNotSaveChanges
Application.ScreenUpdating = True
lbl_Exit:
Exit Sub
End Sub

davidov
09-07-2017, 08:17 PM
I'm surprised that in VBA we can't simply just set a column as a range and perform the count on that, but that must be under-thinking it.

These work well. Speed is an issue so I'm going with Greg's method. Copying the column text to a new document, counting and closing, is what I've been doing manually for some time - didn't know code could do it.

I can combine it with Kilroy's column selection box, which is useful, and will add Section.Collapse at the end to deselect.

Many thanks for the help.

macropod
09-07-2017, 08:54 PM
You can, but you can't use ComputeStatistics:

Sub Demo()
Application.ScreenUpdating = False
Dim Rng As Range, i As Long
Set Rng = Selection.Range
ActiveDocument.Tables(1).Columns(3).Select
i = Selection.Range.Words.Count
Rng.Select
Application.ScreenUpdating = True
MsgBox "ActiveDocument.Tables(1).Columns(3) contains " & i & " words."
End Sub
Conversely, without selecting anything, you can still get a count:

Sub Demo()
Dim r As Long, i As Long, Rng As Range
With ActiveDocument.Tables(1)
For r = 1 To .Rows.Count
Set Rng = .Cell(r, 3).Range
With Rng
.End = .End - 1
i = i + .ComputeStatistics(wdStatisticWords)
End With
Next
End With
MsgBox i
End Sub

gmaxey
09-07-2017, 08:56 PM
Yes, some window dressing wouldn't hurt:


Sub ScratchMacro()
'A basic Word macro coded by Greg Maxey, http://gregmaxey.com/word_tips.html, 9/7/2017
Dim oRng As Range
Dim strIndexes As String
Dim oDocTemp As Document
Set oRng = Selection.Range
Application.ScreenUpdating = False
strIndexes = InputBox("Enter the document table index number e.g., " _
& "2 (for second table in document) followded by a comma then the column " _
& "index number e.g, 2,3 (for the third column in second table)", "Table/Column Index")
On Error GoTo Err_Indexes
If IsNumeric(Split(strIndexes, ",")(0)) And IsNumeric(Split(strIndexes, ",")(1)) Then
ActiveDocument.Tables(Split(strIndexes, ",")(0)).Columns(Split(strIndexes, ",")(1)).Select
Selection.Copy
Set oDocTemp = Documents.Add(, , , False)
oDocTemp.Range.Paste
MsgBox oDocTemp.Range.ComputeStatistics(wdStatisticWords)
oDocTemp.Close wdDoNotSaveChanges
Application.ScreenUpdating = True
oRng.Select
Else
Err_Indexes:
MsgBox "Invalid table\column index"
If Not oDocTemp Is Nothing Then oDocTemp.Close wdDoNotSaveChanges
End If
lbl_Exit:
Exit Sub
End Sub

gmaxey
09-07-2017, 09:06 PM
Paul,

That doesn't work for me. I would have to revise i by the numbe of cells in the table. Here is a modified version of your code:

Revised. Paul, the code below worked for one test table, but with a different table the word count was off by one. I'm not sure that it can work at all. Did you test your method?


Sub ScratchMacroII()
'Adaptation of Paul's code.
Dim oRng As Range
Dim strIndexes As String
Set oRng = Selection.Range
Application.ScreenUpdating = False
strIndexes = InputBox("Enter the document table index number e.g., " _
& "2 (for second table in document) followded by a comma then the column " _
& "index number e.g, 2,3 (for the third column in second table)", "Table/Column Index")
On Error GoTo Err_Indexes
If IsNumeric(Split(strIndexes, ",")(0)) And IsNumeric(Split(strIndexes, ",")(1)) Then
ActiveDocument.Tables(Split(strIndexes, ",")(0)).Columns(Split(strIndexes, ",")(1)).Select
MsgBox Selection.Range.Words.Count - (ActiveDocument.Tables(Split(strIndexes, ",")(0)).Range.Cells.Count - 1)
oRng.Select
Application.ScreenUpdating = True
Else
Err_Indexes:
MsgBox "Invalid table\column index"
End If
lbl_Exit:
Exit Sub
End Sub

macropod
09-07-2017, 09:42 PM
There is a more fundamental issue with the Selection method, which I should have mentioned, which is that .Words.Count includes punctuation marks, paragraph breaks, and end-of-cell markers in the count. I can't see how you come to the conclusion it's counting other cells, though. Hence the second macro I posted.

gmaxey
09-08-2017, 04:42 AM
Sometimes it counts the other cell markers and sometimes it doesn't. The fundamental conclusion that I came to is that it didn't work. Thanks for the alternate solution.

Kilroy
09-08-2017, 07:53 AM
So if I understand what's happening the code doesn't look for words it looks for groups of characters with a space before and after and this is why punctuations with a space on both sides is counted as a word? How do we not include punctuation, dash types, numbering bullets, etc.? I guess punctuation with a space on either side is just a mistake so it wouldn't really be a problem but maybe a more detailed list like:

Definitions:
words = (groups of letters possibly ending with punctuation with a space before and after)
Numbered paragraphs = (any paragraph numbered using the number list button which would include multi-level lists)
Bulleted point = (any list with any type of bullets using the bullet button which would include multi-level lists)
Punctuation error = (any punctuation mark with a space before and after)

There are "x amount" of words
There are "x amount" of numbered paragraphs
There are "x amount" of bulleted points
There are "x amount" of punctuation errors

Maybe this is to complicated?

gmaxey
09-08-2017, 08:50 AM
Kilroy,

In addition to not really knowing what a word is, Word doesn't know what a sentence is either.

Very complicated and likely never perfect.

You could use my http://gregmaxey.com/word_tip_pages/word_usage_and_frequency_report.html to create a list of words that excluded things like " , "

davidov
09-08-2017, 10:07 AM
Neither Paul's first code in Post#6 nor Greg's Post#8 are giving me the correct count.

I've been trying various count methods and ComputeStatistics(wdStatisticWords) is the only one that gets the count dead right every time. Seems like it is never thrown by any punctuation including hyphenated words, em dashes, bullets, odd characters etc, so for word counts I would insist on that method.

macropod
09-08-2017, 02:51 PM
So if I understand what's happening the code doesn't look for words it looks for groups of characters with a space before and after and this is why punctuations with a space on both sides is counted as a word?
That's what .Words.Count does, but not .ComputeStatistics(wdStatisticWords). Neither includes automatic numbers or bullets.

gmaxey
09-09-2017, 05:06 AM
Regardless, neither is guaranteed to return a count that is accurate considering what many people would consider a "word"


Sub ScratchMacro()
'A basic Word macro coded by Greg Maxey, http://gregmaxey.com/word_tips.html, 9/9/2017
Dim oRng As Range
Set oRng = Selection.Range
oRng.Text = "This is , a test"
MsgBox oRng.Words.Count
MsgBox oRng.ComputeStatistics(wdStatisticWords)
lbl_Exit:
Exit Sub
End Sub

Kilroy
09-11-2017, 04:50 AM
Thanks for the extra responses guys very informative.