Yes, and it's not all that hard. The issue, though, is that there's an awful lot of information that can be extracted and most of it probably wouldn't be of any particular interest. Did you look at how many attributes can be applied to a Style? That's why
I suggested extracting just the attributes you're interested in. Knowing which attributes you're interested in also narrows down how many comparisons need to be done against a given Style in order to know whether hard formatting to attributes of interest has
been applied.
The following macro extracts variations from the underlying Style for just the most common paragraph formatting attributes (i.e. not including font details) to a new Excel workbook. As you can see, it's already quite lengthy. The output lists every paragraph,
by number, including it's underlying Style and any of the specified departures from it.
Sub ParaHardFmtXtract()
Application.ScreenUpdating = False
Dim StrData As String, StrSty As String, Sty As Style
Dim i As Long, j As Long, k As Long, bTabOK As Boolean, Rng As Range
Dim xlApp As Object, xlWkBk As Object, StrRecord As String
StrData = "Paragraph #,Style,Alignment,Borders.Enable,KeepTogether,KeepWithNext,LeftIndent,"
StrData = StrData & "LineSpacing,LineSpacingRule,OutlineLevel,PageBreakBefore,RightIndent,"
StrData = StrData & "Shading.BackgroundPatternColor,.Shading.ForegroundPatternColor,Shading.Texture,"
StrData = StrData & "SpaceAfter,SpaceBefore,TabStops.Count,WidowControl,TabStop Discrepancies"
With ActiveDocument.Range
For i = 1 To .Paragraphs.Count
With .Paragraphs(i)
StrSty = .Style
StrData = StrData & vbCr & i & "," & StrSty
Set Sty = ActiveDocument.Styles(StrSty)
If Sty.ParagraphFormat.Alignment <> .Alignment Then
StrData = StrData & "," & .Alignment
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.Borders.Enable <> .Borders.Enable Then
StrData = StrData & "," & .Borders.Enable
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.KeepTogether <> .KeepTogether Then
StrData = StrData & "," & .KeepTogether
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.KeepWithNext <> .KeepWithNext Then
StrData = StrData & "," & .KeepWithNext
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.LeftIndent <> .LeftIndent Then
StrData = StrData & "," & .LeftIndent
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.LineSpacing <> .LineSpacing Then
StrData = StrData & "," & .LineSpacing
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.LineSpacingRule <> .LineSpacingRule Then
StrData = StrData & "," & .LineSpacingRule
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.OutlineLevel <> .OutlineLevel Then
StrData = StrData & "," & .OutlineLevel
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.PageBreakBefore <> .PageBreakBefore Then
StrData = StrData & "," & .PageBreakBefore
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.RightIndent <> .RightIndent Then
StrData = StrData & "," & .RightIndent
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.Shading.BackgroundPatternColor <> .Shading.BackgroundPatternColor Then
StrData = StrData & "," & .Shading.BackgroundPatternColor
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.Shading.ForegroundPatternColor <> .Shading.ForegroundPatternColor Then
StrData = StrData & "," & .Shading.ForegroundPatternColor
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.Shading.Texture <> .Shading.Texture Then
StrData = StrData & "," & .Shading.Texture
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.SpaceAfter <> .SpaceAfter Then
StrData = StrData & "," & .SpaceAfter
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.SpaceBefore <> .SpaceBefore Then
StrData = StrData & "," & .SpaceBefore
Else
StrData = StrData & ","
End If
With ActiveDocument.Range
.InsertAfter vbCr
Set Rng = .Paragraphs.Last.Range
End With
Rng.Style = StrSty
If Rng.Paragraphs(1).TabStops.Count <> .TabStops.Count Then
StrData = StrData & "," & .TabStops.Count
Else
StrData = StrData & ","
End If
If Sty.ParagraphFormat.WidowControl <> .WidowControl Then
StrData = StrData & "," & .WidowControl
Else
StrData = StrData & ","
End If
For j = 1 To .TabStops.Count
bTabOK = False
For k = 1 To Rng.Paragraphs(1).TabStops.Count
If Rng.Paragraphs(1).TabStops(k).Position = .TabStops(j).Position And _
Rng.Paragraphs(1).TabStops(k).Alignment = .TabStops(j).Alignment And _
Rng.Paragraphs(1).TabStops(k).Leader = .TabStops(j).Leader Then
bTabOK = True
Exit For
End If
Next
With .TabStops(j)
If bTabOK = False Then StrData = StrData & "," & .Position & " | " & .Alignment & " | " & .Leader
End With
Next
Rng.Delete
End With
Next
End With
'Create an Excel session
Set xlApp = CreateObject("Excel.Application")
If xlApp Is Nothing Then
MsgBox "Can't start Excel.", vbExclamation
Exit Sub
End If
With xlApp
.Visible = True
Set xlWkBk = .Workbooks.Add
If xlWkBk Is Nothing Then
MsgBox "Cannot create a workbook", vbExclamation
Exit Sub
End If
' Update the workbook.
With xlWkBk
With .Worksheets(1)
' Output the captured data.
For i = 0 To UBound(Split(StrData, vbCr))
StrRecord = Trim(Split(StrData, vbCr)(i))
For j = 0 To UBound(Split(StrRecord, ","))
.Cells(i + 1, j + 1).Value = Trim(Split(StrRecord, ",")(j))
Next
Next
End With
' Tell the user we're done.
MsgBox "Workbook updates finished.", vbOKOnly
End With
End With
' Release object memory
Set xlWkBk = Nothing: Set xlApp = Nothing
Application.ScreenUpdating = True
End Sub
One of the challenges with fonts is that the text may be partly or wholly in a different typeface, point size, italicized, underlined, bolded, superscripted, subscripted and/or hidden, whether via the application of character Styles or via hard formatting.
A given paragraph will thus have the attributes belonging to its paragraph Style and could include any number of departures from that via character Styles or via hard formatting. The question then becomes one of at what point is the paragraph considered to
no longer conform to its Style. Identification might come down to testing every character in a given paragraph. That part is relatively straightforward but one then has to consider how all of this can be reported in a meaningful way...