Home » excel » vb.net – Decimal parsing differences on separate environments

vb.net – Decimal parsing differences on separate environments

Posted by: admin April 23, 2020 Leave a comment

Questions:

Evening,

I’m bashing my head against a wall with the following problem:

  • I’m loading numbers from cells from a Number column with size=16
    and decimal places = 2 inside adBase III .dbf file.

  • These numbers, when viewed with a DbfViewer appear as: 12345.12, where there is no thousands separator and the decimal
    separator is ..

  • I parse the number from the cell in the database using decimal.parse(val).

  • I do stuff with that number.

  • I am using the ClosedXML library to paste the number into an .xlsx Excel file cell with the following formula: "=R[-1]C * 100/" & val where val is the value I obtained from the dBaseIII database file. This is done with the following statements:

    • Dim formula as String = "=R[-1]C * 100/" & project.TotalIncome(i)
    • cell.FormulaR1C1 = formula.
  • I am using two programming environments:

    1. A Windows 8.1 machine with Visual Studio 2013 Community and Office 2010.
    2. A Windows 8.1 machine with Visual Studio 2013 Ultimate and Office 2013.
  • I have made sure that both environments have the same Language, Date, Time and Number format, both for Windows and Office.

When I build and execute the program from the Option 1 Environment, everything pastes fine inside the Excel file. I navigate to the cell containing the formula, and whether or not the value obtained had decimal places, the formula is there.

However, If I build and execute the program from the Option 2 Environment, I get a:

  • Removed Records: Formula from /xl/worksheets/sheet.xml part
  • Removed Records: Formula from /xl/calcChain.xml part (calculation properties)

I tried adding a breakpoint in Environment 2, opening the Locals window and editing those values which had decimal places and everything worked as intended, whereas when I use Environment 1 I have no trouble whatsoever when the value has decimal places.

I have tried the following (in Environment 2):

Dim nfi As NumberFormatInfo = New CultureInfo("es-ES", False).NumberFormat
nfi.NumberDecimalSeparator = ","
value = Decimal.Parse(row("VALUECOL"), nfi)

also:

value = Decimal.Parse(row("VALUECOL"), New CultureInfo("es-ES"))

To no avail.

I have opened the XML file containing the Excel Sheet info in Environment 2 and found this:

<x:c r="L101" s="41">
    <x:f>L100 * 100/57125,71</x:f>
</x:c>

Whereas the definitions for the same XML file created by the Environment 1 has the following cell value:

<x:c r="L101" s="41">
    <x:f>L100 * 100/57125.71</x:f>
</x:c>

So, is it a Visual Studio Locale thing (which both have the same, as far as I can see), or am I missing something else?


EDIT: Printing out the current Locale with:

Console.WriteLine(CultureInfo.CurrentCulture.Name)

yields the same es-ES on both Environment 1 and Environment 2.


EDIT 2:
Taken from: Microsoft Office XML formats. Defective by design.

To save them time, Microsoft chose to store XML using the US English
locale regardless of all settings above. […]

Also, for Excel formulas, it means the formula names are US English
formula names, […] it implies you are willing to work with US English
function names (plus US English separators, …).

So basically it all boils down (I believe) to a pre localisation of the decimal value into the Excel XML taking into account something, somewhere.

In Environment 2, any other (non-formula) value I write to the Excel file appears in the XML as an en-US localised value (i.e. 12345.12). Most of them brought in by a dataTable import. However, since writing a formula requires the input of a string, and Visual Studio applies locale settings to said string, it ends up as 12345,12 in the Excel XML, which results in the previously mentioned errors.

So, what on earth is Visual Studio taking from Environment 1 that is different from Environment 2? All possible UI localisation options are exactly the same in both machines…

How to&Answers:

I had a similar issue before, and found that there was a different dll file in my project references. The dll’s were named the same, I only noticed because of a file size difference. Once I manually linked to the same one on both Dev machines, I got the expected results.

Like I said, my issue was different… But it did also involve excel files, and I did have Excel 2010 on one Dev machine and 2013 on the other.

Answer:

I don’t even know if this qualifies as an answer since I still have no clue about where’s the localisation variable that Environment 1 has different from Environment 2.

However, It seems Visual Studio –when using different localisations– deals internally with de-localised decimal variables, but with localised string variables. Even when checking the locals panel during debugging, the value of a decimal number stored in a dictionary entry will appear as its localised version on the keyValuePair entry, and as a de-localised en-US value when expanded:

Different localisations depending on representation

Hence, when outputting a dataTable as a whole to the Excel file, it’s written onto the XML as en-US values. On the other hand, when outputting a formula (a.k.a. a string) it pours over the localised version of the associated decimal value.

Conclusion: When dealing with Office files in localised systems, just write the data as de-localised (i.e. en-US) and let the software localise it for you.

Ended up doing the following dirty patch:

Dim formula As String = "=R[-1]C * 100/" & project.TotalIncome(i).ToString().Replace(",", ".")