Decimal numbers (in our regional settings, a comma is the decimal symbol) are changed to semicolons when used in formula.
Let's say I have a number (I actually just parse it from a field but I need it in a variable):
c = 10,5
If I do:
sheet.Cells(1,1).Formula = "=SUM(" & c & ",10)"
The whole formula becomes:
=SUM(10;5;10)
The comma is always changed to a semi-colon which ruins the double number.
I can use .FormulaLocal and then the semi-colon separator works in the formula but the comma still works too so that does not solve it.
Changing the regional settings does not work since I need to distribute it and won't be able to get everyone to change the regional settings.
Anything that could save me from this?
if c i as string containing a double value in local format, you can use:
sheet.Cells(1,1).Formula = "=SUM(" & Str(CDbl(c)) & ",10)"
CDblwill convert the value from the locale string to the Double format, and Str will make a String of it using . as decimal separator.
You can also replace the DecimalSeparator directly:
sheet.Cells(1,1).Formula = "=SUM(" & Replace(c, Application.DecimalSeparator, ".") & ",10)"
Related
I've created a set of macro files in Microsoft Word's VBA as a sort of a CAT tool (CAT = https://en.wikipedia.org/wiki/Computer-assisted_translation). The problem is that there are cases where I display the text needed to be translated and the user needs to input text in his own language. That might include some special chars, like "ăîâșț/ĂÎÂȘȚ", or even quotes or brackets. Is there any way to use those in some InputBox function? Or, at least, some way to let the user input the text he needs in some TextBox or something?... Or how should I approach this?... Maybe UTF-8 support would be what I need? Or?... Any help would be appreciated!...
I've tried Microsoft Word's vba function InputBox. I'm also thinking if, maybe, I would be able to create my own InputBox, with my conditions on it, I might be able to have one that accepts those chars too, or all the chars into some string variable... Here is something someone on StackOverflow says:
Is it possible to create an 'input box' in VBA that can take a text selection with multiple lines as an input? (I'm referring to gizlmo's answer...)
Here are 3 lines of code that contain that (although it's more of a how to question, not a debugging question, so those are not really needed...)
MsgBox ("Ziua " & Str(ziua) & " - " & titlurien(ziua))
titluales = InputBox("Titlul original: " & titlurien(ziua), "Ziua: " & Str(ziua) & ", Rapsodia Realitatilor " & monthname(lunanecesara) & Str(annecesar))
titluriro(ziua) = titluales
I expect the output to be exactly what he typed, whether it's quotes, brackets or special characters (like "ăîâșț"/"ĂÎÂȘȚ")...
A VBA InputBox will take any character typed or pasted into it. The characters available to type depends on the Language version of Windows and Office that the end user has installed.
Below is a test I just made with your example character string "ăîâșț/ĂÎÂȘȚ"
SpecialCharInput()
Dim str As String
str = InputBox("Enter you text", "Special Test Input Box")
Debug.Print str
End Sub
On my English language system, the only trouble it had was with the upper and lower case "ȘȚ" Turkish characters. By trouble I mean it turned those characters into question marks "??" in the result string. I'm sure though, if my system supported the Turkish language that those characters would be recognized and outputted properly.
I'm having a hard time understanding how to place a double quote (") within a String in VBA. I know that I can easily do this using the char(34) function. I also understand that another way of doing this is to use 4 double quotes: """". All of this comes from a previous SO post:
How do I put double quotes in a string in vba?
However, my question is.... Why are 4 quotes needed? Do the first two act as the escape, the third is the quote itself, and the fourth is the terminating quote? Or does it work in a different way? I haven't been able to find a concrete answer as to how VBA treats these double quotes.
I've also noticed that if I try adding or removing the number of double quotes within a String, Visual Studio will dynamically add or remove double quotes. For example, I initially had the following String:
data = TGName + """ + iterator.Value + """
...which produces the following within a message box:
However, if I try adjusting the second set of double quotes at the end of the String (+ """) from 3 to 4, Visual Studio automatically adjusts this to 5. There's no way for me to only have 4 quotes at the end. This is the resulting String within a message box:
The Strings within the message boxes aren't the actual output that I'm hoping to have, they're purely for experimental purposes. However, what I've noticed is that there clearly is a requirement for the number of quotes that are allowed within a String in VBA. Does anyone know what that requirement is? Why is the IDE forcefully inserting an additional quote in the second String? Can someone explain the differences between the actual String contents and the formatting quotes within both cases that I've described?
As always, any assistance on this would be greatly appreciated :)
The general rule is as follows.
The first double-quote (DQ) announces the beginning of a string. Afterwards, some DQ announces the end of the string. However, if a DQ is preceded by a DQ, it is "escaped". Escaped means it is a character part of the string, not a delimiter.
Simply put, when you have any even number of consecutive double-quotes inside a string, say 2n, this means there are n escaped double-quotes. When the number is odd, say 2n+1, you have n escaped DQs and a delimiter.
Examples
""" + iterator.Value + """
' delimiter " + iterator.Value + " delimiter
' ^ escaped ^ escaped
""" + iterator.Value + """"
' delimiter " + iterator.Value + "" ' (missing enclosing delimiter)
' ^ escaped ^^ both escaped.
In this latter case the last delimiter is missing, For this reason VS inserted it for you, and you got 5 DQs.
Finally the particular case """" (just 4 DQs), the first and last are delimiters, and inside there's one escaped DQ. This is equivalent to chr(34).
To append iterator value to TGName in quotes, you can do this:
Data = TGName & """" & iterator.Value & """"
or this:
Data = TGName & Chr(34) & iterator.Value & Chr(34)
Note: I replaced + signs with & because that's simply a VBA best practice when concatenating strings.
I've been searching for two days to solve my issue but so far nothing.
There are many (Very many) vba excel tools developed where I work and our regional settings in PC-s determine comma as decimal separator but reports and data downloaded from our systems have dot as decimal separator. In these tools, when needed we just have set UseSystemSeparators = False then DecimalSeparators = "." and at the end of the macro reverted back.
Now new people have been getting windows 10 pcs and some of the tools run into errors. I got a Win10 pcs from IT to test and found out that no matter how I set in Excel settings VBA Macro uses PC regional settings while on the sheet it still uses what is determined in Excel settings. Same file, same test in my win7 pc and if set then both on sheet and vba macro use local application settings.
Does anyone know what is the reason and how it could be fixed? I can figure many workarounds but all of these mean that the tools need to be re-coded and there are just so many of these that I still keep finding out new tools used and what were developed before I joined the company in March. Changing all ~300 PC-s regional setting is not an option because it needs to be comma as decimal separator normally.
Edit: just to make it bit more clear I'll add some code:
Sub test()
Application.UseSystemSeparators = False
Application.DecimalSeparator = "."
variable = "10.1"
MsgBox CDbl(variable)
End Sub
Under Windows 7 - no problem. The variable containing a string can be converted.
Under Windows 10 - Run-time error, Type mismatch. Both PCs have "," as system separator. The funny thing is that when I change "10.1" to "10,1" then that works on both PC-s. Settings for both PC-s are same. System uses "," as separator and Excel is set to use ".".
This answer is based on your system (default) DecimalSeparator being a comma (,) and ThousandsSeparator being a point (.) - using Windows 10
Explanation:
I've done a little testing and found that the following functions only change the DecimalSeparator within Excel, not within VBA:
Application.UseSystemSeparators = False
Application.DecimalSeparator = "."
Application.ThousandsSeparator = ","
This means that when you change the DecimalSeparator by using these lines of code, it will simply update the values in your workbooks to be displayed in the format you are specifying. For example if your system format is:
100.000.000,99
Then the lines of code above would convert the values to:
100,000,000.99
However, when you run the code above and try to use a string that uses the non-system format for the DecimalSeparator then VBA will not recognise it.
Example:
(Where Application.DecimalSeparator = "," when Application.UseSystemSeparators = True)
Sub TestSeparator()
Application.UseSystemSeparators = False
Application.DecimalSeparator = "."
Application.ThousandsSeparator = ","
Debug.Print CDbl("100.99")
End Sub
This code will return 10099, not the expected double of 100,99 (in your system format) because VBA does not see the DecimalSeparator of "." as a DecimalSeparator.
Solution:
When referencing doubles within VBA you will need to always use the computer's system separators for thousands and decimals. If the doubles are being imported as strings you will need to use Replace to convert the string into a format that uses system separators.
Solution Example:
(Where Application.DecimalSeparator = "," when Application.UseSystemSeparators = True)
If you have the string of "100,000,000.99" in cell A1 and use the following code:
CDbl(Range("A1").Value)
It will produce a "Type mismatch" error. However if you convert this into a string that uses your system separators then no error will be given. You will need to use two Replace functions though, one to remove the ThousandsSeparators and one to convert the DecimalSeparators to your system ones:
CDbl(Replace(Replace(Range("A1").Value, ",", ""), ".", ",")
Perhaps this:
Set ws = ThisWorkbook.Worksheets("Name of Worksheet")
ws.Cells.Replace What:="", Replacement:="", LookAt:=xlPart, _ SearchOrder:=xlByRows, MatchCase:=False, SearchFormat:=True, ReplaceFormat:=True
Set ws = Nothing
I run different scripts using VBA on my German computer with an English Excel 2013 version installed on it. My local decimal settings are set to be international, e.g. 123123 is displayed as 123,123.00.
However, when I program with VBA, the decimal changes.
For example:
sub decimal_problem()
dim sDecSep as string
dim sThSep as string
sDecSep = Application.International(xlDecimalSeparator) ' sDecSep = "."
sThSep = Application.International(xlThousandsSeparator) ' sThSep = ","
Fmt= "#" & sThSep & "##0" & sDecSep & "00"
'Fmt looks like "#,##0.00" which is what I want
Msgbox(Format(123123,Fmt)) 'Fmt="#,##0.00"
end sub
The number in the Msgbox is 123.123,00 which is the German number format and definitely not the format I specified before.
When I change the format in a Spreadsheet I get the correct separators (e.g. "#,##0.00" returns 123,123.00).
Do you have a solution for that issue?
As I need to calculate with the formatted number, I try to avoid to change the number to a string and use the replace function.
Thanks for the help!
The code you mentioned above is showing the output you wanted that is 123,123.00 and not 123.123,00.
Also as soon as you will assign this value to a range in a sheet this Text value will get converted to numeric automatically. for ex - thisworkbook.sheets(1).range("a1").value = Format(123123, Fmt)--This will assign cell a1 walue as 123,123.00 which will be in numeric
please let me know if I have not understood your scenario.
I am creating an Excel file that helps people to automatically process data. Within this sheet, there are numbers that have to be parsed (and converted to other units, etc. Simple calculations).
The numbers come in US format which means they look like:
0,000,000.00
In Germany, numbers are displayed like this:
0.000.000,00
In VBA, I actually don't know, which localized Version of Excel is in use (German or English).
Question:
Is there an easy way to parse the US format numbers into data type Double regardless of the Excel localization, that is used by the user?
Some notes. I did not change locale to test.
'http://msdn.microsoft.com/en-us/library/office/bb177675(v=office.12).aspx
Debug.Print Application.International(xlCountryCode) 'Excel locale
Debug.Print Application.International(xlCountrySetting) 'Windows locale
sDecimal = Application.International(xlDecimalSeparator)
sThousand = Application.International(xlThousandsSeparator)
sNumber = "1,000,000.00"
If sThousand <> "," Then
If sDecimal <> "." Then
sNumber = Replace(sNumber, ",", "")
sNumber = Replace(sNumber, ".", sDecimal)
End If
End If
Debug.Print sNumber
A possible solution may be:
cells(y, x) = Val(Replace(cells(y, x).Text, ",", ""))
Val always uses the . as decimal mark (CDbl for example uses cultural settings, tested in a German Excel).