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
Bookmarks