Problem
With an example form with a Textbox and a Commandbutton:
You can check the data type of the text box with Vartype or Typename:
Debug.Print VarType(TextBox1.Value)
Debug.Print TypeName(TextBox1.Value)
That will return the number 8
and String
, respectively. Then you have a String variable and are leaving for Excel to perform the conversion to numbers automatically, which can create errors, as in the case of language change between different versions of Excel.
Conversion
To convert the input data, be it a number in a comma or dot text box and turn it into a number. The following function can be used in a Module:
Public Function converter_numero(ByVal num As String) As Double
On Error GoTo erros
Dim pos_ponto As Long, pos_virgula As Long
pos_ponto = InStr(1, num, ".", vbBinaryCompare)
pos_virgula = InStr(1, num, ",", vbBinaryCompare)
If pos_ponto > 0 Then
converter_numero = CDbl(Mid(num, 1, pos_ponto - 1)) + CDbl((Mid(num, pos_ponto + 1, Len(num))) / 10 ^ (Len(num) - pos_ponto))
ElseIf pos_virgula > 0 Then
converter_numero = CDbl(Mid(num, 1, pos_virgula - 1)) + CDbl((Mid(num, pos_virgula + 1, Len(num))) / 10 ^ (Len(num) - pos_virgula))
ElseIf IsNumeric(num) Then
converter_numero = CDbl(num)
Else
MsgBox "Insira um número válido!"
End If
Exit Function
erros:
'Criar o tratamento de erros
MsgBox "O número " & num & " gerou o seguinte erro. " & Err.Number & " : " & Err.Description
On Error GoTo 0
End Function
Explanation
- Checks the position of the comma
","
or point "."
in the variables pos_virgula
and pos_ponto
, respectively.
- Checks whether the position is greater than zero, i.e., whether it has a comma or a dot.
- Creates the decimal number by adding the part before the separator and the part after the separator, i.e., the whole part and the decimal part.
- Converting the number before the separator
CDbl(Mid(num, 1, pos_ponto - 1))
to Double, where it converts the numbers that are in String from position 1 to separator position minus 1.
- Converting the number after the separator
CDbl((Mid(num, pos_ponto + 1, Len(num))) / 10 ^ (Len(num) - pos_ponto))
to Double, where it converts the numbers that are in the String from the separator position plus 1 to the full size of the string (final position) and then divides by 10 high the number of decimals. For example, it has two decimal places, 10 2 = 100.
- Returns the function result
converter_numero
Note: The error handling can be performed using the function Isnumeric
Upshot
Then with the following code:
Private Sub CommandButton1_Click()
Debug.Print VarType(TextBox1.Value)
Debug.Print TypeName(TextBox1.Value)
TextBox1.Value = Round(converter_numero(TextBox1.Value) / 30, 2)
End Sub
The following result can be obtained:
Formatting
Conversion of output data is also required.
Formatting the result in the text box can be performed as follows after the calculations:
TextBox1 = Format(TextBox1, "##0.00")
Function
And then the dot can be replaced by the comma with a function in a module:
Public Function converter_virgula(num) As String
Dim str As String
str = CStr(num)
converter_virgula = Replace(str, ".", ",")
End Function
Example
Then the example would be:
Private Sub CommandButton1_Click()
TextBox1 = Format(Round(converter_numero(TextBox1.Value) / 30, 2), "###0.00")
TextBox1 = converter_virgula(TextBox1.Value)
End Sub
Or
Private Sub CommandButton1_Click()
TextBox1 = converter_virgula(Format(Round(converter_numero(TextBox1.Value) / 30, 2), "###0.00"))
End Sub
https://docs.microsoft.com/pt-br/office/vba/api/excel.application.decimalseparator
– Augusto Vasques
You directly assign the value in the textbox ? You can show the code that does this ?
– Isac
Yes! I know it is not good practice not to work with variables and do the way I did, I intend to change this later. I edited the question with the code in question.
– Clayton