View Full Version : Solved: Format fractions
Paul_Hossler
04-20-2012, 06:31 PM
I picked up a little macro that will reformat an appropriate selection, i.e. 
 
if you select 22/7 then the macro will superscript the 22, insert a fraction-slash and subscript the 7.
 
But ... the 'smart selection' will include the paragraph and subscript that.
 
If I leave a space, it will subscript that, and then typing will be in subscript
 
I'm stuck trying to figure out how to have the macro ignore the leading and trailing white space if it's part of the selection:
 
22/7<p> selected then only the 22/7
 
22/7 is the value for pi .... only the 22/7, with out the space
 
 
Sub FmtFraction()
    Dim sFraction() As String
    Dim sChar As String
    'Check if a fraction is selected and if not show a warning and exit
    If InStr(Selection, "/") = False Then
         MsgBox "No fraction selected!", _
        vbCritical, "Format Fraction"
        Exit Sub
    End If
    'Define a new slash character
    sChar = ChrW(&H2044)
    'Split the original fraction at the slash character
    sFraction = Split(Selection, "/")
    'Reformat the fraction using super and subscript
    With Selection
         .Font.Superscript = True
        .TypeText Text:=sFraction(0)
        .Font.Superscript = False
        .TypeText Text:=sChar
        .Font.Subscript = True
        .TypeText Text:=sFraction(1)
        .Font.Subscript = False
    End With
End Sub
 
Thanks
 
Paul
macropod
04-21-2012, 02:27 AM
You could use something like:
Sub Fraction()
Dim RngTmp As Range, StrFrac
With Selection
  If Not .Characters.First.Text Like "[0-9]" Then Exit Sub
  If InStr(.Text, "/") < 2 Then
        MsgBox "No fraction selected!", _
        vbCritical, "Format Fraction"
        Exit Sub
    End If
  StrFrac = Split(.Text, "/")
  Set RngTmp = .Range
  With RngTmp
    While Not .Characters.Last.Text Like "[0-9]"
      .End = .End - 1
    Wend
    .InsertAfter " "
    .End = .End - 1
    .Font.Size = .Font.Size * 0.875
    .End = .Start + Len(StrFrac(0))
    .Font.Superscript = True
    .Characters.Last.Next.Font.Italic = True
    .End = .End + 2 + Len(StrFrac(1))
    .Start = .End - Len(StrFrac(1)) - 1
    .Font.Subscript = True
    .Collapse wdCollapseEnd
    .Start = .Start - 1
    .Text = vbNullString
  End With
End With
Set RngTmp = Nothing
End Sub
Paul_Hossler
04-21-2012, 07:51 AM
Hi Paul, thanks for the thoughts
 
Ignore this post.
 
I did better on my second try (below)
 
 
Paul
Paul_Hossler
04-21-2012, 08:05 AM
Paul
 
My next effort. This time I paid closer attention to some of your techniques, and incorporated them.
 
I 'think' it works, at least my tests so far
 
Sub FmtFraction2()
    Dim sFraction() As String
 
     'Check if a fraction is selected and if not show a warning and exit
    If InStr(Selection, "/") = 0 Then
        MsgBox "No fraction selected!", vbCritical, "Format Fraction"
        Exit Sub
    End If
 
 
    'Reformat the fraction using super and subscript
    With Selection
 
        While Not .Characters.Last.Text Like "[0-9,a-z,A-Z]"
            .End = .End - 1
        Wend
 
        'Split the original fraction at the slash character
        sFraction = Split(Selection, "/")
 
        .Font.Superscript = True
        .TypeText Text:=sFraction(0)
        .Font.Superscript = False
 
        .TypeText Text:=ChrW(&H2044)
 
        .Font.Subscript = True
        .TypeText Text:=sFraction(1)
        .Font.Subscript = False
    End With
End Sub
 
 
Paul (the other one)
macropod
04-21-2012, 02:52 PM
Hi Paul,
 
Amongst other things, my previous approach:
• reduced the font size to approximately 7/8ths of the original. IMHO it looks better that way.
• checked that there's at least a numerator character before the '/' (your's only checks for the '/')
• only stripped off non-numeric final characters (your's now strips off letters as well).
• added a temporary space after the fraction, so that any tab, space, paragraph mark, etc, didn't get the denominator's subscript (which is what you were concerned about)
 
The new version below:
• does all except the last of the above (the effects of which I've achieved differently)
• resizes the font more consistently - in 0.5pt increments
• tests for a numeric numerator and a numeric denominator. It's still possible to have a selection that incorporates other content (eg 8 abc 1/3 def 9), but I don't think I really need to code for that. Besides, your code seems to intentionally allow alpha characters. 
Sub Fraction()
Dim RngTmp As Range, StrFrac
With Selection
  If InStr(.Text, "/") < 2 Then GoTo ErrMsg
  While Not .Characters.Last.Text Like "[0-9]"
    .End = .End - 1
    If .Start + InStr(.Text, "/") = .End Then GoTo ErrMsg
  Wend
  While Not .Characters.First.Text Like "[0-9]"
    .Start = .Start + 1
    If .Start = .End Or InStr(.Text, "/") = 0 Then GoTo ErrMsg
  Wend
  StrFrac = Split(.Text, "/")
  Set RngTmp = .Range
  With RngTmp
    .Font.Size = Round(.Font.Size * 1.75) / 2
    .End = .Start + Len(StrFrac(0))
    .Font.Superscript = True
    .Characters.Last.Next.Font.Italic = True
    .End = Selection.End
    .Start = .Start + InStr(.Text, "/")
    .Font.Subscript = True
  End With
End With
Set RngTmp = Nothing
Exit Sub
ErrMsg:
MsgBox "No fraction selected!", vbCritical, "Format Fraction"
End Sub
Paul_Hossler
04-21-2012, 06:54 PM
hi Paul -- thanks for the updated code. I think that you've pointed out some things that I hadn't considered enough
 
I did include the letters since I thought it might be nice to allow things like
 
North/East as a fraction
 
Paul
Tinbendr
04-23-2012, 06:16 AM
Paul,
 
Have you considered equations?
 
Sub test2()
Dim objRange As Range
Dim objEq As OMath
Set objRange = Selection.Range
objRange.Text = "Celsius = (5/9)(Fahrenheit – 32)"
Set objRange = Selection.OMaths.Add(objRange)
Set objEq = objRange.OMaths(1)
objEq.BuildUp
End Sub
macropod
04-23-2012, 02:46 PM
Have you considered equations?
Yeah, but they're not available for Word 2003 & earlier. I could have used EQ fields too, but why complicate things?
Paul_Hossler
04-23-2012, 03:42 PM
David -- Word 2010 has the interactive Inset Equation feature, and the EQ fields, but I figured for the simple things I was looking to do, that'd be like hunting flies with a sledge hammer.
 
Paul -- thanks for the ideas and the tips. I think I can live with this. It's not perfect, but it seems to handle the simple cases I run accross (at least so far)
 
 
Sub FmtFraction3()
    Dim sFraction() As String
 
    On Error GoTo NotFraction
 
    'Reformat the fraction using super and subscript
    With Selection
 
        If InStr(.Text, "/") < 2 Then
            Call Err.Raise(10001, "FormatFraction", "Selection is not formatted like a fraction (123/456)")
        End If
 
        While Not .Characters.Last.Text Like "[0-9]"
            .End = .End - 1
            If .Start + InStr(.Text, "/") = .End Then
                Call Err.Raise(10002, "FormatFraction", "Denominator is missing")
            End If
        Wend
        While Not .Characters.First.Text Like "[0-9]"
            .Start = .Start + 1
            If .Start = .End Or InStr(.Text, "/") = 0 Then
                Call Err.Raise(10003, "FormatFraction", "Numerator is missing")
            End If
        Wend
 
 
        'Split the original fraction at the slash character
        sFraction = Split(Selection, "/")
 
        .Font.Superscript = True
        .TypeText Text:=sFraction(0)
        .Font.Superscript = False
 
        .TypeText Text:=ChrW(&H2044)
 
        .Font.Subscript = True
        .TypeText Text:=sFraction(1)
        .Font.Subscript = False
 
    End With
    Exit Sub
 
NotFraction:
    Call MsgBox(Err.Description & " (Err#" & Err.Number & ")", vbCritical, "Format Fraction")
 
    Err.Clear
End Sub
 
Paul
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.