+ Reply to Thread
Results 1 to 12 of 12

Userform textbox, account for Backspace and Delete

Hybrid View

  1. #1
    Forum Contributor
    Join Date
    11-10-2009
    Location
    Perth, Australia
    MS-Off Ver
    Excel 2007
    Posts
    549

    Userform textbox, account for Backspace and Delete

    This userform edits cell contents as you type, while preserving the font.

    The initiation starts at the class module "clsTextBox". There are two methods. (1) "MyTextBox_Change" is used when the cursor is placed somewhere before typing begins. (2) "MyTextBox_KeyPress" is used if part of the text is highlighted before typing.

    There is an issue if the BACKSPACE or DELETE key is used, it throws out the fonts.

    Is there a way to capture the BACKSPACE and DELETE event? So I can write a separate module for this.



    CLASS MODULE clsTextBox
    Private WithEvents MyTextBox As MSForms.TextBox
    
    Public Property Set Control(tb As MSForms.TextBox)
        Set MyTextBox = tb
    End Property
    
    Private Sub MyTextBox_Change()
        Call UserFormFormulas.transfer(MyTextBox.SelLength)
    End Sub
    
    Private Sub MyTextBox_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
        Call UserFormFormulas.transfertwo(MyTextBox.SelLength)
    End Sub

    FORM CODE
    Option Explicit
    
    Private WithEvents MyApplication As Excel.Application
    Public WithEvents cDelegate As ClassFormulasDelegate
    Private TextBoxes As Collection
    Private mActiveTextBox As MSForms.TextBox
    Dim Buttons() As New ClassFormulasEvents
    
    Private mTxtBoxes As Collection
    Dim tbCollection As Collection
    
    'INITIALIZE
    Private Sub UserForm_Initialize()
        Set cDelegate = New ClassFormulasDelegate
        Call FormCreation(True)
        
        Dim ctrl As MSForms.Control
        Dim obj As clsTextBox
        Set tbCollection = New Collection
            For Each ctrl In Me.Controls
                If TypeOf ctrl Is MSForms.TextBox Then
                    Set obj = New clsTextBox
                    Set obj.Control = ctrl
                    tbCollection.Add obj
                End If
            Next ctrl
        Set obj = Nothing
    End Sub
    
    'ACTIVATE
    Private Sub UserForm_Activate()
        ButtonExit.SetFocus
    End Sub
    
    'CREATE FORM
    Private Sub FormCreation(BuildButtons As Boolean)
        Dim cEvents As ClassFormulasEvents
        Dim Box As MSForms.TextBox
        Dim BoxTop As Long, BoxHeight As Long, BoxLeft As Long, BoxWidth As Long, BoxGap As Long
        Dim BoxName As String
        Dim cell As Range
        Dim MultiPageHeight As Double
        Dim MyControl As MSForms.Control
        Dim ButtonCount As Integer
        Dim index As Long
        'Introduction
        Set MyApplication = Application
        BoxHeight = 24: BoxTop = 0: BoxLeft = 0: BoxWidth = 388: BoxGap = 0
        index = 1
        If TextBoxes Is Nothing Then Set TextBoxes = New Collection
        'Create textboxes
        For Each cell In MyApplication.Selection
            If Not IsEmpty(cell) Then
                If index > TextBoxes.Count Then
                    Set cEvents = New ClassFormulasEvents
                    Set cEvents.cDelegate = cDelegate
                    BoxName = "TextBox" & index
                    Set Box = Me.TextBoxFrame.Controls.Add("Forms.Textbox.1", BoxName, True)
                    Set cEvents.TextBoxGo = Box
                    TextBoxes.Add cEvents
                Else
                    Set Box = TextBoxes(index).TextBoxGo
                End If
                With Box
                    .Height = BoxHeight: .top = BoxTop: .Left = BoxLeft: .width = BoxWidth
                    .Font.Size = 12
                    .Text = cell.Formula
                    .AutoWordSelect = False
                End With
                index = index + 1
                BoxTop = BoxTop + BoxHeight + BoxGap
            End If
        Next
        'Remove extra textboxes
        Do While TextBoxes.Count > index
            TextBoxes.Remove TextBoxes.Count
        Loop
        'Size form for variable conditions
        Me.Height = BoxTop + MultiPageHeight + 148 'TRIAL & ERROR
        TextBoxFrame.Height = BoxTop
        'Create Command Button objects
        If BuildButtons Then
            ButtonCount = 0
            For Each MyControl In Me.Controls
                If TypeName(MyControl) = "CommandButton" Then
                    ButtonCount = ButtonCount + 1
                    ReDim Preserve Buttons(1 To ButtonCount)
                    Set Buttons(ButtonCount).ButtonGroup = MyControl
                End If
            Next MyControl
        End If
    End Sub
    
    'RECEIVING EVENT
    Private Sub cDelegate_TextBoxGoChanged(TextBoxGo As MSForms.TextBox)
        Set mActiveTextBox = TextBoxGo
    End Sub
    
    'INSERT CHARACTERS
    Public Sub InsertCharacter(CharacterType As String) 'Public since called  from Class Module
        Dim TextBox As MSForms.TextBox
        Dim cell As Range
        Dim CursorLocation As Long
        Dim index As Long
        index = 1
        If mActiveTextBox Is Nothing Then
            Exit Sub 'To prevent error message
        End If
        For Each cell In MyApplication.Selection
            If Not IsEmpty(cell) Then
                If TextBoxes(index).TextBoxGo.Name = mActiveTextBox.Name Then
                    With mActiveTextBox
                        CursorLocation = .SelStart
                        'Insert character General Case
                        cell.Characters(.SelStart + 1, 0).Insert CharacterType
                        mActiveTextBox.Text = Left(.Text, .SelStart) & CharacterType & Mid(.Text, .SelStart + 1)
                        .SelStart = CursorLocation + Len(CharacterType)
                        .SetFocus 'Prevents the cursor from disappearing
                    End With
                End If
            index = index + 1
            End If
            Next
    End Sub
    
    Sub transfer(SelectionCount As Long)
        Dim TextBox As MSForms.TextBox
        Dim cell As Range
        Dim CursorLocation As Long, cursorplaceholder As Long
        Dim characterarray() As String
        Dim fontarray() As String
        Dim index As Long
        Dim i As Long, j As Long
        index = 1
        For Each cell In MyApplication.Selection
            Application.ScreenUpdating = False
            If Not IsEmpty(cell) Then
                If TextBoxes(index).TextBoxGo.Name = mActiveTextBox.Name Then
                    With mActiveTextBox
    CursorLocation = .SelStart
    cursorplaceholder = CursorLocation
    ReDim characterarray(Len(cell) - 1)
    ReDim fontarray(Len(cell) - 1)
                    For i = 1 To Len(cell)
                        characterarray(i - 1) = Mid$(cell, i, 1)
                        fontarray(i - 1) = cell.Characters(i, 1).Font.Name
                    Next
    'Transfer to cell
    cell.value = mActiveTextBox.value
    'Restore fonts
    If SelectionCount = 0 Then
        If cursorplaceholder = 1 Then
        cell.Characters(1, 1).Font.Name = fontarray(0)
            For i = cursorplaceholder + 1 To Len(cell)
            cell.Characters(i, 1).Font.Name = fontarray(i - 2)
            Next
        End If
        If cursorplaceholder > 1 Then
            For i = 1 To cursorplaceholder - 1
            cell.Characters(i, 1).Font.Name = fontarray(i - 1)
            Next
            For i = cursorplaceholder To Len(cell)
            cell.Characters(i, 1).Font.Name = fontarray(i - 2)
            Next
        End If
    End If
    If SelectionCount > 0 Then
    'do nothing
    End If
                    End With
                End If
            index = index + 1
            End If
            Application.ScreenUpdating = True
            Next
    End Sub
    
    
    Sub transfertwo(SelectionCount As Long)
      Dim TextBox As MSForms.TextBox
        Dim cell As Range
        Dim CursorLocation As Long, cursorplaceholder As Long
        Dim characterarray() As String
        Dim fontarray() As String
        Dim index As Long
        Dim i As Long, j As Long
        index = 1
        For Each cell In MyApplication.Selection
            Application.ScreenUpdating = False
            If Not IsEmpty(cell) Then
                If TextBoxes(index).TextBoxGo.Name = mActiveTextBox.Name Then
                    With mActiveTextBox
    CursorLocation = .SelStart
    cursorplaceholder = CursorLocation
    ReDim characterarray(Len(cell) - 1)
    ReDim fontarray(Len(cell) - 1)
                For i = 1 To Len(cell)
                    characterarray(i - 1) = Mid$(cell, i, 1)
                    fontarray(i - 1) = cell.Characters(i, 1).Font.Name
                Next
    'Transfer to cell
    'cell.value = mActiveTextBox.value
    
    'Restore fonts
                If SelectionCount = 0 Then
                'do nothing
                End If
                If SelectionCount > 0 Then
                    If cursorplaceholder > 1 Then
                        For i = 1 To cursorplaceholder - 1
                        cell.Characters(i, 1).Font.Name = fontarray(i - 1)
                        Next
                        For i = cursorplaceholder + SelectionCount - SelectionCount To Len(cell) - SelectionCount
                        cell.Characters(i, 1).Font.Name = fontarray(i - 1 + SelectionCount)
                        Next
                    End If
                End If
                    End With
                End If
            index = index + 1
            End If
            Application.ScreenUpdating = True
            Next
    End Sub
    
    'EXIT
    Private Sub ButtonExit_Click()
        Unload Me
    End Sub
    
    'TERMINATE
    Private Sub UserForm_Terminate()
        Dim Box As MSForms.TextBox
        Dim index As Long
        For index = TextBoxes.Count To 1 Step -1
            Me.TextBoxFrame.Controls.Remove TextBoxes(index).TextBoxGo.Name
            TextBoxes.Remove index
        Next
        Set TextBoxes = Nothing
        Set MyApplication = Nothing
    End Sub
    Attached Files Attached Files

  2. #2
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,653

    Re: Userform textbox, account for Backspace and Delete

    Trap it with the KeyDown event

    Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = 8 Or KeyCode = 46 Then KeyCode = 0 'Backspace or Del
    End Sub
    Surround your VBA code with CODE tags e.g.;
    [CODE]your VBA code here[/CODE]
    The # button in the forum editor will apply CODE tags around your selected text.

  3. #3
    Forum Contributor
    Join Date
    11-10-2009
    Location
    Perth, Australia
    MS-Off Ver
    Excel 2007
    Posts
    549

    Re: Userform textbox, account for Backspace and Delete

    This is creating an event, which is a good step forward.

  4. #4
    Forum Contributor
    Join Date
    11-10-2009
    Location
    Perth, Australia
    MS-Off Ver
    Excel 2007
    Posts
    549

    Re: Userform textbox, account for Backspace and Delete

    Is it possible to relay the "character typed" information to the Sub in the form code?

  5. #5
    Forum Contributor
    Join Date
    11-10-2009
    Location
    Perth, Australia
    MS-Off Ver
    Excel 2007
    Posts
    549

    Re: Userform textbox, account for Backspace and Delete

    I've tried to delete a selected portion of text with "KeyDown". It doesn't work.
    There seems to be a lag of one event. Pressing the second time shows the result for the first time, pressing for the third time shows the result for the second time, and so on.
    When I say it doesn't work, the selected string characters are not deleted, but the fonts are changed though.

    Private Sub MyTextBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = 8 Or KeyCode = 46 Then
            Call UserFormFormulas.transfertwoLess(MyTextBox.SelLength)
        End If
    End Sub
    Attached Files Attached Files

  6. #6
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,653

    Re: Userform textbox, account for Backspace and Delete

    With the KeyDown event, the textbox is not updated until after the event. So your transfertwoless procedure is not evaluating the most recent key press. It's evaluating the existing text that has not updated yet. I think you want you pass the KeyCode as an argument to transfertwoless and process the Backspace-Delete conditions. Alternatively, consider using the KeyUp event which the Textbox update before that event.

  7. #7
    Forum Moderator Leith Ross's Avatar
    Join Date
    01-15-2005
    Location
    San Francisco, Ca
    MS-Off Ver
    2000, 2003, & 2010
    Posts
    23,259

    Re: Userform textbox, account for Backspace and Delete

    Hello Un-Do Re-Do,

    To prevent the KeyCode from being processed, set it to zero. Sub-Classing is a FIFO stack oriented process. What does not get processed by your class will be passed along to the original class.

    Private Sub MyTextBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        If KeyCode = 8 Or KeyCode = 46 Then
             KeyCode = 0
            Call UserFormFormulas.transfertwoLess(MyTextBox.SelLength)
        End If
    End Sub
    Sincerely,
    Leith Ross

    Remember To Do the Following....

    1. Use code tags. Place [CODE] before the first line of code and [/CODE] after the last line of code.
    2. Thank those who have helped you by clicking the Star below the post.
    3. Please mark your post [SOLVED] if it has been answered satisfactorily.


    Old Scottish Proverb...
    Luathaid gu deanamh maille! (Rushing causes delays!)

  8. #8
    Forum Contributor
    Join Date
    11-10-2009
    Location
    Perth, Australia
    MS-Off Ver
    Excel 2007
    Posts
    549

    Re: Userform textbox, account for Backspace and Delete

    I've tried the suggestion at post #6 by passing the argument into the Sub (with "KeyDown"). I can't make it update in the Sub though.
    I did try "KeyUp" yesterday but this does not store the value of the SelectionCount, the number of selected characters. This was one of the other requirements which allowed the ability to type over a selected number of characters.
    "KeyPress" (when combined with MyTextBox_Change()) did update and restore fonts but unfortunately does not handle Delete.
    A summary is shown below.

    With the suggestion at post #7, the intention is to actually to implement the BackSpace and Delete, not prevent it.

    See attached workbook for latest working.

    Attachment 643760
    Attached Files Attached Files

  9. #9
    Forum Contributor
    Join Date
    11-10-2009
    Location
    Perth, Australia
    MS-Off Ver
    Excel 2007
    Posts
    549

    Re: Userform textbox, account for Backspace and Delete

    I've progressed this somewhat over a lengthy period.
    It's getting closer but still baffles.

    First, to explain the theme:
    The order of events is "KeyDown", "Change" of textbox, then "KeyUp". Public declarations are used to relay information between the three.

    KeyDown is required to capture the instance where a selection is made (highlight a number of characters and type over them). "Change" of textbox is used to transfer contents to cell, from which a new array of characters is manipulated. "KeyUp" is required since it handles Backspace and Delete and captures the event after the textbox change. This took me days to figure out ... using Debug.Print window.

    The code still does not work in instances such as Backspace and Delete. I can understand the details of what's happening however it still baffles me why the fonts are not restored correctly. The algorithm formulas look correct.

    Any further suggestions?

    CLASS MODULE (Part)
    Private Sub MyTextBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
            Call UserFormFormulas.TransferKeyDown(MyTextBox.SelLength, KeyCode)
    End Sub
    
    Private Sub MyTextBox_Change()
        Call UserFormFormulas.TransferBoxChange(MyTextBox.SelLength)
    End Sub
    
    
    Private Sub MyTextBox_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
    On Error Resume Next 'Important
        Call UserFormFormulas.TransferKeyUp(MyTextBox.SelLength, KeyCode)
    End Sub
    FORM CODE (Part)
    '(1)
    Sub TransferKeyDown(SelectionCount As Long, ByVal KeyCode As MSForms.ReturnInteger)
    
    Debug.Print "(1) KEY_DOWN"
    Debug.Print "Selection = " & SelectionCount & ", " & "Code = " & KeyCode & ", " & "Letter = " & Chr(KeyCode)
    
        Dim TextBox As MSForms.TextBox
        Dim cell As Range
        Dim CursorLocation As Long
        Dim characterarray() As String
        Dim index As Long
        Dim i As Long, j As Long
        index = 1
    
        KeyPressed = KeyCode 'Used in KeyUp
        SelectionCountHold = SelectionCount
    
        For Each cell In MyApplication.Selection
            If Not IsEmpty(cell) Then
                If TextBoxes(index).TextBoxGo.Name = mActiveTextBox.Name Then
                    With mActiveTextBox
                        CursorLocation = .SelStart
                        cursorHolder = CursorLocation
                        
    Debug.Print "Cursor = " & cursorHolder
    
                        ReDim characterarray(Len(cell) - 1)
                        ReDim fontarray(Len(cell) - 1)
                        For i = 1 To Len(cell)
                            characterarray(i - 1) = Mid$(cell, i, 1)
                            fontarray(i - 1) = cell.Characters(i, 1).Font.Name
                        Next
                        
                fontarrayOrig = fontarray 'Required when changing fonts in KeyUp
                     
    Debug.Print "Length of cell = " & Len(cell)
    'Debug.Print "Text = " & Join(characterarray, "")
    Debug.Print Join(fontarray, ", ")
                       
                    End With
                End If
            index = index + 1
            End If
        Next
        
    Debug.Print "------------------------------------------------------------------"
    
    End Sub
    
    
    '(2)
    Sub TransferBoxChange(SelectionCount As Long)
    
    Debug.Print "(2) TEXTBOX CHANGE"
    Debug.Print "Selection = " & SelectionCountHold
    
        Dim TextBox As MSForms.TextBox
        Dim cell As Range
        Dim characterarray() As String
        Dim index As Long
        Dim i As Long, j As Long
        index = 1
        For Each cell In MyApplication.Selection
            If Not IsEmpty(cell) Then
                If TextBoxes(index).TextBoxGo.Name = mActiveTextBox.Name Then
                    With mActiveTextBox
                        
    Debug.Print "Cursor = " & cursorHolder
    
                        ReDim characterarray(Len(cell) - 1)
                        ReDim fontarray(Len(cell) - 1)
                        For i = 1 To Len(cell)
                            characterarray(i - 1) = Mid$(cell, i, 1)
                            fontarray(i - 1) = cell.Characters(i, 1).Font.Name
                        Next
            
        '''Transfer to cell
        '''Use in Debug.Print if required as a guide
        '''Turn off to make it work when there is just a cursor, no selection
            'cell.value = mActiveTextBox.value
                        
    Debug.Print "Length of cell = " & Len(cell)
    'Debug.Print "Text = " & Join(characterarray, "")
    Debug.Print Join(fontarray, ", ")
    
                    End With
                End If
            index = index + 1
            End If
        Next
    
    Debug.Print "------------------------------------------------------------------"
    
    End Sub
    
    
    '(3)
    Sub TransferKeyUp(SelectionCount As Long, ByVal KeyCode As MSForms.ReturnInteger)
    
    Debug.Print "(3) KEY_UP"
    Debug.Print "Selection = " & SelectionCountHold & ", " & "Code = " & KeyCode & ", " & "Letter = " & Chr(KeyCode)
    
        Dim TextBox As MSForms.TextBox
        Dim cell As Range
        Dim CursorLocation As Long, cursorplaceholder As Long
        Dim characterarray() As String
        Dim fontarray() As String
        Dim index As Long
        Dim i As Long, j As Long
        index = 1
    
        For Each cell In MyApplication.Selection
            If Not IsEmpty(cell) Then
                If TextBoxes(index).TextBoxGo.Name = mActiveTextBox.Name Then
                    With mActiveTextBox
                        CursorLocation = .SelStart
                        cursorplaceholder = CursorLocation
    Debug.Print "Cursor = " & cursorHolder
                        
                        ReDim characterarray(Len(cell) - 1)
                        ReDim fontarray(Len(cell) - 1)
                        For i = 1 To Len(cell)
                            characterarray(i - 1) = Mid$(cell, i, 1)
                            fontarray(i - 1) = cell.Characters(i, 1).Font.Name
                        Next
                        
                        'Transfer to cell
                        cell.value = mActiveTextBox.value
                        
    '########################################################################################
    'RESTORE FONTS
    
    'If Backspace or Delete
    If KeyPressed = 8 Or KeyPressed = 46 Then
        For i = 1 To cursorHolder
            cell.Characters(i, 1).Font.Name = fontarrayOrig(i - 1)
        Next
        For i = cursorHolder + 1 To Len(cell)
            cell.Characters(i, 1).Font.Name = fontarrayOrig(i - 1 + SelectionCount)
        Next
    End If
              
    'If No Backspace or Delete (Typical)
    If KeyPressed <> 8 And KeyPressed <> 46 Then
        'If SelectionCountHold = 0 (cursor only, no selection)
        If SelectionCountHold = 0 Then
            If cursorplaceholder = 1 Then
                cell.Characters(1, 1).Font.Name = fontarray(0)
                For i = cursorplaceholder + 1 To Len(cell)
                    cell.Characters(i, 1).Font.Name = fontarray(i - 2)
                Next
            End If
            If cursorplaceholder > 1 Then
                For i = 1 To cursorplaceholder - 1
                    cell.Characters(i, 1).Font.Name = fontarray(i - 1)
                Next
                For i = cursorplaceholder To Len(cell)
                    cell.Characters(i, 1).Font.Name = fontarray(i - 2)
                Next
            End If
        End If
        'If SelectionCountHold = 1
        If SelectionCountHold = 1 Then
            For i = 1 To Len(cell)
                cell.Characters(i, 1).Font.Name = fontarrayOrig(i - 0)
            Next
        End If
        'If SelectionCountHold > 1
        If SelectionCountHold > 1 Then
            For i = 1 To cursorHolder + 1
                cell.Characters(i, 1).Font.Name = fontarrayOrig(i - 1)
            Next
            For i = cursorHolder + 2 To Len(cell)
                cell.Characters(i, 1).Font.Name = fontarrayOrig(i + SelectionCount)
            Next
        End If
    End If
    '########################################################################################
                         
                        ReDim fontarray(Len(cell) - 1)
                        For i = 1 To Len(cell)
                            fontarray(i - 1) = cell.Characters(i, 1).Font.Name
                        Next
                                      
    Debug.Print "Length of cell = " & Len(cell)
    'Debug.Print "Text = " & Join(characterarray, "")
    Debug.Print Join(fontarrayOrig, ", ")
    Debug.Print Join(fontarray, ", ")
    
                    End With
                End If
            index = index + 1
            End If
        Next
    
    Debug.Print "------------------------------------------------------------------"
    
    End Sub
    Attached Files Attached Files

  10. #10
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,653

    Re: Userform textbox, account for Backspace and Delete

    To easily associate a textbox with a cell, I put the cell address in the Textbox name. I then later extract the cell address from the name to reference the cell.

    Private Sub FormCreation(BuildButtons As Boolean)
    
            BoxName = "TextBox_" & cell.Address(0, 0)
    This seems to work though I didn't test it a lot.
    clsTextBox

    Dim strTextOriginal As String
    Dim arrFonts As Variant
    Dim lSelStart As Long
    Dim lSelLen As Long
    
    Private WithEvents MyTextBox As MSForms.TextBox
    
    Public Property Set Control(tb As MSForms.TextBox)
        Set MyTextBox = tb
    End Property
    
    Private Sub MyTextBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        'Call UserFormFormulas.TransferKeyDown(MyTextBox.SelLength, KeyCode)
            
        strTextOriginal = MyTextBox.Text
        lSelStart = MyTextBox.SelStart
        lSelLen = MyTextBox.SelLength
        
        With ActiveSheet.Range(Mid(MyTextBox.Name, 9)) 'Name of Textbox contains cell address
            If .value <> Empty Then
                ReDim arrFonts(1 To Len(.Text))
                For i = 1 To UBound(arrFonts)
                    arrFonts(i) = .Characters(i, 1).Font.Name
                Next
            Else
                Erase arrFonts
                'Default font for empty textbox
                ReDim arrFonts(1 To 1)
                arrFonts(1) = "Courier"
            End If
        End With
    End Sub
    
    Private Sub MyTextBox_Change()
        'Call UserFormFormulas.TransferBoxChange(MyTextBox.SelLength)
    End Sub
    
    
    Private Sub MyTextBox_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        Dim i As Long
        
        'ignore arrow keys, shift , etc.
        If MyTextBox.Text = strTextOriginal Then Exit Sub
        
        With ActiveSheet.Range(Mid(MyTextBox.Name, 9))    'Name of Textbox contains cell address
            
            Application.ScreenUpdating = False
            .value = MyTextBox.Text
            
            If lSelLen > 0 Then    ' if overwrite selected text
                For i = 1 To UBound(arrFonts)
                    If i <= lSelStart Or i > lSelStart + lSelLen Then
                        j = j + 1
                        .Characters(j, 1).Font.Name = arrFonts(i)
                    End If
                Next i
            ElseIf KeyCode = 8 Or KeyCode = 46 Then  'Backspace or Del (no selected text)
                For i = 1 To UBound(arrFonts)
                    If i < lSelStart Or i > lSelStart Then
                        j = j + 1
                        .Characters(j, 1).Font.Name = arrFonts(i)
                    End If
                Next i
            Else    'new character inserted
                For i = 1 To Len(MyTextBox.Text)
                    If i <= lSelStart Or i > lSelStart + 1 Or lSelStart = 0 Then j = j + 1
                    .Characters(i, 1).Font.Name = arrFonts(j)
                Next i
            End If
                
            Application.ScreenUpdating = True
        End With
    End Sub
    Last edited by AlphaFrog; 10-05-2019 at 08:06 AM.

  11. #11
    Forum Contributor
    Join Date
    11-10-2009
    Location
    Perth, Australia
    MS-Off Ver
    Excel 2007
    Posts
    549

    Re: Userform textbox, account for Backspace and Delete

    @AlphaFrog
    The code is much simpler and intuitive. I've tested with no selection (cursor only) and this works. It will need a tweak when there is a selection in the text box. It also accounts for Navigation keys (non text), which was another part I had to add to stop errors.
    Thanks for assisting.

    Incidentally with the code at post #9, the error for Backspace or Delete was due to the following:
    "SelectionCount" should have been "SelectionCountHold"

  12. #12
    Forum Guru
    Join Date
    07-25-2011
    Location
    Florida
    MS-Off Ver
    Excel 2003
    Posts
    9,653

    Re: Userform textbox, account for Backspace and Delete

    Here's a better version FWIW

    Private Sub MyTextBox_KeyUp(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
        Dim i As Long, j As Long
        
        'ignore arrow keys, shift , etc.
        If MyTextBox.Text = strTextOriginal Then Exit Sub
        
        With ActiveSheet.Range(Mid(MyTextBox.Name, 9))    'Name of Textbox contains cell address
            
            Application.ScreenUpdating = False
            .value = MyTextBox.Text
            
            If lSelLen > 0 Then    'Overwrite selected text
                For i = 1 To UBound(arrFonts)
                    If i <= lSelStart + IIf(KeyCode = 8 Or KeyCode = 46, 0, 1) Or i > lSelStart + lSelLen Then
                        j = j + 1
                        .Characters(j, 1).Font.Name = arrFonts(i)
                    End If
                Next i
            ElseIf KeyCode = 8 Then   'Backspace (no selected text)
                For i = 1 To UBound(arrFonts)
                    If i <> lSelStart Then
                        j = j + 1
                        .Characters(j, 1).Font.Name = arrFonts(i)
                    End If
                Next i
            ElseIf KeyCode = 46 Then  'Del (no selected text)
                For i = 1 To UBound(arrFonts)
                    If i <> lSelStart + 1 Then
                        j = j + 1
                        .Characters(j, 1).Font.Name = arrFonts(i)
                    End If
                Next i
            Else    'new character inserted
                For i = 1 To Len(MyTextBox.Text)
                    If lSelStart = 0 And i = 1 Then
                        .Characters(i, 1).Font.Name = arrFonts(1)
                    ElseIf i = lSelStart Then
                        .Characters(i, 1).Font.Name = arrFonts(i)
                    Else
                        j = j + 1
                        .Characters(i, 1).Font.Name = arrFonts(j)
                    End If
                Next i
            End If
                
            Application.ScreenUpdating = True
        End With
    End Sub
    Last edited by AlphaFrog; 10-06-2019 at 05:58 AM.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Similar Threads

  1. Masked Control Textbox entry field - backspace not working right
    By Arnold Layne in forum Excel Programming / VBA / Macros
    Replies: 2
    Last Post: 03-28-2019, 07:34 PM
  2. [SOLVED] How to allow TextBox backspace key?
    By VAer in forum Excel Programming / VBA / Macros
    Replies: 2
    Last Post: 02-08-2017, 09:34 AM
  3. [SOLVED] How to clear all text form textbox with one backspace (userform)
    By HaroonSid in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 01-16-2017, 12:36 PM
  4. [SOLVED] Narrowing Results in ListBox using TextBox that Reloads when Backspace is Struck
    By kak132 in forum Excel Programming / VBA / Macros
    Replies: 2
    Last Post: 07-24-2014, 12:10 PM
  5. [SOLVED] Userform: Backspace button and Shift key
    By Gal403 in forum Excel Programming / VBA / Macros
    Replies: 4
    Last Post: 03-08-2014, 03:25 AM
  6. Enable backspace key in combobox on Userform
    By bdb1974 in forum Excel Programming / VBA / Macros
    Replies: 3
    Last Post: 04-06-2011, 05:35 PM
  7. Assigning backspace and delete to form buttons
    By solnajeff in forum Excel Programming / VBA / Macros
    Replies: 4
    Last Post: 05-03-2010, 09:32 AM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

Search Engine Friendly URLs by vBSEO 3.6.0 RC 1