Solved

Val (VB6) function equivalent in VB.net

Posted on 2012-03-24
18
1,229 Views
Last Modified: 2012-03-24
Hi ,

I need to create a function in VB.net that emulate 100% the  old VB6 "Val" function.

I have a project in VB.net that use more then 100/200 calls to this function.

I need to remove all the old vb6 functions calls.

I have created this function:

//
    Public Function S_Val(ByVal Number As Object) As Double

        If Number = Nothing Then Return 0

        If Double.TryParse(Number, 0) = False Then Return 0

        Return Double.Parse(Number)

    End Function
//

but not work in many situations like:


      MsgBox(Val("   222#222,222"))                     ------> 222

        MsgBox(S_Val("  222#222,222"))                 ------> 0

-------------------------------------------------------------

      MsgBox(Val("   222.222,222"))                       -------> 222,222

        MsgBox(S_Val("  222.222,222"))                   -------> 222222,222

-------------------------------------------------------------------

Someone can help me please to create an exact duplicate of val function ?
0
Comment
Question by:luca345
  • 8
  • 7
  • 3
18 Comments
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 37760527
Val exists in VB.NET. Are you saying you are not permitted to use it?
0
 

Author Comment

by:luca345
ID: 37760529
Yes, I need only pure vb.net instructions.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 37760591
Would regular expressions be out of the question?
0
 

Author Comment

by:luca345
ID: 37760616
If this solution can solve the problem, for me is good.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 37760669
OK. Based on what I see as the definition of Val, I believe this matches functionally:

Public Shared Class HelperMethods
  Private Shared _reg As New System.Text.RegularExpressions.Regex("^\s*(\d+(?:\.\d+)?)", Text.RegularExpressions.RegexOptions.Compiled)

  Public Shared Function S_Val(ByRef Number As Object) As Double
    If Number Is Nothing Then
      Return 0
    ElseIf Number Is GetType(Double) OrElse _
       Number Is GetType(Integer) OrElse _
       Number Is GetType(Short) OrElse _
       Number Is GetType(Long) OrElse _
       Number Is GetType(Single) Then

      Return Number
    Else
      Dim result As Double = 0
      Dim convert As String = Number.ToString()
      Dim m As System.Text.RegularExpressions.Match = _reg.Match(convert)

      If m.Success Then
        result = Double.Parse(m.Groups(1).Value)
      End If

      Return result
    End If
  End Function
End Class

Open in new window


Usage
Dim result As Double = HelperMethods.S_Val("32")

Open in new window

0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 37760671
P.S.

I don't have all the "U" types listed above (e.g. UInteger, UShort, etc.), but it should be easy enough for you to add. I can also explain all of the logic for you if it's not apparent.
0
 

Author Comment

by:luca345
ID: 37760696
Thank you for your code.

Do you think is possible do a function/s and not a class ?

Best Regadrs
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 37760759
I only put it into a class so I could have the Shared Regex object. A Module gets compiled into a class anyway, so they really are equivalent, but you could break the function out, like so:

Public Shared Function S_Val(ByRef Number As Object) As Double
    If Number Is Nothing Then
      Return 0
    ElseIf Number Is GetType(Double) OrElse _
       Number Is GetType(Integer) OrElse _
       Number Is GetType(Short) OrElse _
       Number Is GetType(Long) OrElse _
       Number Is GetType(Single) Then

      Return Number
    Else
      Dim result As Double = 0
      Dim convert As String = Number.ToString()
      Dim m As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(convert)

      If m.Success Then
        result = Double.Parse(m.Groups(1).Value)
      End If

      Return result
    End If
  End Function

Open in new window

0
 

Author Comment

by:luca345
ID: 37760789
Hi  kaufmed ,

Seem there is some errors.

Please see image attached.
error.png
0
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
LVL 40
ID: 37761101
Could you explain to me why somebody would like to get 222 out of "122#222,222"?

Personnally, if somebody provides me with 222#222,222 as a number, I would reject it as an error.

What is S_Val? This is not a VB6 function.
0
 

Author Comment

by:luca345
ID: 37761184
Hi James,

This is only a test to see if the functions (Val and S_Val) return the some result.

In my county for example 1 million and 10 cent is:

1.000.000,10 (1 million and 10 cent)

if the S_Val return a different result there is the possibility to exchange the cents and the Euros .....

But this in only an example.

Marco

Simply I need a function that return the some result of Val.
0
 
LVL 74

Expert Comment

by:käµfm³d 👽
ID: 37761208
Remove the Shared keyword from the function signature. I think that will remove the other error as well.
0
 

Author Comment

by:luca345
ID: 37761213
I have already do this , but don't remove the second error.

P.S.

Do you known a way to prevent the debug to this function or in one particular module ?
0
 
LVL 74

Assisted Solution

by:käµfm³d 👽
käµfm³d   👽 earned 250 total points
ID: 37761230
My fault. It helps if you include the pattern in the call to the function! Change line 16 of your screenshot to:

Dim m As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(convert, "^\s*(\d+(?:\.\d+)?)")

Open in new window

0
 
LVL 40
ID: 37761232
Most of the functions dealing with strings in .NET adjust to the configuration panel as far as formatting is concerned.

If information is transmitted as numbers, the formatting is not important. I would send you 1 000 000.10 from my computer, and it would show as 1.000.000,10 on yours. Since numeric values are not saved with formatting (the value is saved as 1000000.10, the dot being the standard decimal separator for .NET numeric values), the system simply adjust to the Control Panel when displaying a numeric value or taking input from the user and saving it as a numeric value.

As long as you are dealing with user input, your aim as a programmer is to follow that same rule: adapt to the Control Panel. This is done automatically for you by most .NET functions. The best replacement for Val would then be TryParse for the type of numeric value you want to work with. Since you seem to be working with money, Microsoft recommends using the Decimal type. So your Val would be replace by the following:
Dim value As Decimal
If Decimal.TryParse("   222#222.222", value) Then
     'Value is good and follows the format defined in the Control Panel
     MessageBox.Show(value.ToString)	'ToString will display the numeric value without the formatting, the way you want it as a programmer
Else
     'Value cannot be resolved for the format used on this computer
     'The String.Format in the following will display a numeric value in the format defined in the Control Panel
     MessageBox.Show("The value you typed is not a valid numeric format. You should type numbers in the following format: " & String.Format("{0:# ### ###.###}", 1234567.098), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information)
End If

Open in new window

This is the best way to deal with user input in .NET, because it follows Windows standards. This is equivalent to how Excel works for instance.

If the string you need to convert comes from a file however, you need to know beforehand in which format it will come and then follow the format of the file in the TryParse. Here is what you could use to convert a String from a file that I send you from Montreal, where the Control Panel is usually set to French Canadian (fr-CA):

If Decimal.TryParse("   222#222.222", System.Globalization.NumberStyles.Number, New System.Globalization.CultureInfo("fr-CA"), value) Then

Open in new window


A little more involved than Val, but it can adapt to any situation. In this world of internationalization, this is a must.
0
 

Author Comment

by:luca345
ID: 37761269
(James)

I understand, but apart the county val function return a real number and not decimal.


(kaufmed)

The function return a different value:

//
      Const value = "222.222,00"

        MsgBox(Val(value))              --------------> 222,222

        MsgBox(S_Val(value))           --------------> 222222
//
0
 
LVL 40

Accepted Solution

by:
Jacques Bourgeois (James Burger) earned 250 total points
ID: 37761285
If you want a real number instead of a decimal, change Decimal by Double.

If you ever work with integer, change for Integer or Long.

TryParse works with most basic types, including dates. It's role is to make sure that the application follows the Windows environement in which it is working.

Here in Canada, we have 3 standards. Then english canadians do not have the same format as the french canadians, and english United States is 20 miles from here. Without those functions, programming would be a chore. This was a chore with Val.

I gave you an example with Decimal because you were talking about cents, so I thought that you were working with money. The old VB6 Currency type does not exists in .NET and Microsoft recommends to replace it by Decimal.
0
 

Author Closing Comment

by:luca345
ID: 37761393
OK thank you I have replace the old Val function with another function.
0

Featured Post

6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

Join & Write a Comment

Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
This article describes some techniques which will make your VBA or Visual Basic Classic code easier to understand and maintain, whether by you, your replacement, or another Experts-Exchange expert.
This tutorial will introduce the viewer to VisualVM for the Java platform application. This video explains an example program and covers the Overview, Monitor, and Heap Dump tabs.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now