不同环境下的十进制解析差异
Decimal parsing differences on separate environments
晚上,
我正在用头撞墙,遇到以下问题:
我正在使用 size=16
从 Number
列的单元格中加载数字
和 decimal places = 2
在 dBase III .dbf
文件中。
这些数字,当用 DbfViewer
查看时显示为:12345.12
,其中没有千位分隔符和小数点
分隔符是 .
.
我使用decimal.parse(val)
解析数据库单元格中的数字。
我用那个数字做事。
我正在使用 ClosedXML
库将数字粘贴到 .xlsx
Excel 文件单元格中,公式如下:"=R[-1]C * 100/" & val
其中 val
是我从 dBaseIII
数据库文件中获取的值。这是通过以下语句完成的:
Dim formula as String = "=R[-1]C * 100/" & project.TotalIncome(i)
cell.FormulaR1C1 = formula
.
我正在使用两个编程环境:
- 一台
Windows 8.1
机器 Visual Studio 2013 Community
和 Office 2010
。
- 一台
Windows 8.1
机器 Visual Studio 2013 Ultimate
和 Office 2013
。
我已确保两个环境具有相同的 Language, Date, Time and Number
格式,对于 Windows 和 Office。
当我从 Option 1 Environment
构建并执行程序时,一切都很好地粘贴到 Excel 文件中。我导航到包含公式的单元格,无论获得的 value
是否有小数位,公式都在那里。
但是,如果我从Option 2 Environment
构建并执行程序,我得到:
Removed Records: Formula from /xl/worksheets/sheet.xml part
Removed Records: Formula from /xl/calcChain.xml part (calculation properties)
我尝试在 Environment 2
中添加一个断点,打开 Locals
window 并编辑那些有小数位的 values
并且一切都按预期工作,而当我使用 Environment 1
当 value
有小数位时我没有任何问题。
我尝试了以下方法(在 Environment 2
中):
Dim nfi As NumberFormatInfo = New CultureInfo("es-ES", False).NumberFormat
nfi.NumberDecimalSeparator = ","
value = Decimal.Parse(row("VALUECOL"), nfi)
还有:
value = Decimal.Parse(row("VALUECOL"), New CultureInfo("es-ES"))
无济于事。
我打开了包含 Excel Sheet 信息的 XML 文件 Environment 2
并找到了这个:
<x:c r="L101" s="41">
<x:f>L100 * 100/57125,71</x:f>
</x:c>
而 Environment 1
创建的同一 XML 文件的定义具有以下单元格值:
<x:c r="L101" s="41">
<x:f>L100 * 100/57125.71</x:f>
</x:c>
所以,它是 Visual Studio 语言环境的东西(据我所知,两者具有相同的东西),还是我遗漏了其他东西?
编辑: 打印当前语言环境:
Console.WriteLine(CultureInfo.CurrentCulture.Name)
在 Environment 1
和 Environment 2
上产生相同的 es-ES
。
编辑 2:
摘自: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, ...).
所以基本上这一切都归结为(我相信)将 decimal
值预先定位到 Excel XML
中,同时考虑到 某事,某处 .
在 Environment 2
中,我写入 Excel 文件的任何其他(非公式)值在 XML
中显示为 en-US
本地化值(即 12345.12
).其中大部分是由 dataTable
进口带来的。但是,由于编写公式需要输入字符串,并且 Visual Studio 将语言环境设置应用于所述字符串,因此在 Excel XML
中最终为 12345,12
,从而导致前面提到的错误.
那么, 究竟是 Visual Studio 从 Environment 1
中提取的,与 不同的 [=40] =]?所有可能的 UI 本地化选项在两台机器上完全相同...
我之前遇到过类似的问题,发现我的项目引用中有不同的dll文件。 dll 的名称相同,我只是因为文件大小不同才注意到。一旦我在两台开发机器上手动链接到同一个,我就得到了预期的结果。
就像我说的,我的问题是不同的...但它也涉及 excel 个文件,我确实在一台开发机器上有 Excel 2010,在另一台机器上有 2013。
我什至不知道这是否可以作为答案,因为我仍然不知道 Environment 1
与 Environment 2
的本地化变量在哪里。
但是,似乎Visual Studio -使用不同的本地化- 处理内部 与去本地化 decimal
变量,但具有本地化 string
变量。即使在调试期间检查 locals
面板,存储在 dictionary
条目中的 decimal
数字的值将作为其本地化版本出现在 keyValuePair
条目中,并作为展开时去本地化 en-US
值:
因此,当dataTable
作为一个整体输出到Excel文件时,它被写入XML作为en-US
值。另一方面,当输出公式 (a.k.a.a string
) 时,它会覆盖相关 decimal
值的本地化版本。
结论:在本地化系统中处理 Office 文件时,只需将数据写入非本地化(即 en-US
),然后让软件为您本地化。
完成了以下脏补丁:
Dim formula As String = "=R[-1]C * 100/" & project.TotalIncome(i).ToString().Replace(",", ".")
晚上,
我正在用头撞墙,遇到以下问题:
我正在使用
size=16
从Number
列的单元格中加载数字 和decimal places = 2
在dBase III .dbf
文件中。这些数字,当用
DbfViewer
查看时显示为:12345.12
,其中没有千位分隔符和小数点 分隔符是.
.我使用
decimal.parse(val)
解析数据库单元格中的数字。我用那个数字做事。
我正在使用
ClosedXML
库将数字粘贴到.xlsx
Excel 文件单元格中,公式如下:"=R[-1]C * 100/" & val
其中val
是我从dBaseIII
数据库文件中获取的值。这是通过以下语句完成的:Dim formula as String = "=R[-1]C * 100/" & project.TotalIncome(i)
cell.FormulaR1C1 = formula
.
我正在使用两个编程环境:
- 一台
Windows 8.1
机器Visual Studio 2013 Community
和Office 2010
。 - 一台
Windows 8.1
机器Visual Studio 2013 Ultimate
和Office 2013
。
- 一台
我已确保两个环境具有相同的
Language, Date, Time and Number
格式,对于 Windows 和 Office。
当我从 Option 1 Environment
构建并执行程序时,一切都很好地粘贴到 Excel 文件中。我导航到包含公式的单元格,无论获得的 value
是否有小数位,公式都在那里。
但是,如果我从Option 2 Environment
构建并执行程序,我得到:
Removed Records: Formula from /xl/worksheets/sheet.xml part
Removed Records: Formula from /xl/calcChain.xml part (calculation properties)
我尝试在 Environment 2
中添加一个断点,打开 Locals
window 并编辑那些有小数位的 values
并且一切都按预期工作,而当我使用 Environment 1
当 value
有小数位时我没有任何问题。
我尝试了以下方法(在 Environment 2
中):
Dim nfi As NumberFormatInfo = New CultureInfo("es-ES", False).NumberFormat
nfi.NumberDecimalSeparator = ","
value = Decimal.Parse(row("VALUECOL"), nfi)
还有:
value = Decimal.Parse(row("VALUECOL"), New CultureInfo("es-ES"))
无济于事。
我打开了包含 Excel Sheet 信息的 XML 文件 Environment 2
并找到了这个:
<x:c r="L101" s="41">
<x:f>L100 * 100/57125,71</x:f>
</x:c>
而 Environment 1
创建的同一 XML 文件的定义具有以下单元格值:
<x:c r="L101" s="41">
<x:f>L100 * 100/57125.71</x:f>
</x:c>
所以,它是 Visual Studio 语言环境的东西(据我所知,两者具有相同的东西),还是我遗漏了其他东西?
编辑: 打印当前语言环境:
Console.WriteLine(CultureInfo.CurrentCulture.Name)
在 Environment 1
和 Environment 2
上产生相同的 es-ES
。
编辑 2: 摘自: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, ...).
所以基本上这一切都归结为(我相信)将 decimal
值预先定位到 Excel XML
中,同时考虑到 某事,某处 .
在 Environment 2
中,我写入 Excel 文件的任何其他(非公式)值在 XML
中显示为 en-US
本地化值(即 12345.12
).其中大部分是由 dataTable
进口带来的。但是,由于编写公式需要输入字符串,并且 Visual Studio 将语言环境设置应用于所述字符串,因此在 Excel XML
中最终为 12345,12
,从而导致前面提到的错误.
那么, 究竟是 Visual Studio 从 Environment 1
中提取的,与 不同的 [=40] =]?所有可能的 UI 本地化选项在两台机器上完全相同...
我之前遇到过类似的问题,发现我的项目引用中有不同的dll文件。 dll 的名称相同,我只是因为文件大小不同才注意到。一旦我在两台开发机器上手动链接到同一个,我就得到了预期的结果。
就像我说的,我的问题是不同的...但它也涉及 excel 个文件,我确实在一台开发机器上有 Excel 2010,在另一台机器上有 2013。
我什至不知道这是否可以作为答案,因为我仍然不知道 Environment 1
与 Environment 2
的本地化变量在哪里。
但是,似乎Visual Studio -使用不同的本地化- 处理内部 与去本地化 decimal
变量,但具有本地化 string
变量。即使在调试期间检查 locals
面板,存储在 dictionary
条目中的 decimal
数字的值将作为其本地化版本出现在 keyValuePair
条目中,并作为展开时去本地化 en-US
值:
因此,当dataTable
作为一个整体输出到Excel文件时,它被写入XML作为en-US
值。另一方面,当输出公式 (a.k.a.a string
) 时,它会覆盖相关 decimal
值的本地化版本。
结论:在本地化系统中处理 Office 文件时,只需将数据写入非本地化(即 en-US
),然后让软件为您本地化。
完成了以下脏补丁:
Dim formula As String = "=R[-1]C * 100/" & project.TotalIncome(i).ToString().Replace(",", ".")