I am maintaining an app for a client that is used in two locations. One in England and one in Poland.
The database is stored in England and uses the format £1000.00 for currency, but the information is being gathered locally in Poland where 1000,00 is the format.
My question is, in VB6 is there a function that takes a currency string in a local format and converts to another, or will I just have to parse the string and replace , or . ?
BTW I have looked at CCur, but not sure if that will do what I want.
The data is not actually stored as the string "£1000.00"; it's stored in some numeric format.
Sidebar: Usually databases are set up to store money amounts using either the decimal data type (also called money in some DBs), or as a floating point number (also called double).
The difference is that when it's stored as decimal certain numbers like 0.01 are represented exactly whereas in double those numbers can only be stored approximately, causing rounding errors.
The database appears to be storing the number as "£1000.00" because something is formatting it for display. In VB6, there's a function FormatCurrency which would take a number like 1000 and return a string like "£1000.00".
You'll notice that the FormatCurrency function does not take an argument specifying what type of currency to use. That's because it, along with all the other locale-specific functions in VB, figures out the currency from the current locale of the system (from the Windows Control Panel).
That means that on my system,
Debug.Print FormatCurrency(1000)
will print $1,000.00, but if I run that same program on a Windows computer set to the UK locale, it will probably print £1,000.00, which, of course, is something completely different.
Similarly, you've got some code, somewhere, I can't tell where, in Poland, it seems, that is responsible for parsing the user's string and converting it to a number. And if that code is in Visual Basic, again, it's relying on the control panel to decide whether "." or "," is the thousands separator and whether "," or "." is the decimal point.
The function CDbl converts its argument to a number. So for example on my system in the US
Debug.Print CDbl("1.200")
produces the number one point two, on a system with the Control Panel set to European formatting, it would produce the number one thousand, two hundred.
It's possible that the problem is that you have someone sitting a computer with the regional control panel set to use "." as the decimal separator, but they're typing "," as the decimal separator.
What database are you using? And what data type is the amount stored in?
As long as you are always converting from one format to another, you do not need to do any parsing, just replace "." with "," or the other way around. You may need to remove the "£"-sign as well if that is stored in your string.
There's probably a correct answer dealing with culture objects and such, but the easiest way would be to taken the input from the polish input, and replace the , with a ., and then store it in your database as type "money" or "decimal". If you know they (possibly configurable per user) are always entering numbers in either Polish or English, you could have a function that you run all the input numbers through to convert the string to a proper "decimal" typed variable. Also, for display purposes you could run it through another similar function to ensure that the user always sees the number format they are comfortable with. The key here is to switch it to a decimal as soon as you get it from the user, and only switch it back to a string at the last step before sending it out to the user.
#KiwiBastard yes i would think so. Are you storing your amount in an "(n)varchar" field or are you using a currency/decimal type field? If the latter is the case, the currency-symbols and separators are added by your client, and there would be no need to replace anything in the database.
Related
I have installed windows 10 64 bit with french localization, and installed Microsoft Office, including ms access.
I have this problem when inserting values to Ms Access 2002 table into Currency field, as the value am trying to insert is a decimal value represented through string, with "." operator as the Decimal Separator, as am getting the error message "datatype mismatch in criteria expression".
Is there a way to tell Ms Access to use the "." as the decimal separator instead of "," and the "," as the Thousands Group Separator instead of " ", as replacing the decimal string value of "." character occurrences to "," characters isn't an option as i have thousands of strings that will need accordingly to have the replace function called upon,
What have tried so far, and didn't bring any results, is:
1. Change the decimal symbol, from control panel, regional and language settings from "," to ".".
2. Switching from OleDB to ODBC, and specifying "Locale Identifier" value to 2057, indicating en-GB, in the connection string.
Please Advise,
Thanks in advance.
First change the comma to a character other than a period ("#")
Then change any remaining periods to a comma.
Lastly change "#" to a period.
dblValue = Replace(Replace(Replace(OriginalValue, ",", "#"), ".", ","), "#", ".")
You mentioned that the values you are passing to access are strings. Why can't you format those strings in a way you wish them to be, and pass the data to MS access?
You did not mention anything specific, so I assume you work in the notepad.exe. In the above program, format the strings you wish to the values you need by replacing appropriate locale symbols to ones you need. After that pass the strings in some way you "better know how" to the MS access.
If you have a millions or billions of rows(columns?!) in your data, you can do a mass replace in the program of your choise(notepad.exe). This is as simple as that.
Use Str, it will never fail:
Str(AnyDecimalValue)
For a generic solution, use my function CSql.
Edit:
The other way around - to convert a text expression to a decimal - use Val:
Val(TextNumberWithDecimalDot)
I am looping over a set of scalars which contain quarterly sif values. I would like to convert them to hrf format and keep them stored in scalars.
However, I found that format %tq only accepts variables. Hence, the only workaround seems to i) convert the scalar to a variable ii) apply format %tq iii) convert the variable to a scalar.
Is there a more elegant and faster way to do this? (I am using Stata MP 15.1.)
You can have string scalars, so you can do this. I can't see why it would be useful, but that could be failure of imagination; you could enlighten us on why you want this.
. scalar foo = yq(2018, 4)
. scalar foo = string(scalar(foo), "%tq")
. scalar list
foo = 2018q4
What is quite different for scalars is that there is no sense whatsoever in which a display format is attached to or associated with a scalar. You can hold a numeric date or a string date in a scalar, but those are the only choices. You can't have a numeric value with a format on the side that Stata will use for display when suitable. You found that out when you attempted to format a scalar.
Goodness knows whether this is faster (than what?) or more elegant (who decides?). The major difference is that a variable manifestly can contain many dates and a changed format made just once with format can apply to them consistently, whereas changing how you show a bunch of scalars requires a loop every time you do it so far as I can see. Further, it follows from above that you might need to keep two sets of scalars, one numeric for calculation and one string for display.
I've used date constants and typically found that either I use them directly (subtracting 2000 as base doesn't requiring putting it into anything) or I use local macros to hold them. But I can't see anything wrong with using scalars, except possibly indirection.
In one of our signup processes, in a Ruby on Rails app, I want to send someone an email with a 6-digit numerical code that they need to copy or type into a box on the page.
How I thought I might do it is to have a string on the page, in a hidden field, say, which, on generating the email, gets combined with some secret key from our codebase, then hashed or encrypted to a series of decimal numbers. I then take the last six of these and put them in the email.
When the form is submitted, with the original string, and the 6 digits the user has typed in, I can repeat the process on the string and test that it produces the same six digits as the user entered.
The question is: how do I hash/encrypt a string to get a series of decimal numbers? The original string can be anything (including a different set of decimal numbers), it just needs to be something that is randomly generated really.
Note: Do not use this as a security measure. You've stated that you intend to use this only as a kind of diy captcha system, and this answer is provided in that context.
OpenSSL provides good hash functions. Once you have the hash in hex the to_i method takes a base argument, so converting to decimal is simple. Then back to a string because that makes it easier to get the last characters.
require 'openssl'
hash = OpenSSL::Digest::SHA256.hexdigest('user#example.com' + Random.new_seed.to_s)
message = hash.to_i(16).to_s.chars.last(6).join
You could then store any part of this along with an expiration time.
I have a text filed which allows user to input numbers. This is what I did:
[_textfield setText:[NSString stringWithFormat:#"%d", [_textfield.text intValue]]];
Basically, I convert text in text filed to integer, then convert back to string. This will ensure the text is numbers only.
Now I need to store the text in _textfield into core data. I was wondering wether should use string as the attribute type or integer.
I know integer is a more sensible option. But to this case, every time the view is loaded, I need fetch this data and set to the _textfield. If I use integer as the attribute type, I have to convert to string each time. I know what I need to do is simply:
_textfield.text = [numberFromCoreData stringValue];
I don't need to compare, sort or do any arithmetic computation with that number, so should I just use string as the attribute type?
Integer searching is significantly faster than string searching. That is the single most compelling reason to use numbers in your persistence layer. Numbers also can sort differently than strings.
For performance reasons I would never use a string when I know the value is always going to be an integer. Control the input, force it to only accept numbers and keep your data integrity.
It depends how you need to use that field. In almost every case, integer data should be stored as an integer type, but not always. You definitely want an integer type if you'll ever be using that field in a case where its numeric value counts in some way. That includes sorting (because it's a hell of a lot faster with numeric fields), comparing numeric values, or any kind of mathematical operation.
But there's are exceptions. For example, in some cases fields which initially seem to be inherently numeric turn out not to be so. Like a "size" field which is normally an integer. But on closer inspection it turns out that some sizes are specified as "8 - 10", "12 - 14", etc. This happened in one app I worked on a couple of years ago. In that case I ended up using two fields for the data-- a numeric "sortSize" that could be used for sorting, and a string "displaySize" that included the full string.
It's probably not what you want but why don't you use a keyboard type "number Pad" for your textfield?
With that, you would be sure that you have only numbers into your textfield.
Honestly I can't think of a compelling reason. Strings in general take up more storage space than Integers but in the modern world of computing this isn't much of an issue. If you aren't really pushing you processor too hard I'd go with what is convenient.
From the most basic way of thinking about it an integer is a number but for a string the computer needs to know when the string ends, starts, and what is in it so its a little bigger.
I am doing some localization testing and I have to test for strings in both English and Japaneses. The English string might be 'Waiting time is {0} minutes.' while the Japanese string might be '待ち時間は{0}分です。' where {0} is a number that can change over the course of a test. Both of these strings are coming from there respective property files. How would I be able to check for the presence of the string as well as the number that can change depending on the test that's running.
I should have added the fact that I'm checking these strings on a web page which will display in the relevant language depending on the location of where they are been viewed. And I'm using watir to verify the text.
You can read elsewhere about various theories of the best way to do testing for proper language conversion.
One typical approach is to replace all hard-coded text matches in your code with constants, and then have a file that sets the constants which can be updated based on the language in use. (I've seen that done by wrapping the require of that file in a case statement based on the language being tested. Another approach is an array or hash for each value, enumerated by a variable with a name like 'language', which lets the tests change the language on the fly. So validations would look something like this
b.div(:id => "wait-time-message).text.should == WAIT_TIME_MESSAGE[language]
To match text where part is expected to change but fall within a predictable pattern, use a regular expression. I'd recommend a little reading about regular expressions in ruby, especially using unicode regular expressions in ruby, as well as some experimenting with a tool like Rubular to test regexes
In the case above a regex such as:
/Waiting time is \d+ minutes./ or /待ち時間は\d+分です。/
would match the messages above and expect one or more digits in the middle (note that it would fail if no digits appear, if you want zero or more digits, then you would need a * in place of the +
Don't check for the literal string. Check for some kind of intermediate form that can be used to render the final string.
Sometimes this is done by specifying a message and any placeholder data, like:
[ :waiting_time_in_minutes, 10 ]
Where that would render out as the appropriate localized text.
An alternative is to treat one of the languages as a template, something that's more limited in flexibility but works most of the time. In that case you could use the English version as the string that's returned and use a helper to render it to the final page.