Application.DecimalSeparator 问题

Ihi*_*dan 5 excel vba

我的地区使用“,”作为小数点分隔符。当我在 Excel 2013 中运行以下代码以导入使用“.”的数字时。作为小数点分隔符,我没有收到任何错误。

Dim strGetResult As String
strGetResult = httpObject.responseText
strGetResult = Replace(strGetResult, ".", Application.DecimalSeparator)
Run Code Online (Sandbox Code Playgroud)

但是,当我在 Excel 2010 中尝试同样使用“,”作为小数分隔符的代码时,我没有得到相同的结果。调试显示 Application.DecimalSeparator = "." 这是没有意义的,因为在 Excel 中输入数字时带有“,”分隔符。

知道为什么会这样吗?

God*_*ith 5

我遇到了同样的问题,并设法在此线程中找到了答案。

Application.DecimalSeparator 仅在用户选中 UseSystemSeparators 选项时才相关。

例如,如果 Application.UseSystemSeparators = True,Application.DecimalSeparator 的值并不反映 Excel 实际使用的内容。如果在Application.DecimalSeparatorMSDN 文档中对此进行了描述,那就太好了,但事实并非如此。

mrexcel 线程还包含一个优雅的解决方案;而不是调用 Application.DecimalSeparator,创建一个函数

Public Function GetDecimalSeparator()

    GetDecimalSeparator = Mid(Format(1000, "#,##0.00"), 6, 1)

End Function
Run Code Online (Sandbox Code Playgroud)

并调用它。我使用了这种方法,它似乎工作正常。


小智 2

我的地区还使用“,”作为小数点分隔符和“.”。用于千位分隔符。我过去也遇到过类似的问题。不幸的是,我现在无法重复该错误,但我记得更改 Excel 的小数分隔符也没有解决问题。

我能找到的唯一解决方法(我不太喜欢)是通过 Workbook_Open 中的代码切换小数和千位分隔符,并在 Workbook_BeforeClose 中将它们更改回原始分隔符。好的部分是工作簿继续显示原始分隔符,而代码使用更改后的分隔符。这样用户就不会看到任何差异。

我想您可以使用此技术将区域设置更改为 httpObject 使用的区域设置,仅用于导入过程并消除代码的替换部分。

原始解决方案在这里找到:http ://www.xtremevbtalk.com/archive/index.php/t-138511.html 。

将下面的代码放入标准模块中。调用InitLocale将小数点分隔符设置为“.” 千位分隔符为“,”。调用RestoreLocale恢复原来的设置。两个命名范围(rDecimal 和 rThousand)用于存储原始设置,但如果您在同一过程中更改回原始设置,则可能不需要这样做。

Declare PtrSafe Function GetLocaleInfo Lib "kernel32" Alias "GetLocaleInfoA" _
(ByVal LOCALE As Long, ByVal LCType As Long, ByVal lpLCData As String, ByVal cchData As Long) As Long
Declare PtrSafe Function GetUserDefaultLCID% Lib "kernel32" ()
Declare PtrSafe Function SetLocaleInfo Lib "kernel32" Alias "SetLocaleInfoA" _
(ByVal LOCALE As Long, ByVal LCType As Long, ByVal lpLCData As String) As Long
Public Const LOCALE_SCURRENCY = &H14
Public Const LOCALE_SDECIMAL = &HE
Public Const LOCALE_STHOUSAND = &HF

Public SDECIMAL As String
Public STHOUSAND As String
Public LOCALE As Long
Public rDecimal As Range, rThousand As Range


Sub FixLocale()
    Set rDecimal = ActiveWorkbook.Names("sDecimal").RefersToRange
    Set rThousand = ActiveWorkbook.Names("sThousand").RefersToRange
    Call GetLocale
    rDecimal = SDECIMAL
    rThousand = STHOUSAND
    If SDECIMAL <> "." Or STHOUSAND <> "," Then
        Call SetLocale(".", ",")
    End If
End Sub

Sub RestoreLocale()
    Set rDecimal = ActiveWorkbook.Names("sDecimal").RefersToRange
    Set rThousand = ActiveWorkbook.Names("sThousand").RefersToRange
    Call GetLocale
    If SDECIMAL <> rDecimal Or STHOUSAND <> rThousand Then
        Call SetLocale(rDecimal.Value, rThousand.Value)
    End If
End Sub

Sub GetLocale()
    Dim Symbol As String
    Dim iRet1 As Long
    Dim iRet2 As Long
    Dim lpLCDataVar As String
    Dim Pos

    LOCALE = GetUserDefaultLCID()

    iRet1 = GetLocaleInfo(LOCALE, LOCALE_SDECIMAL, lpLCDataVar, 0)
    Symbol = String$(iRet1, 0)
    iRet2 = GetLocaleInfo(LOCALE, LOCALE_SDECIMAL, Symbol, iRet1)
    Pos = InStr(Symbol, Chr$(0))
    If Pos > 0 Then
        SDECIMAL = Left$(Symbol, Pos - 1)
    Else
        MsgBox ("Error geting LOCALE")
    End If

    iRet1 = GetLocaleInfo(LOCALE, LOCALE_STHOUSAND, lpLCDataVar, 0)
    Symbol = String$(iRet1, 0)
    iRet2 = GetLocaleInfo(LOCALE, LOCALE_STHOUSAND, Symbol, iRet1)
    Pos = InStr(Symbol, Chr$(0))
    If Pos > 0 Then
        STHOUSAND = Left$(Symbol, Pos - 1)
    Else
        MsgBox ("Error geting LOCALE")
    End If

End Sub

Sub SetLocale(SymbDecimal As String, SymbThousand As String)
    LOCALE = GetUserDefaultLCID()
    iRet1 = SetLocaleInfo(LOCALE, LOCALE_SDECIMAL, SymbDecimal)
    LOCALE = GetUserDefaultLCID()
    iRet1 = SetLocaleInfo(LOCALE, LOCALE_STHOUSAND, SymbThousand)
End Sub
Run Code Online (Sandbox Code Playgroud)