does anyone know how to encode subscripts?

kylefoley76

Well-known Member
Joined
Mar 1, 2010
Messages
1,553
I need to write things like H2O in the Excel but 2 of course being subcripted. Does anyone know how to code for that in VBA?
 
Ah -- two sets of unbalanced braces ...
 
Upvote 0

Excel Facts

Lock one reference in a formula
Need 1 part of a formula to always point to the same range? use $ signs: $V$2:$Z$99 will always point to V2:Z99, even after copying
Revised for generality ...
Shg: The IsBalanced function returns False for the typical chemical reaction below because the slash in 1/2 has no balancing backslash:

H/2\ + 1/2 O/2\ --> H/2\O

Rick: Why no closing backslash on P/1\Sn/2\C/3\Pb/4\ ?
 
Upvote 0
Once more:

Code:
Sub main()
    SubScr ActiveSheet.Cells
End Sub

Sub SubScr(rInp As Range)
    ' subscripts characters bracketed by open and closing braces
    ' ignores nesting

    Const sOpn      As String * 1 = "/"
    Const sCls      As String * 1 = "\"

    Dim rFind       As Range
    Dim sInp        As String
    Dim dic         As Object

    Dim ab()        As Boolean
    Dim b           As Boolean

    Dim sOut        As String
    Dim iRd         As Long
    Dim iWr         As Long
    
    Set dic = CreateObject("Scripting.Dictionary")
    Set rFind = rInp.Find(What:=sOpn, LookIn:=xlValues, LookAt:=xlPart)
    If Not rFind Is Nothing Then

        Do While Not rFind Is Nothing
            With rFind
                sInp = .Text
                If IsBalanced(sInp, sOpn, sCls) Then
                    iWr = 0
                    sOut = Replace(Replace(sInp, sOpn, ""), sCls, "")
                    ReDim ab(1 To Len(sOut))

                    For iRd = 1 To Len(sInp)
                        Select Case Mid(sInp, iRd, 1)
                            Case sOpn
                                b = True
                            Case sCls
                                b = False
                            Case Else
                                iWr = iWr + 1
                                ab(iWr) = b
                        End Select
                    Next iRd

                    .Value = sOut

                    For iWr = 1 To Len(sOut)
                        If ab(iWr) Then .Characters(iWr, 1).Font.Subscript = True
                    Next iWr

                Else
                    If dic.exists(.Address) Then Exit Do
                    dic.Add Key:=.Address, Item:=Nothing
                    .Interior.Color = vbYellow
                End If
            End With

            Set rFind = Cells.FindNext(rFind)
        Loop
    End If
End Sub

Function IsBalanced(sInp As String, sOpn As String, sCls As String) As Boolean
    ' returns True if sInp has balanced opening and closing braces

    Dim i           As Long
    Dim n           As Long

    For i = 1 To Len(sInp)
        Select Case Mid(sInp, i, 1)
            Case sOpn
                n = n + 1
            Case sCls
                n = n - 1
                If n < 0 Then Exit Function
        End Select
    Next i

    IsBalanced = n = 0
End Function

Thanks for the catch, Rick.
 
Upvote 0
Shg: The IsBalanced function returns False for the typical chemical reaction below because the slash in 1/2 has no balancing backslash:

H/2\ + 1/2 O/2\ --> H/2\O
You need to choose brace characters that are not otherwise used-- curly braces, brackets, whatever. Based on the OP's prior questions, I don't think this is about chemistry.
 
Upvote 0
You need to choose brace characters that are not otherwise used-- curly braces, brackets, whatever. Based on the OP's prior questions, I don't think this is about chemistry.

Agreed, just wanted to give a a heads up for those who might want to apply such a nice piece of code to such cases.
 
Upvote 0
Fair point, Joe

In a related vein, the code doesn't support subscrpting either of the brace characters.
 
Upvote 0
In the last code posted, this ...

Code:
Set rFind = Cells.FindNext(rFind)

... should be ...

Code:
Set rFind = rInp.FindNext(rFind)
 
Upvote 0
Testing is underrated ...

Code:
Sub main()
    SubScr ActiveSheet.Cells
End Sub

Sub SubScr(rInp As Range)
    ' subscripts characters bracketed by open and closing braces
    ' ignores nesting

    Const sOpn      As String * 1 = "/"
    Const sCls      As String * 1 = "\"

    Dim rFind       As Range
    Dim sInp        As String
    Dim dic         As Object

    Dim ab()        As Boolean
    Dim b           As Boolean

    Dim sOut        As String
    Dim iRd         As Long
    Dim iWr         As Long

    Set dic = CreateObject("Scripting.Dictionary")
    Set rFind = rInp.Find(What:=sOpn, LookIn:=xlValues, LookAt:=xlPart)
    
    Do While Not rFind Is Nothing
        With rFind
            sInp = .Text
            If IsBalanced(sInp, sOpn, sCls) Then
                iWr = 0
                sOut = Replace(Replace(sInp, sOpn, ""), sCls, "")
                ReDim ab(1 To Len(sOut))

                For iRd = 1 To Len(sInp)
                    Select Case Mid(sInp, iRd, 1)
                        Case sOpn
                            b = True
                        Case sCls
                            b = False
                        Case Else
                            iWr = iWr + 1
                            ab(iWr) = b
                    End Select
                Next iRd

                .Value = sOut

                For iWr = 1 To Len(sOut)
                    If ab(iWr) Then .Characters(iWr, 1).Font.Subscript = True
                Next iWr

            Else
                If dic.exists(.Address) Then Exit Do
                dic.Add Key:=.Address, Item:=Nothing
                .Interior.Color = vbYellow
            End If
        End With

        Set rFind = rInp.FindNext(rFind)
    Loop
End Sub

Function IsBalanced(sInp As String, sOpn As String, sCls As String) As Boolean
    ' returns True if sInp has balanced opening and closing braces

    Dim i           As Long
    Dim n           As Long

    For i = 1 To Len(sInp)
        Select Case Mid(sInp, i, 1)
            Case sOpn
                n = n + 1
            Case sCls
                n = n - 1
                If n < 0 Then Exit For
        End Select
    Next i

    IsBalanced = n = 0
End Function
 
Upvote 0
Here is my take on coding for this question (it does like shg's code and marks improperly formed text yellow)...

Code:
Sub SubscriptBetweenBackwardForwardSlashes()
  Dim X As Long, R As Long, C As Long, BS As Long, FS As Long, Data As Variant, Temp As String
  If ActiveSheet.UsedRange.Address(0, 0) = "A1" And Len(Range("A1").Value) = 0 Then Exit Sub
  Data = Range("A1").Resize(Cells.Find("*", , xlValues, , xlRows, xlPrevious).Offset(1).Row, _
         Cells.Find("*", , xlValues, , xlByColumns, xlPrevious).Offset(, 1).Column)
  Application.ScreenUpdating = False
  For R = 1 To UBound(Data)
    For C = 1 To UBound(Data, 2)
      If Len(Data(R, C)) Then
        Temp = Data(R, C)
        For X = 1 To Len(Temp)
          If Mid(Temp, X, 1) Like "[!/\]" Then Mid(Temp, X, 1) = " "
        Next
        Temp = Replace(Temp, " ", "")
        If Temp Like "*//*" Or Temp Like "*\\*" Or UBound(Split(Temp, "/")) <> UBound(Split(Temp, "\")) Then
          Cells(R, C).Interior.ColorIndex = 6
        Else
          FS = InStrRev(Cells(R, C).Value, "/")
          Do While FS
            BS = InStr(FS, Cells(R, C).Value, "\")
            Cells(R, C).Characters(FS, BS - FS + 1).Text = Cells(R, C).Characters(FS + 1, BS - FS - 1).Text
            Cells(R, C).Characters(FS, BS - FS - 1).Font.Subscript = True
            FS = InStrRev(Cells(R, C).Value, "/", FS - 1)
          Loop
        End If
      End If
    Next
  Next
  Application.ScreenUpdating = True
End Sub
 
Upvote 0

Forum statistics

Threads
1,215,329
Messages
6,124,301
Members
449,149
Latest member
mwdbActuary

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top