Проблема с округлением после перехода к adp

User_06
Дата: 27.09.2005 17:40:49
В mdb округлялкой работала следующая функция (не моя, исторически сложилось):

Public Function Okr(Ch) As Currency
Ch = Nz(Ch, 0)
Okr = CCur(Ch / 100) * 100
End Function

Перехожу на adp. В запросах нужно писать аналогичную ф-ию для SQL (внимание - цель не соорудить более "правильную" функцию. Основная цель - чтобы цифры в "новой" программе максимально точно соответствовали цифрам "старой". Т.е. нужен полный аналог, работающий по тем же принципам). В SQL пока не особо силен. Попытался соорудить нечто вроде:


ALTER FUNCTION dbo.Okr
(@Ch float)

RETURNS money

AS
BEGIN
RETURN
isnull(convert(money, @Ch/100)*100,0)

END

Посмотрел - разница при подсчете сумм все равно имеется. В итого наиболее приближенные результаты получил с помощью след. функции:


ALTER FUNCTION dbo.Okr
(@Ch float)

RETURNS money

AS
BEGIN
RETURN
isnull(round(@Ch,2),0)

END

Но все равно полной идентичности достичь не удается. Проблема в том, что в формах в строках работает старая функция, а в запросах, где подсчитываются суммы - новая. Один пример.
1-я позиция 101,50
2-я позиция 101,50
Сумма - 203,00
Курс - 37,07
Старая функция округляет в меньшую сторону: 101,5*37,07=3762,605=3762,6*2=7525,2
Новая (которая используется при подсчете суммы) в большую -
101,5*37,07=3762,605=3762,61*2=7525,22

В итоге по строкам (где используется старая функция) должно быть 7525,2.
А получается же 7525,22 , т.е. на 2 коп. больше.
Вообще есть возможность сделать так, чтобы новая функция работала полностью идентично старой?
ANTIVIR
Дата: 27.09.2005 17:53:24
Поиск по форуму СКЛ Сервер юзали? Я думаю там полно было тему по поводу округления
User_06
Дата: 27.09.2005 17:56:49
Там ничего похожего не нашел.
На всякий случай, туда запостил.
Iskander68
Дата: 27.09.2005 18:02:47


А эта старая Okr чем-нибудь отличается от встроенной Round()? Попробуй
Sub testround()
Dim curPrice As Currency
Dim curQty As Currency
Dim curSum As Currency

curPrice = 101.5
curQty = 37.07
curSum = curPrice * curQty


Debug.Print curSum; Round(curSum, 2)
curSum = curSum * 2
Debug.Print curSum; Round(curSum, 1)


'3762,605=3762,6*2=7525,2
End Sub


И ты пробовал скульную ф-цию Round?

--
Regards
Alexander Artamonov


"User_06" <nospam@sql.ru> сообщил/сообщила в новостях следующее:
news:1915402@sql.ru...
В mdb округлялкой работала следующая функция (не моя, исторически
сложилось):

Public Function Okr(Ch) As Currency
Ch = Nz(Ch, 0)
Okr = CCur(Ch / 100) * 100
End Function

Перехожу на adp. В запросах нужно писать аналогичную ф-ию для SQL
(внимание - цель не соорудить более "правильную" функцию. Основная цель -
чтобы цифры в "новой" программе максимально точно соответствовали цифрам
"старой". Т.е. нужен полный аналог, работающий по тем же принципам). В SQL
пока не особо силен. Попытался соорудить нечто вроде:


ALTER FUNCTION dbo.Okr
(@Ch float)

RETURNS money

AS
BEGIN
RETURN
isnull(convert(money, @Ch/100)*100,0)

END

Посмотрел - разница при подсчете сумм все равно имеется. В итого наиболее
приближенные результаты получил с помощью след. функции:


ALTER FUNCTION dbo.Okr
(@Ch float)

RETURNS money

AS
BEGIN
RETURN
isnull(round(@Ch,2),0)

END

Но все равно полной идентичности достичь не удается. Проблема в том, что в
формах в строках работает старая функция, а в запросах, где подсчитываются
суммы - новая. Один пример.
1-я позиция 101,50
2-я позиция 101,50
Сумма - 203,00
Курс - 37,07
Старая функция округляет в меньшую сторону:
101,5*37,07=3762,605=3762,6*2=7525,2
Новая (которая используется при подсчете суммы) в большую -
101,5*37,07=3762,605=3762,61*2=7525,22

В итоге по строкам (где используется старая функция) должно быть 7525,2.
А получается же 7525,22 , т.е. на 2 коп. больше.
Вообще есть возможность сделать так, чтобы новая функция работала
полностью идентично старой?
Тема Ответить

Posted via ActualForum NNTP Server 1.3

Toking
Дата: 27.09.2005 19:32:42
Действительно интересная бага получается

Если в Access написать так:

Public Function Okr(Ch as Double) As Currency
  Ch = Nz(Ch, 0)
  Okr = CCur(Ch / 100) * 100
End Function

... то все будет работать правильно, т.е. 101,5*37,07=3762,605=3762,61*2=7525,22

Выходит, что функция CCur некорректно конвертирует аргументы типа variant/double.

Теперь о решении проблемы. Для того чтобы суммы сошлись можно исправить функцию Okr в Access, добавив описание типа аргумента. А в MSSQL использовать функцию Round(@Ch, 2).

Либо можно записать в MSSQL так Round(@Ch - 0.001, 2) ... тогда исправится этот перекос Акса.
ANTIVIR
Дата: 27.09.2005 20:09:45
Toking
Действительно интересная бага получается
Выходит, что функция CCur некорректно конвертирует аргументы типа variant/double.

И в чем же не корректность ее работы?
Toking
Дата: 28.09.2005 15:00:38
А вот посмотрите

  Dim V, D As Double
  
  D = 3762.605
  V = D

  Debug.Print CCur(CDbl(V) / 100#), CCur(V / 100#), CCur(D / 100#)

... и попробуйте объяснить почему разные результаты
Поверьте, нам будет интересно

------------------------------
MS Access (10.6501.6714) SP 3
ANTIVIR
Дата: 28.09.2005 15:10:24
Toking
А вот посмотрите

Вы проделываете какие то операции с цифрами, а потом вам CCur не корректен, не вижу связи...Помоему CCur делает все правильно, как и должен

Debug.Print CCur(CDbl(V) / 100#), CCur(V / 100), CCur(D / 100), CCur(D), D / 100

 37,6261       37,6261       37,6261       3762,6051     37,626051111 
От 37,626051111 CCur как и должен берет 4 занка после запятой...что не так?
LeonM
Дата: 28.09.2005 15:11:38
'CCur(CDbl(V) / 100#)=CCur(37.62605)=>37,6261
'CCur(V / 100#)=CCur(37.6260)=>>37,626
'CCur(D / 100#)=CCur(CDbl(V) / 100#)
ANTIVIR
Дата: 28.09.2005 15:17:57
Dim V, D As Double
  Dim c As Double
  D = 3762.605
  V = D
  c = V

  Debug.Print CCur(CDbl(V) / 100#), CCur(V / 100#), CCur(D / 100#), CCur(c / 100#)
37,6261 37,626 37,6261 37,6261

Помоему дело все так не Ccur а в храненние чисел double и вариант