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

Глобальные функции: различия между версиями

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


<syntaxhighlight lang="vb">
<syntaxhighlight lang="vb">
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
</syntaxhighlight>
</syntaxhighlight>


<syntaxhighlight lang="vb">
<syntaxhighlight lang="csharp">
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);
}
</syntaxhighlight>
</syntaxhighlight>


Пример использования:
Пример использования:
<syntaxhighlight lang="vb">=Code.Rounding.RoundBase(Fields!D1.Value, 2, 1)</syntaxhighlight>
<syntaxhighlight lang="vb">=Code.Rounding.RoundBase(Fields!D1.Value, 2, 1)</syntaxhighlight>

Версия от 04:21, 11 марта 2026

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

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

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

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

Rounding.RoundBase()

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(Fields!D1.Value, 2, 1)