Excel - Формат значения (маска)
Я хотел бы отформатировать значение ячейки следующим образом:
1234,980 -> 1,234,980
12237119867,761 -> 12,237.119,867,761
Как подготовить общую маску, которая установит точки как тысячи разделителей и запятую для десятичных дробей. Маска должна работать для любого заданного значения.
1 ответ
Определите первый сегмент слева от десятичной точки. Он будет автоматически продублирован по мере необходимости.
Количество окто-верпов после точки задает максимальное количество знаков после запятой после точки, будет использоваться только необходимое число.
Что-то вроде:
#.###,0##
(Я предполагаю, что это будет действительным для вашей текущей локали).
Как следует из комментария phoog, независимый от локали формат будет:
#,###.0##
(используйте это, чтобы установить формат, используя Cell.NumberFormat = "#,###.0##"
)
Что касается некоторого кода VBA, у вас может быть улучшенная версия Format
функция, которая принимает две локали, одна из которых является строкой форматирования, а другая используется для форматирования результата.
Поместите следующее в отдельный модуль:
Option Explicit
Private Declare Function VarTokenizeFormatString Lib "oleaut32.dll" (ByVal pstrFormat As Long, ByRef rgbTok As Any, ByVal cbTok As Long, ByVal iFirstDay As VbDayOfWeek, ByVal iFirstWeek As VbFirstWeekOfYear, ByVal lcid As Long, ByRef pcbActual As Long) As Long
Private Declare Function VarFormatFromTokens Lib "oleaut32.dll" (ByRef pvarIn As Variant, ByVal pstrFormat As Long, ByRef pbTokCur As Any, ByVal dwFlags As Long, ByRef pbstrOut As Long, ByVal lcid As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Const S_OK As Long = 0
Private Const E_INVALIDARG As Long = &H80070057
Private Const E_OUTOFMEMORY As Long = &H8007000E
Private Const DISP_E_BUFFERTOOSMALL As Long = &H80020013
Private Const DISP_E_TYPEMISMATCH As Long = &H80020005
Public Function FormatForLocale(ByVal Expression As Variant, Optional ByVal Format As String, Optional ByVal FirstDayOfWeek As VbDayOfWeek = vbUseSystemDayOfWeek, Optional ByVal FirstWeekOfYear As VbFirstWeekOfYear = vbUseSystem, Optional ByVal PatternLocaleID As Long = 0, Optional ByVal TargetLocaleID As Long = 0) As String
Dim b() As Byte, t As Long
Dim hResult As Long
Dim pBstrResult As Long, res As String
Const CHUNK_SIZE As Long = 256
If TypeOf Expression Is Excel.Range Then
Expression = Expression.Value
End If
ReDim b(1 To CHUNK_SIZE)
Do
hResult = VarTokenizeFormatString(StrPtr(Format), b(LBound(b)), UBound(b) - LBound(b) + 1, FirstDayOfWeek, FirstWeekOfYear, PatternLocaleID, t)
Select Case hResult
Case S_OK
Exit Do
Case E_INVALIDARG
Err.Raise 5, , "Some arguments are invalid."
Case DISP_E_BUFFERTOOSMALL
ReDim b(LBound(b) To UBound(b) + CHUNK_SIZE)
Case Else
Err.Raise 5, , "Internal error. Unexpected error code returned from system."
End Select
Loop
Select Case VarFormatFromTokens(Expression, StrPtr(Format), b(LBound(b)), 0, pBstrResult, TargetLocaleID)
Case S_OK
CopyMemory ByVal VarPtr(res), pBstrResult, 4
Case E_OUTOFMEMORY
Err.Raise 7
Case E_INVALIDARG
Err.Raise 5, , "Some arguments are invalid."
Case DISP_E_TYPEMISMATCH
Err.Raise 5, , "The argument could not be coerced to the specified type."
Case Else
Err.Raise 5, , "Internal error. Unexpected error code returned from system."
End Select
FormatForLocale = res
End Function
Теперь у вас есть функция, FormatForLocale
, что имитирует VBA по умолчанию Format
функция, но добавляет два дополнительных параметра. Чтобы получить желаемый результат, вы можете сделать:
result = FormatForLocale(123456789, "#,###.0##", , , LOCALE_INVARIANT, LOCALE_GERMAN)
где LOCALE_INVARIANT
а также LOCALE_GERMAN
константы вы можете посмотреть здесь.
Вы также можете позвонить с рабочего листа:
=FormatForLocale(123456789,"#,###.0##",,,127,3079)