gfurst
asked on
How do I fix the decimal separator in VB 6.0 different from Windows 6.setting
Can I fix in VB .0 the decimal separator to "." when the Windows Regional setting is "," , without changing the Windows setting? If so, how do I do it
Thank you
Thank you
Not sure what you are asking. Inside of VB6, when doing math calculations for example, VB6 always uses a decimal point (period) as the decimal separator. The only time the localization/regional settings come into play is when formatting the data for display and using the "named" format options (such as Currency). I believe that you can override the regional settings by simply using custom format strings rather than the named format options to get it to display any way you want.
You can override the locale specific formatting using GetNumericFormat API which allows you to specify your decimal and thousands separators.
http://www.ex-designz.net/apidetail.asp?api_id=213
http://www.ex-designz.net/apidetail.asp?api_id=213
If you mean e.g. displaying "0,5" as ",5" then format(0.5,"#.#") returns ",5"
But if you mean swapping "." with "," for displaying numbers
without changing the Windows setting (when "," is the decimal point) then:
Public Function Dbl2Str(Number As Double) As String
Dim strNumber As String
strNumber = CStr(Number)
strNumber = Replace(strNumber, ".", Chr(1))
strNumber = Replace(strNumber, ",", ".")
Dbl2Str = Replace(strNumber, Chr(1), ",")
End Function
But if you mean swapping "." with "," for displaying numbers
without changing the Windows setting (when "," is the decimal point) then:
Public Function Dbl2Str(Number As Double) As String
Dim strNumber As String
strNumber = CStr(Number)
strNumber = Replace(strNumber, ".", Chr(1))
strNumber = Replace(strNumber, ",", ".")
Dbl2Str = Replace(strNumber, Chr(1), ",")
End Function
VK, that code does a swap of the . and , regardless of the locale or windows settings. It would produce the reverse of what was desired if the Windows locale setting already specified US style numeric strings.
Also, CStr will never insert thousands separators.
Also, CStr will never insert thousands separators.
<<when the Windows Regional setting is "," , without changing the Windows setting? If so, how do I do it>>
I'm assuming:
Qfurst has a windows where the "," ist the decimal separator.
He does not intend to change that.
<<Can I fix in VB .0 the decimal separator to ".">>
This is the most confusing part of the question. I'm assuming:
Qfurst want's to "prevent" the localization/regional conversion when a string is putted out (screen, printer, ...)
<<Also, CStr will never insert thousands separators.>>
Yes, i know but that wasn't intended. Does qfurst need that?
I'm assuming:
Qfurst has a windows where the "," ist the decimal separator.
He does not intend to change that.
<<Can I fix in VB .0 the decimal separator to ".">>
This is the most confusing part of the question. I'm assuming:
Qfurst want's to "prevent" the localization/regional conversion when a string is putted out (screen, printer, ...)
<<Also, CStr will never insert thousands separators.>>
Yes, i know but that wasn't intended. Does qfurst need that?
>Qfurst has a windows where the "," ist the decimal separator.
He does not intend to change that.
Right. But *if* the program is ever run on a different machine, where US locale is used, it will cause it to use a comma instead of a period for the decimal. A more secure way to override the locale settings is to use the API I posted above. I assume that the word "fix" means he doesn't want it to switch in every locale.
>Yes, i know but that wasn't intended. Does qfurst need that?
Unclear, but your code does a swap of thousands and decimal signs where no swap is possible, because no thousands character ever appears.
He does not intend to change that.
Right. But *if* the program is ever run on a different machine, where US locale is used, it will cause it to use a comma instead of a period for the decimal. A more secure way to override the locale settings is to use the API I posted above. I assume that the word "fix" means he doesn't want it to switch in every locale.
>Yes, i know but that wasn't intended. Does qfurst need that?
Unclear, but your code does a swap of thousands and decimal signs where no swap is possible, because no thousands character ever appears.
GetNumberFormat returns an error because "," isn't allowed in lpValue.
(ByVal lpValue As String) requires a string as parameter
<<where no swap is possible, because no thousands character ever appears>>
the replace function does nothing when nothing to replace is found.
The code from the link with qfurst's os-setting and an example which fails:
also
GetNumberFormat ByVal 0&, 0, Str(300243.24), NF, Buffer, Len(Buffer)
would fail!
(ByVal lpValue As String) requires a string as parameter
<<where no swap is possible, because no thousands character ever appears>>
the replace function does nothing when nothing to replace is found.
The code from the link with qfurst's os-setting and an example which fails:
also
GetNumberFormat ByVal 0&, 0, Str(300243.24), NF, Buffer, Len(Buffer)
would fail!
Private Type NUMBERFMT
NumDigits As Long ' number of decimal digits
LeadingZero As Long ' if leading zero in decimal fields
Grouping As Long ' group size left of decimal
lpDecimalSep As String ' ptr to decimal separator string
lpThousandSep As String ' ptr to thousand separator string
NegativeOrder As Long ' negative number ordering
End Type
Private Declare Function GetNumberFormat Lib "kernel32" Alias "GetNumberFormatA" (ByVal Locale As Long, ByVal dwFlags As Long, ByVal lpValue As String, lpFormat As NUMBERFMT, ByVal lpNumberStr As String, ByVal cchNumber As Long) As Long
Private Sub Form_Load()
Dim Buffer As String, NF As NUMBERFMT
Buffer = String(255, 0)
With NF
.NumDigits = 3
.Grouping = 3
.lpDecimalSep = ","
.lpThousandSep = "."
.NegativeOrder = 0
End With
GetNumberFormat ByVal 0&, 0, "300,243.24", NF, Buffer, Len(Buffer)
MsgBox Buffer
End Sub
If a general solution converting from any locale setting to US setting is wished:
Private Enum LocaleStringConstants
locCurrency = &H14
locCurSymbol = &H15
locDate = &H1D
locDecimal = &HE
locList = &HC
locMoneyDecimal = &H16
locMoneyThousands = &H17
locNegative = &H51
locPositive = &H50
locThousands = &HF
locTime = &H1E
End Enum
Private Declare Function GetUserDefaultLCID Lib "kernel32" () As Long
Private Declare Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" (ByVal Locale As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long
Private Function LocaleString(Info As LocaleStringConstants) As String
Dim nLocale As String
Dim nLen As Long
'
nLocale = Space(10)
nLen = GetLocaleInfo(GetUserDefaultLCID(), Info, nLocale, 10)
LocaleString = Left(nLocale, nLen - 1)
'
End Function
Public Function Dbl2USNumberStr(Number As Double) As String
Dim strNumber As String
'
strNumber = CStr(Number)
Select Case True
Case LocaleString(locMoneyThousands) <> "."
Case LocaleString(locMoneyDecimal) <> ","
Case Else
strNumber = Replace(strNumber, ".", Chr(1))
strNumber = Replace(strNumber, ",", ".")
strNumber = Replace(strNumber, Chr(1), ",")
End Select
Dbl2USNumberStr = strNumber
'
End Function
Private Sub Form_Load()
MsgBox Dbl2USNumberStr(10000 / 7)
End Sub
You're right that GetNumberFormat isn't a good fit because of the need to have the number as a string already.
I think your last post is on the right track, but I'm getting commas for decimals when using a French locale.
I think your last post is on the right track, but I'm getting commas for decimals when using a French locale.
Here is a solution from danaseaman that seems pretty complete, if more than a little complex:
http:Q_21841979.html#a16632954
May be overkill for the question author... (Would be nice to hear from the question author, but it doesn't look like that's going to happen.)
http:Q_21841979.html#a16632954
May be overkill for the question author... (Would be nice to hear from the question author, but it doesn't look like that's going to happen.)
FYI, as far as dates are concerned, only the Named Formats such as Short or Long are affected by the regional settings in VB6... if you use label1.Caption = Format(Now(), "MM-dd-yyyy") you would get 01-26-2009 even if you select French Standard Regional Setting which would have a default short date format of dd/MM/yy
I thought the same worked for formatting decimals (ie, only named formats such as currency were affected by the regional settings, however, a quick test shows that's not the case).
I would suggest, rather than get too fancy, just write your own MyFormat() procedure that would parse a typical numeric format string and search and replace the regional characters with the desired characters... for the French standard, that would be to replace a comma with a period for the decimal separator and replace a space with a comma for the digits separator.
I thought the same worked for formatting decimals (ie, only named formats such as currency were affected by the regional settings, however, a quick test shows that's not the case).
I would suggest, rather than get too fancy, just write your own MyFormat() procedure that would parse a typical numeric format string and search and replace the regional characters with the desired characters... for the French standard, that would be to replace a comma with a period for the decimal separator and replace a space with a comma for the digits separator.
You are all right, and we should hear something obout the author too.
I think that it is the topic what us make so "ambitious" :-)
I think that it is the topic what us make so "ambitious" :-)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.