[RESOLVED] Convert some parts of a little string in integer or double.
Hi! I have an string like this:
The power is -50dBm@1MHz
I want to select only the part of -50 (including the minus sign since the number can be positive or negative) and convert it in a double variable to work with it.
I know that I have to use the val() function but I don´t know how select only the numer with the minus sign
Anybody can help me?
Re: Convert some parts of a little string in integer or double.
Code:
Private Sub Command1_Click()
Dim D As Double
Dim S As String
Dim S2 As String
S = "The power is -50dBm@1MHz"
For i = 1 To Len(S)
S2 = Mid(S, i)
If Val(S2) Then
Print S2, Val(S2)
End If
Next
'note:
'if the value to look for is 0 (zero) this will not find it
'if the value you are looking for is always located before 'dBm'
'maybe better to look for that
'or maybe the value to look for is always at the start of the 4th word ?
'or maybe anything only you are able to know
'if you post a few 1000 of these strings, maybe someone will find a sure-fire way ?
End Sub
Last edited by IkkeEnGij; Oct 10th, 2017 at 05:10 AM.
Reason: forgot code tags
do not put off till tomorrow what you can put off forever
Re: Convert some parts of a little string in integer or double.
ams16,
If you're willing to use the Val() function, it always interprets as much of a string as a number (left-to-right) as it possibly can, and then stops.
In other words, if you know that the "-50dBm@1MHz" will the the general format of your number, then the Val() gives you exactly what you're after.
In other words:
Code:
debug.Print Val("-50dBm@1MHz") ' <--- This prints the number -50.
Enjoy,
Elroy
EDIT1: Also, just as an FYI, the Val() function will trim off left-hand white space (such as spaces, tabs, and even Cr/Lf) and still find your number.
EDIT2: Actually, after reading more closely, I do see that you've got that "The power is" prefix. As shown by IkkeEnGij, that would need to be trimmed off first.
Last edited by Elroy; Oct 10th, 2017 at 10:18 AM.
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Convert some parts of a little string in integer or double.
Note. Val function is not locale aware.
debug.Print Val("-50.3dBm@1MHz") ' <--- This prints the number -50.3.
Certain locales use comma as a decimal point.
debug.Print Val("-50,3dBm@1MHz") ' <--- This prints the number -50
So need to convert comma to decimal point.
fex...
Code:
Function CommaToDecimalPoint(ByVal PnctToPt As Variant) As String
Dim iCharPos As Integer
'Convert comma(s) to dot.
Do
iCharPos = InStr(PnctToPt, ",")
If iCharPos Then PnctToPt = Left$(PnctToPt, iCharPos - 1) & "." & Mid$(PnctToPt, iCharPos + 1)
Loop While iCharPos
CommaToDecimalPoint = PnctToPt
End Function
debug.Print Val(CommaToDecimalPoint("-50,3dBm@1MHz")) ' <--- This prints the number -50.3
or simply
Code:
debug.Print Val(Replace("-50,3dBm@1MHz",",",".")) ' <--- This prints the number -50.3
Re: Convert some parts of a little string in integer or double.
Another implementation
Code:
Dim hz As Double
Dim j As Integer
Dim f() As String
f = Split("The power is -50dBm@1MHz", " ")
' find first number then exit the loop
For j = 0 To UBound(f)
hz = Val(f(j))
If hz > 0 Then
Exit For
End If
Next
MsgBox (hz)
Re: Convert some parts of a little string in integer or double.
Originally Posted by Tech99
Note. Val function is not locale aware.
debug.Print Val("-50.3dBm@1MHz") ' <--- This prints the number -50.3.
Certain locales use comma as a decimal point.
debug.Print Val("-50,3dBm@1MHz") ' <--- This prints the number -50
So need to convert comma to decimal point.
fex...
Code:
Function CommaToDecimalPoint(ByVal PnctToPt As Variant) As String
Dim iCharPos As Integer
'Convert comma(s) to dot.
Do
iCharPos = InStr(PnctToPt, ",")
If iCharPos Then PnctToPt = Left$(PnctToPt, iCharPos - 1) & "." & Mid$(PnctToPt, iCharPos + 1)
Loop While iCharPos
CommaToDecimalPoint = PnctToPt
End Function
debug.Print Val(CommaToDecimalPoint("-50,3dBm@1MHz")) ' <--- This prints the number -50.3
or simply
Code:
debug.Print Val(Replace("-50,3dBm@1MHz",",",".")) ' <--- This prints the number -50.3
Thank you Tech99! Your answer is the easiest for me. It works well, but I want to save the -50.3 value in a variable. How can I do that?
Re: Convert some parts of a little string in integer or double.
Something like the following, ams16?
Code:
Dim d As Double
d = Val(Replace("-50,3dBm@1MHz", ",", "."))
Any software I post in these forums written by me is provided "AS IS" without warranty of any kind, expressed or implied, and permission is hereby granted, free of charge and without restriction, to any person obtaining a copy. To all, peace and happiness.
Re: Convert some parts of a little string in integer or double.
Or you could get a little more elaborate and "do things correctly."
For example scan the input text for a run of characters within the character set of a valid number. Make sure it is more than just a decimal point character.
Or even get more elaborate if necessary and make sure the run of characters is a valid number. Note that IsNumeric() may be inadequate when working with cross-locale values. Calls to VarParseNumFromStr() might be your best bet there, but I posted on that a few times already so I'll skip that here. It all depends on how bullet-proof you need to be... but if things get that raggedy then all bets are off anyway. For all you know the desired number might be preceded by some other valid number in the text.
Code:
Option Explicit
Private VConvert As VConvert
Private DecimalPt As String
Private NumberChars As String
Private Sub Command1_Click()
Dim Text As String
Dim NumEnd As Long
Dim NumStart As Long
Dim NumText As String
Dim Number As Single
Text = Text1.Text
NumEnd = 1
Do
NumStart = StringScans.ScanUntil(NumEnd, Text, NumberChars)
If NumStart = 0 Then Exit Do
NumEnd = StringScans.ScanWhile(NumStart, Text, NumberChars)
NumText = Mid$(Text, NumStart, NumEnd - NumStart)
Loop Until NumText <> DecimalPt
If Len(NumText) = 0 Then
Label1.Caption = "No number found"
Else
On Error Resume Next
Number = VConvert.Convert(NumText, vbSingle)
If Err Then
Label1.Caption = Err.Description
Else
Label1.Caption = CStr(Number)
If Err Then Label1.Caption = Err.Description
End If
End If
End Sub
Private Sub Form_Load()
Set VConvert = New VConvert
List1.ListIndex = 0
End Sub
Private Sub List1_Click()
Dim LCID As LCIDs
Select Case List1.ListIndex
Case 0: LCID = LOCALE_USER_DEFAULT
Case 1: LCID = LOCALE_INVARIANT
Case 2: LCID = LOCALE_DEDE
End Select
VConvert.LCID = LCID
DecimalPt = LocaleInfo.GetString(LOCALE_SDECIMAL, LCID)
NumberChars = "+-0123456789" & DecimalPt
End Sub
Private Sub Text1_Change()
Label1.Caption = vbNullString
End Sub
If the text is data from some Internet appliance or something as it appears to be, more likely than not it is in invariant locale format anyway. Then Val() is probably adequate, being locale-blind. Data meant for interchange should ALWAYS be in invariant format anyway. Nobody in his right mind uses some Elbonian format and expects any software to guess that accurately.
Ouch, that doesn't work because the "positive sign" may be empty or a space for some locales. Maybe best bet:
Code:
Private Sub List1_Click()
Dim LCID As LCIDs
Dim PSign As String
Select Case List1.ListIndex
Case 0: LCID = LOCALE_USER_DEFAULT
Case 1: LCID = LOCALE_INVARIANT
Case 2: LCID = LOCALE_DEDE
End Select
VConvert.LCID = LCID
DecimalPt = LocaleInfo.GetString(LOCALE_SDECIMAL, LCID)
PSign = Trim$(LocaleInfo.GetString(LOCALE_SPOSITIVESIGN, LCID))
If Len(PSign) = 0 Then PSign = "+"
NumberChars = PSign _
& LocaleInfo.GetString(LOCALE_SNEGATIVESIGN, LCID) _
& LocaleInfo.GetString(LOCALE_SNATIVEDIGITS, LCID) _
& DecimalPt
End Sub
Last edited by dilettante; Oct 12th, 2017 at 02:41 PM.