PDA

View Full Version : Userform field changes not detected when userform invoked from userform



wjwestcott
11-02-2016, 06:59 AM
I have a simple calculator written as a userform, which I call from a data entry userform.
When I call the calculator direct from excel it works 100% correctly.
If I call the calculator from a userform field most of the processing works as expected.
A fature of the calculator is that it allows data and operators as a string i.e. 123+456*789/111=
As the string is typed the field change event detects the operators and performs the required calculation.
When the calculator is called from a userform this change event is not detected.

I have attached a very cutdown version of the workbook.
Press CTRL z to invoke the calculator directly. Type 123+456-789= in the input field, as you type it will split the string, add 123 to 456 and then deduct 789.
Press button BROWSE on row 8 of the summary worksheet and then type an equals sign in the taxi box, as you do this the calculator will appear.
Enter the same string in the calculator box and see that it does not perform the calculation. Calculations can be performed using the calculator push button keys.
None of the other buttons on the summary sheet will work.
If you need to make any changes to the worksheets you will need to unprotect them, CTRL/SHIFT/Q will do this.

Paul_Hossler
11-02-2016, 07:32 AM
Did you want TxtRes instead of OutDisp?




Private Sub cmdbtnSav_Click()
Result = TxtRes
Hide
End Sub


If you just enter a number and [Save] OutDisp is never updated

wjwestcott
11-02-2016, 08:05 AM
You are more correct that the result will always be correct in OutDsp.
If the equals button is pressed the result will also be in TxtRes.

However the problem relates to data being entered into the TxtRes field not being correctly processed.

wjwestcott
11-02-2016, 08:26 AM
I have attached a document showing screen prints of the calculator as it should work and how it works when called from a userform.

Paul_Hossler
11-02-2016, 12:41 PM
I think you'll need to use



Private Sub UserForm_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)

End Sub


'or maybe

Private Sub UserForm_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)

End Sub






and handle each key press one at a time, similar to the command button click events




Private Sub cmdBtn1_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn1.Caption
Else
TxtRes = TxtRes + cmdBtn1.Caption
End If
End Sub

wjwestcott
11-03-2016, 07:17 AM
Hi Paul
I have made some progress with this, at least the keystrokes are being detected.
If I step through the code it appears to work ok, but if I remove the breakpoints it duplicates each character I enter.

Updated code below


Public tmpVar As String
Public calVal As String
Dim Textbutton

Private Sub cmdbtnSav_Click()
Result = OutDsp
Hide
End Sub

Private Sub UserForm_Initialize()
TxtRes.MaxLength = 10
InpDsp.MaxLength = 10
Result = Empty
TextClear
End Sub


Private Sub TxtRes_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
ch = Chr(KeyAscii)
If KeyAscii > 47 And KeyAscii < 58 Then
If TxtRes = "" Then
TxtRes = ch
Else
TxtRes = TxtRes + ch
End If
Else
Select Case ch
Case "+"
cmdBtnadd_Click
Case "-"
cmdBtnMns_Click
Case "/"
cmdBtnDvd_Click
Case "*"
cmdBtnMult_Click
Case "="
cmdBtnEql_Click
Case Else
MsgBox "Invalid Character in string"
End Select
End If

End Sub

Private Sub Validate_TxtRes()
If TxtRes.TextLength > 10 Then
MsgBox "Its Too long to calculate value.", vbInformation
TxtRes.Text = Left(TxtRes.Text, 10)
Exit Sub
End If
TxtRes.SetFocus
End Sub

Private Sub cmdBtnclr_Click()
TxtRes = Empty: InpDsp = Empty: InpClc = Empty
TextClear
End Sub

Private Sub cmdBtnDvd_Click()
If TxtRes <> 0 Then
TextRoll
Calc
Validate_TxtRes
InpDsp = TxtRes
InpClc = "÷"
TxtRes = Empty
Textbutton = "Off"
calVal = "divide"
End If
End Sub

Private Sub cmdBtnMult_Click()
If TxtRes <> 0 Then
TextRoll
Calc
Validate_TxtRes
InpDsp = TxtRes
InpClc = "x"
TxtRes = Empty
Textbutton = "Off"
calVal = "multiply"
End If
End Sub

Private Sub cmdBtnMns_Click()
If TxtRes <> 0 Then
TextRoll
Calc
Validate_TxtRes
InpDsp = TxtRes
InpClc = "-"
TxtRes = Empty
Textbutton = "Off"
calVal = "subtract"
End If
End Sub

Private Sub cmdBtnadd_Click()
If TxtRes <> 0 Then
TextRoll
Calc
Validate_TxtRes
InpDsp = TxtRes
InpClc = "+"
TxtRes = Empty
Textbutton = "Off"
calVal = "add"
End If
End Sub

Private Sub cmdBtnDot_Click()
If TxtRes <> 0 Then TxtRes = TxtRes + "."
End Sub

Private Sub cmdBtn1_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn1.Caption
Else
TxtRes = TxtRes + cmdBtn1.Caption
End If
End Sub

Private Sub cmdBtn2_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn2.Caption
Else
TxtRes = TxtRes + cmdBtn2.Caption
End If
End Sub

Private Sub cmdBtn3_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn3.Caption
Else
TxtRes = TxtRes + cmdBtn3.Caption
End If
End Sub

Private Sub cmdBtn4_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn4.Caption
Else
TxtRes = TxtRes + cmdBtn4.Caption
End If
End Sub

Private Sub cmdBtn5_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn5.Caption
Else
TxtRes = TxtRes + cmdBtn5.Caption
End If
End Sub

Private Sub cmdBtn6_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn6.Caption
Else
TxtRes = TxtRes + cmdBtn6.Caption
End If
End Sub

Private Sub cmdBtn7_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn7.Caption
Else
TxtRes = TxtRes + cmdBtn7.Caption
End If
End Sub

Private Sub cmdBtn8_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn8.Caption
Else
TxtRes = TxtRes + cmdBtn8.Caption
End If
End Sub

Private Sub cmdBtn9_Click()
If TxtRes = 0 Then
TxtRes = cmdBtn9.Caption
Else
TxtRes = TxtRes + cmdBtn9.Caption
End If
End Sub

Private Sub cmdBtn0_Click()
If TxtRes = 0 Then
TxtRes = TxtRes
Else
TxtRes = TxtRes + cmdBtn0.Caption
End If
End Sub

Private Sub cmdBtnEql_Click()
On Error GoTo ErrOccured

If InpDsp = "Cannot divide by Zero" Then InpDsp = Empty
TextRoll
Calc
InpDsp = TxtRes
InpClc = "="
If TxtRes <> "" And calVal <> "" Then
Result = OutDsp
TxtRes = Result
End If
ErrOccured:
End Sub

Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
Result = Empty
End Sub

Sub Calc()
If OutDsp.Text = Empty Then
FNum = Val(InpDsp)
Else
FNum = Val(OutDsp)
End If
SNum = Val(TxtRes)

Select Case calVal
Case "add"
OutDsp = FNum + SNum
Case "subtract"
OutDsp = FNum - SNum
Case "multiply"
OutDsp = FNum * SNum
Case "divide"
If SNum = 0 Then
TxtRes = "Cannot divide by Zero"
Else
OutDsp = FNum / SNum
End If
Case ""
calVal = calVal
Case Else
MsgBox calVal & " is invalid"
End Select
End Sub

Sub TextRoll()
InpDsp4 = InpDsp3
InpDsp3 = InpDsp2
InpDsp2 = InpDsp1
InpDsp1 = InpDsp

OutDsp4 = OutDsp3
OutDsp3 = OutDsp2
OutDsp2 = OutDsp1
OutDsp1 = OutDsp

InpClc5 = InpClc4
InpClc4 = InpClc3
InpClc3 = InpClc2
InpClc2 = InpClc1
InpClc1 = InpClc
End Sub

Sub TextClear()
InpDsp4 = Empty
InpDsp3 = Empty
InpDsp2 = Empty
InpDsp1 = Empty

OutDsp4 = Empty
OutDsp3 = Empty
OutDsp2 = Empty
OutDsp1 = Empty
OutDsp = Empty

InpClc5 = Empty
InpClc4 = Empty
InpClc3 = Empty
InpClc2 = Empty
InpClc1 = Empty
End Sub

Paul_Hossler
11-03-2016, 10:01 AM
I think that since the pressing of the key added the character, there's no need to do it again

This seems to work for both NumPad and TopRow numbers




Private Sub TxtRes_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
ch = Chr(KeyAscii)
If KeyAscii > 47 And KeyAscii < 58 Then
' If TxtRes = "" Then
' TxtRes = ch
' Else
' TxtRes = TxtRes + ch
' End If
Else
Select Case ch
Case "+"
cmdBtnadd_Click
Case "-"
cmdBtnMns_Click
Case "/"
cmdBtnDvd_Click
Case "*"
cmdBtnMult_Click
Case "="
cmdBtnEql_Click
Case Else
MsgBox "Invalid Character in string - " & KeyAscii
End Select
End If

End Sub

wjwestcott
11-06-2016, 04:15 AM
Thanks for your help, I now have it working.
Needed to use Keyup, I was not aware of Keydown/keyup/keypress before.