Глобальные функции
Внешний вид
Общие сведения
Функции, вынесенные в глобальную видимость через объект Code, позволяют централизованно управлять логикой форматирования данных.
Это избавляет от необходимости дублировать код в каждом отдельном макете и обеспечивает единообразие расчетов во всех отчетах.
Rounding.RoundBase()
Предназначена для гибкого округления числовых значений.
В отличие от стандартных функций, она поддерживает работу с отрицательными разрядами и округление до значащих цифр.
Входные параметры
value(Double) - исходное число для обработки;digits(Object)- при
Mode = 1- количество знаков после запятой (положительное) или до запятой (отрицательное); - при
Mode = 0- количество значащих цифр;
- при
mode(Object) - режим работы:1(ToDecimalPlace) - десятичное округление;0(ToSignificantPlace) - значащие цифры.
Выходные параметры
String- возвращает строковое представление числа.
Алгоритм
Функция работает по методу Away From Zero (округление от нуля).
Режим 1 (десятичное округление):
- вычисляется множитель;
- число умножается на множитель, округляется до целого и делится обратно;
- при положительном n результат форматируется с фиксированным количеством нулей после запятой.
Режим 0 (значащие цифры):
- определяется порядок числа через десятичный логарифм;
- вычисляется масштабный коэффициент, чтобы оставить ровно
nцифр; - число масштабируется, округляется и возвращается в исходный порядок;
- результат преобразуется в компактную строку (удаляются лишние нули в конце).
Примеры использования внутри ячейки
| Исходное значение | Синтаксис в соответствии с формулой =Code.Rounding.RoundBase(x, n, m)
|
Результат |
|---|---|---|
| 12345 | =Code.Rounding.RoundBase(ReportItems!variable.Value, 2, 1)
|
12345,00 |
| 12345.00 | =Code.Rounding.RoundBase(ReportItems!variable.Value, 0, 1)
|
12345 |
| 12345.01 | =Code.Rounding.RoundBase(ReportItems!variable.Value, -2, 1)
|
12300 |
| 555.55 | =Code.Rounding.RoundBase(ReportItems!variable.Value, 1, 0)
|
600 |
Примеры использования во вкладке Scripts
Return New Triteia.Rounding().RoundBase(variable, 2, 1)
или
Dim rounder As New Triteia.Rounding()
Return rounder.RoundBase(variable, 2, 1)
Предварительный вариант на VB.NET
Public Function RoundBase(ByVal xValue As Double, ByVal nDigits As Integer, ByVal mMode As Integer) As String
If xValue = 0 Then Return "0"
'Проверка аргумента nDigits, является ли пустым, остутствующим в БД или пустой строкой
Dim nDigitsFlag As Boolean = True
If nDigits Is Nothing OrElse IsDBNull(nDigits) OrElse String.IsNullOrEmpty(nDigits.ToString().Trim()) Then
nDigitsFlag = False
End If
'Проверка аргумента mMode, является ли пустым, остутствующим в БД или пустой строкой
Dim mModeFlag As Boolean = True
If mMode Is Nothing OrElse IsDBNull(mMode) OrElse String.IsNullOrEmpty(mMode.ToString().Trim()) Then
mModeFlag = False
End If
'Если хотя бы один из параметров (nDigits или mMode) отсутствует, возвращается исходное число xValue
If (nDigitsFlag = False) Or (mModeFlag = False)
Return xValue
End If
If mMode = 1 Then
' Округление до n знаков после запятой
' В отличие от стандартной функции Math.Round(value, digits, MidpointRounding.AwayFromZero)
' может работать с отрицательными digits за счет сдвига
' Вычисление множителя
Dim factor As Double = Math.Pow(10, nDigits)
' Свдиг запятой на расстояние множителя, округление до целого, обратный сдвиг
' Направление сдвига зависит от знака (+-) в nDigits
Dim result As Double = Math.Round(xValue * factor, 0, MidpointRounding.AwayFromZero) / factor
' Форматирование результата (либо до целого(0), либо по положительному nDigits)
Return result.ToString("F" & Math.Max(0, nDigits))
End If
If mMode = 0 Then
' Округление до n значащих цифр
' Определение порядка числа (до запятой)
Dim scale As Double = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(xValue))) + 1 - nDigits)
' Свдиг запятой влево (уменьшение порядка числа), округление, сдвиг вправо (увеличение порядка числа)
Dim result As Double = Math.Round(xValue / scale, 0, MidpointRounding.AwayFromZero) * scale
' Форматирование результата в компактную строку (удаление лишних нулей, научная нотация)
Return result.ToString("G")
End If
' При некорректном значении режима mMode
Return ""
End Function
Итоговый вариант на С#
public class Rounding
{
public string RoundBase(double value, int digits, RoundMode mode)
{
if (value == 0)
return "0";
double result;
switch (mode)
{
case RoundMode.ToDecimalPlace:
double factor = Math.Pow(10, digits);
result = Math.Round(value * factor, 0, MidpointRounding.AwayFromZero) / factor;
return result.ToString("F" + Math.Max(0, digits));
case RoundMode.ToSignificantPlace:
double scale = Math.Pow(10, Math.Floor(Math.Log10(Math.Abs(value))) + 1 - digits);
result = Math.Round(value / scale, 0, MidpointRounding.AwayFromZero) * scale;
return result.ToString("G");
default:
throw new ArgumentOutOfRangeException(nameof(mode), "Некорректный режим округления");
}
}
public string RoundBase(double value, int digits, int mode) => RoundBase(value, digits, (RoundMode)mode);
}