You are not logged in.

hru

Beginner

  • "hru" started this thread

Posts: 1

Date of registration: May 24th 2011

  • Send private message

1

Tuesday, May 24th 2011, 2:02pm

Val function incompatible with VB6

Hi,

Unexpected behaviour in Jabaco compared to VB6:

The Val function is returning 0.0 if the argument is a decimal number (has a dot in the string)

Cheers

A1880

Intermediate

  • "A1880" is male

Posts: 500

Date of registration: Jan 1st 2009

Location: Hanover, Germany

Occupation: Software Engineer

Hobbies: Hilbert Curves

  • Send private message

2

Wednesday, May 25th 2011, 4:52pm

Val() is a Jabaco framework function implemented in "Conversion.java".

You are right, it mostly/always returns 0.0
There seems to be a bug in the framework implementation.
I've tried to trace it down. It seems to be in VBVariant.doubleValue(), but I'm not sure.

For the time being, you could use CDbl() to circumvent the problem.

Add a new Module to your project with the following content:

Jabaco Source

1
2
3
4
5
Option Explicit

Public Function Val(expression As String)
   Val = CDbl(expression)
End Function


This re-defines Val() and seems to work, at least for me ...

Greetings

A1880

A1880

Intermediate

  • "A1880" is male

Posts: 500

Date of registration: Jan 1st 2009

Location: Hanover, Germany

Occupation: Software Engineer

Hobbies: Hilbert Curves

  • Send private message

3

Thursday, May 26th 2011, 9:14am

I've done the following experiment:

Jabaco Source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Option Explicit

Public Sub Command1_Click()
   t "1,234"
   t "1.234"
   t "1,234.56"
End Sub

Private Sub t(s As String)
   Dim a As New VBVariant(s) 
   Dim x As Double = a.doubleValue()
   
   Debug.Print s & " = " & x
End Sub


The debugging output:

Source code

1
2
3
4
...
1,234 = 0.0
1.234 = 1.234
1,234.56 = 0.0


My suspicion is that Val() constructs a string using the local decimal separator (in Germany the comma).
This string is then converted to double by using CDbl(). However, CDbl() is calling VBVariant.doubleValue().
And there every string with comma separator is mapped to 0.0

Any volunteers to fix this in the framework?

Greetings

A1880

Dani

Intermediate

Posts: 325

Date of registration: Nov 19th 2009

Location: GERMANY

  • Send private message

4

Friday, June 21st 2013, 10:50am

Hey there,

well I guess this still has not been taken care of...

Jabaco Source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Public Sub Form_Load()
   cdblWert CDbl("123,04") ' VB = 123,04 / JB = 0.0
   cdblWert CDbl(123.04)   ' VB = 123,04 / JB = 123.04
   cdblWert CDbl("123.04") ' VB = 12304  / JB = 123.04
   cintWert CInt("123,04") ' VB = 123    / JB = 0
   cintWert CInt(123.6)    ' VB = 124    / JB = 124
   cintWert CInt("123.04") ' VB = 12304  / JB = 123
   clngWert CLng("123,04") ' VB = 123    / JB = 0
   clngWert CLng(123.6)    ' VB = 124    / JB = 124
   clngWert CLng("123.04") ' VB = 12304  / JB = 123
   
   valWert Val("123")      ' VB = 123    / JB = 123.0
   valWert Val("123,04")   ' VB = 123    / JB = 0.0
   valWert Val("123.04")   ' VB = 123,04 / JB = 0.0
   valWert Val(" 123 04")  ' VB = 12304  / JB = 12304.0
   valWert Val("123four")  ' VB = 123    / JB = 123.0
   valWert Val("one234")   ' VB = 0      / JB = 234.0
   
End Sub
Private Sub cdblWert(s As String)
   Debug.Print s
End Sub
Private Sub cintWert(s As String)
   Debug.Print s
End Sub
Private Sub clngWert(s As String)
   Debug.Print s
End Sub
Private Sub valWert(s As String)
   Debug.Print s
End Sub


Visual Basic is clearly considering the regional settings to evaluate a number.
Comma separated values are not beeing recognized by Jabacos' conversion functions.
Also note the difference for cdblWert CDbl("123.04")!!

As for the Val() function A1880 has pointed out above what is going wrong.
The Java code is

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        /**
         * Returns the numbers contained in a string as a numeric value of appropriate type.
         * @author Manuel Siekmann
         * @param  Any valid numeric expression. 
         */
        public static double Val(String Expression) {
            if (Expression == null) { return 0.0; }
            StringBuffer strBuff = new StringBuffer();
                char decimalSeparator = (new java.text.DecimalFormatSymbols()).getDecimalSeparator();
                char c; boolean bSetOperator = false; boolean bSetDecimalSeparator = false;
            for (int i = 0; i < Expression.length() ; i++) {
                c = Expression.charAt(i);
                if (Character.isDigit(c)) {
                    strBuff.append(c);
                } else if (c == '-') {
                                if (bSetOperator == false) {
                                        bSetOperator = true;
                                        strBuff.append("-");
                                }
                        } else if (c == '.' || c == ',') {
                                if (bSetDecimalSeparator == false) {
                                        bSetDecimalSeparator = true;
                                        strBuff.append(decimalSeparator);
                                }
                        }
            }
                return (CDbl(new VBVariant(strBuff.toString())));
        }

It should at least give us a valid value for Val("123.04") !!!
I don't know Java very well, anyone any ideas!?

Dani

theuserbl

Intermediate

Posts: 436

Date of registration: Dec 20th 2008

  • Send private message

5

Friday, June 21st 2013, 5:01pm

Jabaco Source

1
2
3
4
5
cdblWert CDbl("123,04") ' VB = 123,04
cdblWert CDbl("123.04") ' VB = 12304

cintWert CInt("123,04") ' VB = 123
cintWert CInt("123.04") ' VB = 12304


I don't think, that such an localization makes sense.
You know, that this is only the output for german (or europe) countries.

On an US localized operating system, it will be the other way around:

Jabaco Source

1
2
3
4
5
cdblWert CDbl("123,04") ' VB = 12304
cdblWert CDbl("123.04") ' VB = 123.04

cintWert CInt("123,04") ' VB = 12304
cintWert CInt("123.04") ' VB = 123


So the result of the program, depends on, to what language your operating system is set.

In the extreme case it comes up to something like Excel. where all commands and functions are localized.
"SUM(A1:B3)" exists in english Excel but not in german.
And "SUMME(A1:B3)" exists in german Excel but not in english one.
So yoiu can then also no longer discuss in international forums about it, like here.


But you can replacing the "," in the string to ".".

For example in VBA/Conversion you can replace

Jabaco Source

1
2
3
public static double CDbl(VBVariant Expression) {
        return (Expression.doubleValue());
}
to

Jabaco Source

1
2
3
public static double CDbl(VBVariant Expression) {
        return (Expression.replace(',', '.').doubleValue());
}


Or if you don't want to change the Java-code here a modified version of your Jabaco example:

Jabaco Source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Public Sub Form_Load()
   cdblWert CDbl(ul("123,04")) ' VB = 123,04 / JB = 123.04
   cdblWert CDbl(123.04)   ' VB = 123,04 / JB = 123.04
   cdblWert CDbl(ul("123.04")) ' VB = 12304  / JB = 123.04
   cintWert CInt(ul("123,04")) ' VB = 123    / JB = 123
   cintWert CInt(123.6)    ' VB = 124    / JB = 124
   cintWert CInt(ul("123.04")) ' VB = 12304  / JB = 123
   clngWert CLng(ul("123,04")) ' VB = 123    / JB = 123
   clngWert CLng(123.6)    ' VB = 124    / JB = 124
   clngWert CLng(ul("123.04")) ' VB = 12304  / JB = 123
   
   valWert Val(ul("123"))      ' VB = 123    / JB = 123.0
   valWert Val(ul("123,04"))   ' VB = 123    / JB = 0.0
   valWert Val(ul("123.04"))   ' VB = 123,04 / JB = 0.0
   valWert Val(ul(" 123 04"))  ' VB = 12304  / JB = 12304.0
   valWert Val(ul("123four"))  ' VB = 123    / JB = 123.0
   valWert Val(ul("one234"))   ' VB = 0      / JB = 234.0
   
End Sub
Private Sub cdblWert(s As String)
   Debug.Print s
End Sub
Private Sub cintWert(s As String)
   Debug.Print s
End Sub
Private Sub clngWert(s As String)
   Debug.Print s
End Sub
Private Sub valWert(s As String)
   Debug.Print s
End Sub

Private Function ul(s As String) As String ' ul = unlocalize
   ul = Replace(s, ",", ".")
End Function


Greatings
theuserbl

Dani

Intermediate

Posts: 325

Date of registration: Nov 19th 2009

Location: GERMANY

  • Send private message

6

Friday, June 21st 2013, 9:08pm

Hey there theuserbl,

it has been a while...

Quoted

I don't think, that such an localization makes sense.

I agree and I wasn't aware that

Jabaco Source

1
CDbl("123.04") ' VB = 12304  / JB = 123.04

is a localisation, so thanks for letting me know.
Actually I am not after ther localization I just wanted to point out the differences of Jabacos' conversion functions compared to VB.
I like the Jabaco implementation better in this case.
We are always after compatibility though especially when porting a VB project to Jabaco, so this would obviously make a difference!.

Now about the Val() function:

Jabaco Source

1
Val("123.04")   ' VB = 123,04 / JB = 0.0

I would expect it to return 123.04 here!
Like:

Jabaco Source

1
CDbl(123.04)  ' VB = 123,04 / JB = 123.04

This would make much more sense wouldn't it?

And again for compatibility reasons:

Jabaco Source

1
2
Val("one234")       ' VB = 0      / JB = 234.0
Val("123 banana 4 free 5")  'VB = 123    / JB = 12345.0

Even though I like it it returns different values compared to VB.

I guess the question is:
Do we want intuitive compatibility to VB6 or not?

Dani

Again I am not talking about the localization issue...

Rate this thread
WoltLab Burning Board