How to set decimal separator in MS Access using VBA? - vba

My software creates PAIN001.XML files directly from an Access financial database. The decimal separator must always be a dot. The numbers are formatted with:
MyText = Format(MyNumber, "#0.00")
However, the format string's dot is automatically replaced by the system decimal separator, which might be "," instead of "." !
In Excel there are easy solutions, for example:
Application.DecimalSeparator = "."
...
However, MS Access doesn't recognize this application property.
Is there a simple way to define a decimal separator within Access vba code ?
Of course, one can create a function which scans each MyText number for wrong decimal separators and replaces them with a dot, but this function would have to be called separately for each number, slowing down the code quite a lot…

The decimal separator must always be a dot.
Then use Str:
MyText = Str(MyNumber)
To convert such a string to a number use Val:
MyNumber = Val(MyText)

I guess the problem is not solveable with the decimal separator Application.DecimalSeparator = ".", even if it was supported by the Access library. It is a rather complicated issue, for the non-US users, as we are used to have , as a decimal separator.
In general, VBA considers only . as a decimal separator. Without taking care of the application default separator, the location of the user and their settings. Thus, some interesting cases could happen:
Sub TestMe()
Dim myText As String
myText = "123,42"
Debug.Print Replace(Format(myText, "#0.00"), ",", ".")
End Sub
A possible solution, that I have implemented some time ago was to use Replace() and to replace as in the gif above. It could be a bit slow indeed, but taking into account the usage of VBA and Access, extreme speed is not something the app could achieve anyway.

Related

How do you use " (double quotes) in a formula in OpenOffice VBA? For instance with Replace()

I am looking to replace double quotes, ", with backslash escaped double quotes - \".
I read online that you can use double quotes in VBA, if you use two double quotes inside the main double quotes. But, this didn't seem to work for me. For instance I tried the following code:
Function ADDSLASHES(InputString As String)
NewString = Replace(InputString, "\", "\\")
NewString = Replace(NewString, "'", "\'")
NewString = Replace(NewString, """", "\""")
ADDSLASHES = NewString
End Function
When I tested it, this function successfully substituted the single backslash and the single quotes, but not the doule quotes.
I also read that you can use CHR(34), and elsewhere to use CHR(147). But this too didn't work. I tried the following lines:
NewString = Replace(NewString, CHR(34), "\"+CHR(34))
NewString = Replace(NewString, CHR(147), "\"+CHR(147))
But testing it out with a cell that had double quotes did not work. Am I doing something wrong? How might I use double quotes with the Replace() function?
When I entered a"b in a cell, Calc converted it to a right double quote, not a left one. Adding this line made it work:
NewString = Replace(NewString, CHR(148), "\"+CHR(148))
Be aware that x94 (decimal 148) is an extended ASCII encoded character, which is something I would avoid at all costs. It's strongly recommended to only use the first 128 characters as ASCII and to use Unicode for everything else.
The Unicode value for a right double quotation mark is U+201D. Sadly, apparently LibreOffice Basic does not have a native way to work with such values. There is ChrW but that requires the VBA compatibility option. Another method is to call the UNICODE() spreadsheet function from Basic, but that is cumbersome.
My preference: Don't use Basic for anything important. LibreOffice macros can be written in Python instead, which has strong Unicode support.
EDIT:
One thing I forgot to mention yesterday: Select a quotation mark in the formula bar and press Alt+x to find out what it really is. This will convert it to the Unicode value and then back again.
EDIT 2:
That's correct—Alt+X only works in LibreOffice, not AOO. Also for some reason, the extended ASCII code above doesn't seem to work in AOO. Maybe that's not a bad thing. Anyway, here is the Unicode spreadsheet function access approach, and it works for me in both AOO and LO.
fa = createUnoService("com.sun.star.sheet.FunctionAccess")
ch = fa.CallFunction("UNICHAR", Array(CLng("&H201D"))
NewString = Replace(NewString, ch, "\"+ch)
If this doesn't work, then you probably have something else in the cell. To figure out what it is, you could install LibreOffice. Or there are lots of other ways; most often I use GVim text editor. Also I just now googled and found https://www.branah.com/unicode-converter where you can paste some text and see the actual UTF-16 hexadecimal values.

Range accepts sometimes only semicolons instead of commas

I have reduced my problem to the following code example. I am using a German Excel version in which separators in normal Excel formulas are semicolons ";" instead of "," (e.g. =SUMME(A1;A3) instead of =SUM(A1,A3)).
Now the code which works different from time to time:
Sub CommasDoNotWorkAnymore()
Dim a()
Dim i%
a = Array("A1,A3,A5", "B1", "B2")
i = 0
Debug.Print Sheets(1).Range(a(i)).Address
End Sub
Normally, when starting Excel, this code works. But sometimes Excel seem to switch the accepted separators used in the Range() to semicolons untill I restart Excel. This occurs most times when rerunning the code after a runtime error.
Is this a general Excel bug? Does anybody know what is behind this behaviour? Is there some Excel-wide "local option" for the Range class?
EDIT: I just tried to convert the a(i) with CStr(a(i) but this does also not work. So no ByRef kind of problem...
If you want to control it, check first what separator is currently in use. What I guess is that you want to know the list separator:
Application.International(xlListSeparator)
Check other separators here:
https://msdn.microsoft.com/en-us/vba/excel-vba/articles/application-international-property-excel
The other time I had a problem with identifying decimal separator in VBA. Finnally I was able to get it in this way:
Function GetVBAdecimalSep()
Dim a(0) As Variant
a(0) = 1 / 2
GetVBAdecimalSep = Mid(a(0), 2, 1)
End Function
Changing separator not always works. Please see this: Changing decimal separator in VBA (not only in Excel)
The best solution is to check/change locale, even temporary.
Application.LanguageSettings.LanguageID(msoLanguageIDUI)
gives the LCID which would be 1033 for English (US)

Determine Number of Lines in a String Read in from an Access Database

I am writing a program in Visual Basic that writes and reads to and from a Microsoft Access Database. When reading from the database, one of the functions that I am trying to perform is to determine the number of lines in a multi-line string that was written to the database and then subsequently read from the database. Here's what I have tried so far with no luck.
Dim stringLines() As String = databaseReader("multilineString").ToString.Split(CChar("Environment.NewLine"))
Dim stringLinesCount As Integer = stringLines.Length
For some reason, this always results in stringLinesCount being equal to one, regardless of how many lines the string has. In this example, I am using Environment.NewLine, but I have tried \n, \r, vbCr, vbLf, and vbCrLf as well, and they all result in a value of one. Since none of these seem to be working, what can I use instead to determine the number of lines?
Edit:
Dim splitCharacters() As Char = {CChar(vbCrLf), CChar(vbCr), CChar(vbLf), CChar(Environment.NewLine), CChar("\n"), CChar("\r")}
Dim stringLines() As String = databaseReader("multilineString").ToString.Split(splitCharacters)
Dim stringLinesCount As Integer = stringLines.Length
Since Chris Dunaway provided the answer that I view as helpful but posted it as a comment, here's what he said:
VB cannot use C# style escape sequences, so CChar("\n") and CChar("\r") is meaningless in VB. Also, calling CChar("Environment.NewLine") is wrong because you are trying to convert the actual string "Environment.NewLine" to a single character, which obviously won't work. You can just use Environment.Newline directly in the call to String.Split.
If Chris decides to post his comment as an answer, please let me know so that I may remove this.

Data download from PHP is not split into newlines

I am retrieving data from web. Data is seperated by each line. Data looks like this
Data1
Data2
Data3
I want to alert for each data found on the webpage. Tried this,
Dim Lines() As String
Dim stringSeparators() As String = {vbCrLf}
Dim Source As String
Dim wc As New WebClient
Source = wc.DownloadString("http://www.example.com/data.php")
Lines = Source.Split(stringSeparators, StringSplitOptions.None)
For Each s As String In Lines
MsgBox(s)
Next
But unfortunately, it alerts once all the data. My question is, how to alert for each data ?
vbCrLf, as defined in Constants, won't match a single UNIX-style newline - "Newline" (\n), LF/LINEFEED, ASCII 10 - character as transmitted from PHP.
To deal with both Windows and UNIX/Linux end-of-line sequences, use:
Dim stringSeparators() As String = {vbLf, vbCrLf}
The order the separators supplied does not matter, see the remarks in String.Split for details.
While the above solves the problem in a fairly robust manner, it may better to use the exact EOL format, especially when writing - and to make a selection prior based on established format. In this case that might be only using vbLf which would work for the given PHP output, but would incorrectly leave in CR characters for Windows text files.
When dealing with system-native text files, or Windows components such as Controls, vbNewLine should generally be preferred over vbCrLf: vbCrlLf is appropriate when the goal is to be explicit, as above, and only accept/emit a specific ASCII sequence as mandated by protocols and conventions.
When dealing with whitespace characters, I often end up running the String.Asc() method on them, to see what they really are.
http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.strings.asc(v=vs.110).aspx
Then, you can ensure that you are splitting on the correct character.

Isolate a a substring within quotes from an entire line

To start here is an example of a line I am trying to manipulate:
trait slot QName(PrivateNamespace("*", "com.company.assembleegameclient.ui:StatusBar"), "_-0IA") type QName(PackageNamespace(""), "Boolean") value False() end
I wrote a code that will go through and read through each line and stop at the appropriate line. What I am trying to achieve now is to read through the characters and save just the
_-0IA
to a new string. I tried using Trim(), Replace(), and indexof so far but I am having a ton of difficulties because of the quotation marks. Has anyone deal with this issue before?
Assuming your source string will always follow a strict format with only some data changes, something like this might work:
'Split the string by "," and extract the 3rd element. Trim the space and _
quotation mark from the front and extract the first 5 characters.
Dim targetstr As String = sourcestr.Split(","c)(2).TrimStart(" """.ToCharArray).Substring(0, 5)
If the length of the target string is variable it can be done like this:
Dim temp As String = teststr.Split(","c)(2).TrimStart(" """.ToCharArray)
'Use the index of the next quotation mark instead of a fixed length
Dim targetstr As String = temp.Substring(0, temp.IndexOf(""""c))