#excel #vba #localization
Вопрос:
Мой макрос запускается на виртуальной машине, которая по какой-то причине использует «,» как разделитель тысяч и десятичных знаков. Я хочу избежать какой-либо зависимости от региональных настроек на этом компьютере.
В книге, созданной макросом, установлен флажок для отображения сумм в тысячах. Я реализовал это как условное форматирование, которое применяется, когда установлен флажок («установлен»). Условие форматирования.Свойство NumberFormat, по-видимому, требует строки локального формата. Я не знаю, возможно ли создать эту строку, когда тысячи и десятичные разделители одинаковы.
Я рассматривал возможность не использовать форматирование, а фактически разделить и округлить значения, когда флажок установлен, но, поскольку я вычисляю сумму этих значений, это приведет к ошибкам округления ниже по потоку.
В качестве примера этот код;
Sub TestFormatting()
Dim aRange As Range
Dim baseFormats
Dim condFormat As String
Dim aNumber As Long
Dim bIndex As Integer
Dim cIndex As Integer
baseFormats = Array("General", "###,###,##0")
condFormat = "0" Application.International(xlThousandsSeparator)
aNumber = 123456789
Application.Workbooks.Add
With ActiveSheet
.Cells(1, 1) = "NumberFormat"
.Cells(2, 1) = "Conditional NumberFormat"
.Cells(3, 1) = "=TRUE"
.Cells(4, 1) = "=FALSE"
For bIndex = 0 To UBound(baseFormats)
.Cells(1, 2 bIndex) = baseFormats(bIndex)
.Cells(2, 2 bIndex) = condFormat
.Cells(3, 2 bIndex) = aNumber
.Cells(4, 2 bIndex) = aNumber
Set aRange = .Range(.Cells(3, 2 bIndex), .Cells(4, 2 bIndex))
aRange.NumberFormat = baseFormats(bIndex)
Call aRange.FormatConditions.Add(xlExpression, , "=$A3")
aRange.FormatConditions(1).NumberFormat = condFormat
Next bIndex
With .UsedRange.columns
.ColumnWidth = 30
.HorizontalAlignment = xlRight
End With
End With
End Sub
При запуске с описанными региональными настройками (оба разделителя»,») генерируется следующий вывод:
Я хочу, чтобы он генерировал тот же вывод, что и при переходе на использование точки («.») в качестве десятичного разделителя:
Ответ №1:
Я не совсем уверен, как это работает, но это обновление кода, похоже, делает свое дело:
Sub TestFormatting()
Dim aRange As Range
Dim baseFormats
Dim condFormat As String
Dim aNumber As Long
Dim bIndex As Integer
Dim cIndex As Integer
Dim xstSep As String
baseFormats = Array("General", "###,###,##0")
aNumber = 123456789
Application.Workbooks.Add
With ActiveSheet
.Cells(1, 1) = "NumberFormat"
.Cells(2, 1) = "Conditional NumberFormat"
.Cells(3, 1) = "=TRUE"
.Cells(4, 1) = "=FALSE"
For bIndex = 0 To UBound(baseFormats)
.Cells(1, 2 bIndex) = baseFormats(bIndex)
.Cells(3, 2 bIndex) = aNumber
.Cells(4, 2 bIndex) = aNumber
Set aRange = .Range(.Cells(3, 2 bIndex), .Cells(4, 2 bIndex))
aRange.NumberFormat = baseFormats(bIndex)
Call aRange.FormatConditions.Add(xlExpression, , "=$A3")
' >>> Temporarily change decimal separator and evaluate the conditional format string
xstSep = Application.DecimalSeparator
Application.DecimalSeparator = "."
Application.UseSystemSeparators = False
condFormat = "0" Application.International(xlThousandsSeparator) ' Moved here from above
.Cells(2, 2 bIndex) = condFormat ' Moved here from above
aRange.FormatConditions(1).NumberFormat = condFormat
Application.UseSystemSeparators = True
Application.DecimalSeparator = xstSep
' <<<
Next bIndex
With .UsedRange.columns
.ColumnWidth = 30
.HorizontalAlignment = xlRight
End With
End With
End Sub
Что он делает, так это временно устанавливает десятичный разделитель на точку (.) во время применения числового формата.