Здравствуйте Террасофт!

В созданном "ФастРепорт" отчете реализована функция подстановки суммы прописью, следующим образом:

var
  ConvertUtils, CurrencyUtils: Variant;
   
procedure memSummaOnBeforePrint(Sender: TfrxComponent);
var
  Amount: String;
  AmountInStr: String;
begin
  Amount := FloatToStr(SUM(,ddOffering));
  AmountInStr := ConvertUtils.ScriptControl.CodeObject.AmountToStr(Amount, 'ru', 'RUB');                
  memSumma.Text := AmountInStr;  
end;

procedure frxReportOnStartReport(Sender: TfrxComponent);
var
  Connector: Variant;                                
begin
  Connector := ds_ReportInvoiceWithNDSForRussia11.GetConnector();
  ConvertUtils := Connector.Services.GetNewItemByUSI('scr_ConvertUtils');
  CurrencyUtils := Connector.Services.GetNewItemByUSI('scr_CurrencyUtils');          
end;

begin

end.

Подскажите как реализовать подстановку копеек цифрами, а остальное оставить, как было, буквами?

Нравится

7 комментариев

Игорь, могу сказать, что у нас это рализовано, возможно, не самым оптимальным методом, поскольку дорабатывался этот функционал на заре знакомства с системой, но работает так:

function PartAmountInCurrencyToString(Dataset, SumString, UE, UEkopek, ValUE, ValUEkopek){
	var kopekString = SumString.substring(SumString.lastIndexOf(UEkopek),SumString.length);
	var rubleString = SumString.substring(SumString.lastIndexOf(UE),SumString.length);
    rubleString = rubleString.substring(0,rubleString.indexOf(' '));
 
	var rubleValSring = SumString.substring(0,SumString.indexOf(UE) - 1);
	Dataset.Values('SumString') = rubleValSring + ' ' +
	rubleString + ' ' + ValUEkopek + ' ' + kopekString;
}

В качестве SumString передается то, что у Вас лежит в AmountInStr. Затем происходит запись непосредственно в Датасет... Вы можете использовать просто переменную...

По другим параметрам:
пример вызова PartAmountInCurrencyToString(Dataset,SumString, 'руб', 'коп', ruble, kopek);
при этом

			//Рубли и копейки
		    var fullSum = Dataset.ValAsStr('Amount') 
			if(fullSum.lastIndexOf(",") == -1){
		 		fullSum = fullSum + ',00';
			}
			//если "круглое" число копеек
	    	if(fullSum.lastIndexOf(",") == fullSum.length - 2){
		  	fullSum = fullSum + '0';
			}
			var ruble =  fullSum.substring(0,fullSum.lastIndexOf(","));
			var kopek = fullSum.substring(fullSum.length - 2,fullSum.length);

Надеюсь, помогла :)

Для того, чтобы внести данные изменения, необходимо откорректировать скрипт scr_ConvertUtils:

Найдите строку

ko = Propis(price = kop, CurrencyOperations.K);

и замените ее на строку

ko = CurrencyOperations.K + " копеек";

Благодарю за ответы!
Алёна ваш метод достаточно трудоемок, если не найдется более простого примера обязательно воспользуюсь вашим, отдельная вам благодарность.

Анна пример предложенный вами не работает, скрипт срабатывает, но в результате вместо копеек цифрами, много раз повторяется слово:"копеек" в разных падежах.

"Alimova Anna" написал:Для того, чтобы внести данные изменения, необходимо откорректировать скрипт scr_ConvertUtils

Анна, а если в другом месте понадобится все строкой? Мы именно из этих соображений не стали менять основной скрипт, потому что в одном месте копейки нужны цифрами, а в другом прописью...

Игорь, в таком случае попробуйте заменить скрипт scr_ConvertUtils на скрипт в приложении.

Что менялось: в функции Propis добавлен фрагмент кода

	    if(D == CurrencyOperations.K){
        	litera = price + ' ' + edinicy.split(/[\s\!,\.\?]+/g).pop();
			return litera;
        }

и в следующем фрагменте

	ko != '' ? res = ru + ' ' + ko: res = ru;
	if (CurrencyOperations.Language == 'ru') {
		ru == 'Ноль ' + CurrencyOperations.R[0] && ko != ''? res = ko: 0;
		kop == 0? res += ' ноль ' + CurrencyOperations.K[0]: 0;
	} else {
		ru == 'Нуль ' + CurrencyOperations.R[0] && ko != ''? res = ko: 0;
		kop == 0? res += ' нуль ' + CurrencyOperations.K[0]: 0;
	}

заменены строки ' ноль ' на цифру.

Алена, если Вас в разных отчетах нужно по-разному отображать копейки, тогда имеет смысл модифицировать функцию Propis:
1. Добавить в нее дополнительный параметр - копейки цифрами или буквами
2. Вызывать добавленный мною фрагмент кода по условию kopnum == true

	    if((D == CurrencyOperations.K)&&(kopnum == true)){
        	litera = price + ' ' + edinicy.split(/[\s\!,\.\?]+/g).pop();
			return litera;
        }

Аналогично поступить с фрагментом кода 0 копеек

Анна спасибо вам, теперь все работает как надо. До конца только не понял, как пользоваться этим:
-----------------------
Алена, если Вас в разных отчетах нужно по-разному отображать копейки, тогда имеет смысл модифицировать функцию Propis:
1. Добавить в нее дополнительный параметр - копейки цифрами или буквами
2. Вызывать добавленный мною фрагмент кода по условию kopnum == true

if((D == CurrencyOperations.K)&&(kopnum == true)){
litera = price + ' ' + edinicy.split(/[\s\!,\.\?]+/g).pop();
return litera;
}
Аналогично поступить с фрагментом кода 0 копеек
---------------------------------------------

Видимо вызов: "ConvertUtils.ScriptControl.CodeObject.AmountToStr(Amount, 'ru', 'RUB');" будет видоизменен? Если да то подскажите как? Если нет, получается, необходимо отлавливать отчет в котором запускается этот скрипт?

Анна, спасибо! Интересный вариант :) Вносить изменения в функцию побоялись по той причине, что "мало ли где еще она вызывается"

Показать все комментарии

Доброе время суток!

Возникла у меня в одном проекте из-за 1 копейки реальная проблема… Кажется, что такое копейка? Сегодня у нас и на гривну не много можно купить, а тут копейка! «К чему бы это он?», - спросите Вы. Объясню подробно.

В проекте, в разделе [Счета], используется двойное налогообложение продукта: Цена + НДС 20% + ННР 0,5% (или 0,1%). Попробуем математически рассчитать (округляем до второго знака после запятой):
Сумма с налогами: 300 грн
НДС 20%:
300*20/(100+20+0,5) = 49,79253112033195020746887966805
(49 грн 79 коп)
ННР 0,5%:
300*0,5/(100+20+0,5) = 1,2448132780082987551867219917012
(1 грн 24 коп)

Если мы воспользуемся стандартной функцией Math.Round() или System.Round() ( http://community.terrasoft.ua/node/1847 )
В поле ННР 0,5% увидим 1 грн 24 коп, что и стоило ожидать!

Но, внимание, если следовать расчетам бухгалтера (со ссылкой на 1С), то должно быть 1 грн 25 коп!!!
Вот эта одна копейка и испортила всю идиллию интересного проекта. Какая здесь логика?
1,2448 => 1,245 => 1,25

Прошу прощения, но тогда нужно начинать с бесконечности… А это, согласитесь, многовато.

Что бы угодить клиенту, пришлось наложить заплатку на расчет налогов:

Math.round(100* Math.round( TaxAmount *1000)/1000) / 100

М-да-а, вот такая история…
А у Вас бывали похожие казусы?

--
γνῶθι σεαυτόν

Нравится

Поделиться

8 комментариев

Так может ошибка в 1С :) Почему от точности 4 к точности 2 ножно идти через точность 3?

Если бы я только знал ПОЧЕМУ! :)

--
γνῶθι σεαυτόν

Тайна веков :) Ну, как говорится жираф большой, ему виднее :)

Вообще, отсутствие единого стандарта на округление - это извечная головная боль.

У всех свои алгоритмы, в итоге бывает очень сложно ввести приходную накладную, выписанную в другой системе.

При этом для бухгалтерии отклонение в 1 копейку - это свидетельство о возможном отклонение в миллион.

Копейка играет огромную роль в debt collection и составлении искового заявления. Если не сходятся суммы даже на копейку судья может отклонить дело по взысканию задолженности с неплательщика до предоставления "корректной информации"

Не знаю принципа расчета Вашей суммы в 1C и в бухгалтерии, почему получается итоговая сумма 1.25.
Предлагаю по своему опыту следующее решение проблемы - расчитывайте все налоги, а на последний налог отнесите сумму, равную разнице общей суммы налога и суммы уже расчитанных налогов. Недостающая копейка будет отнесена на последний налог.

Насколько мне известно в 1С бухгалтерии идет расчет сумм от цены без НДС. То есть на нее накручивается и НДС и налог на рекламу. Это соответствует методики выписки Налоговой накладной.
При попытке вести обратный расчет (от сумм с НДС) вполне может возникнуть данная проблема.

"Ковалишин Виталий aka samael" написал:1,2448 => 1,245 => 1,25
Что бы угодить клиенту, пришлось наложить заплатку на расчет налогов:
Math.round(100* Math.round( TaxAmount *1000)/1000) / 100

Это Вы созря. Могу почти гарантировать что 1С так не считает, разве что так написал какой-то безумный программист. А "Расчет налога на рекламу" как правило - это дописанные конфигурации.
Впрочем Вы сами можете посмотреть бизнесс-логику расчета в конфигурации 1С бухгалтерии. Она же есть открыта для просмотра.

Возможно, в общем Вы и правы, но в конкретном случае - другого варианта не было..

--
Cogito, ergo sum

Показать все комментарии