Wednesday, February 17, 2010

Tips & Tricks - General

Tips and tricks when programming VB6.




Default Property And Event

Each control in Vb has one default property. This default property will automatically being assigned when you call the control name.
For example, Text1 is an instance of TextBox.
   Text1 = "TEST", equals to Text1.Text = "TEST".
This goes same with Event. Supposed Command1 is an instance of Command.
   Command1 = True, equals to calling Command1_Click.
Notice that you can call the a control's default event this way, even when the control is in another Form, without changing the Sub's scope.
   Form2.Command1 = True (Sub can be Private), equals to calling Form2.Command1_Click (Sub must be Public).

Split and Join

You can parse a string which is delimited by certain characters, using Split() function. The results, called as tokens, will be saved in an array.

The reverse operation, that's change the array's elements in to a string can be achieved by using the Join() function.

Here is the example:

Dim tokens() As String
tokens = Split("11/12/2009", "/")

Dim s As String
s = Join(tokens, "-")


ScaleMode ?

In some container-level controls, e.g. PictureBox, and even Form, you will see this property in the Property Page. It is necessary to understand what is the function of this property and how it affects the application.

The ScaleMode is used to determining the measurement units for sizing and positioning controls. This property will affect the control itself, and the its childs.

For the childs, it will affect the Top, Left, Width and Height. But for the control itself, it will affect the ScaleWidth and ScaleHeight.

This mechanism can be easily understood, that Top, Left, Width and Height were determined by the measurement unit of parent, and ScaleWidth and ScaleHeight (which are internal size of a control) were determined by the control itself (since it is internal process).

However, there is a bug in VB6, when you create a UserControl, and define it as ControlContainer. The ScaleMode will only affect the childs stored in Controls collection. (See the article of this Bug in Tips & Tricks - UserControl)

Math function: Round Problem

Somehow, the code>Round function in VB acts unlike others, such as MSSQL.
As its name says, this function rounds a number. This can be ceiling or flooring.
However, to determine what action is performed can not be assigned manually.

The case is the result of this function sometimes is not same as we do rounding in other programming language (even SQL), that is when the last digit is 5. See examples below:
MSSQL

select round(2.285, 2) -- returns 2.290
select round(2.995, 2) -- returns 3.000

ORACLE

select round(2.285, 2) from dual -- returns 2.29
select round(2.995, 2) from dual -- returns 3

VB6

round(2.285, 2) ' returns 2.28
round(2.995, 2) ' returns 3

As we can see in the examples, VB return a different value when rounding 2.285 (flooring).
After a series of experiments, I found out an interest thing about this strange behavior. It seems there's something to do with the NumDigitsAfterComma argument :
"If the NumDigitsAfterComma-th digit after comma (OR the digit before the last digit) is ODD, the ceiling is used. Else (EVEN), the floor is used."

So, in the example above we can understand why round(2.285, 2) = 2.28.
That's because the 2nd digit is even. So here is the conclusion

Round(2.285, 2) -> 2.28, because 8 is even
Round(2.995, 2) -> 3, because 9 is odd


Then, how to produce the same value as the others (ORACLE & MSSQL)?
Of course by find out whether that digit is odd or even (You must be crazy, lol). Another and the best workaround : just add 1/(10^(NumDigitsAfterComma + 1)) to the value.

Round(2.285 + 0.001, 2) -> 2.29
Round(2.995 + 0.001, 2) -> 3
Round(2.284 + 0.001, 2) -> 2.28

Tricky huh....

No comments:

Post a Comment