Перейти к содержанию

Глобальные функции

Материал из Химсофт Вики

Общие сведения

Раздел Scripts предназначен для добавления программной логики непосредственно в файл макета отчета.

Это позволяет отчету быть самодостаточным: код из раздела выполняется в процессе формирования отчета.

Внутри раздела можно создавать собственные вспомогательные функции для выполнения сложных вычислений прямо «на лету».

Rounding.RoundBase()

Предварительный вариант на 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"
	
	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);
}

Примеры использования в дизайнере-конструкторе

Исходное значение Синтаксис в соответствии с формулой =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