webForumDet fria alternativet

Avancerad uträkning

ASP

22 svar · 1 373 visningar · startad av MickeA.com

Medlem sedan feb. 20034 441 inlägg
Frågan#1

Tjena
Jag hämtar data från SQL Server och ska sedan göra ett antal uträkningar för att presentera resulten på en hemsida.
Problemet är att vi idag upptäckte att det inte stämmer fullt ut.

Mina kolumner i databasen:

nBRake, decimal(12,2)
nBonus, decimal(12,2)
nNettorake, decimal(12,2)

Min SQLfråga ser ut såhär:

sql =	"SELECT " &_
	"id AS id_test, cID, LEFT(pDate, 6) AS pMonth, pPeriod, SUM(nBRake) AS sumBRake, SUM(nBonus) AS sumBonus, SUM(nNettorake) AS nNetto, SUM(nRakeback) AS sumRakeback, nCurrency " &_
	"FROM payout " &_
	"WHERE cID IN " &_
	"(" &_
	"SELECT id " &_
	"FROM customers " &_
	"WHERE nReferer = " & nCustId &_
	") " &_
	"AND pSite = '" & rsSites ("sSajt") & "' " &_
	"GROUP BY pPeriod, cID, pDate, nCurrency, id"

Senare körs följande kod för att få till alla resultat "rätt":

result = ""
					If Len(rsMonths("nNetto") & "") > 0 Then
						nNetto = cdBL(rsMonths("nNetto"))
						result = (percent_amount/100) * nNetto
						result = Round(result, 2)
					Else
						If Len(rsMonths("sumBRake") & "") > 0 Then
							bruttorake	= cdBL(rsMonths("sumBRake"))
							sumBonus	= cdBL(rsMonths("sumBonus"))
							result = bruttorake - sumBonus * (percent_amount/100)
						Else
							bruttorake	= cdBL(rsMonths("sumBRake"))
							result = bruttorake * (percent_amount/100)
						End If
						
						result = Round(result, 2)
					End If

Problemet är att kolumnen nNettorake kan innehålla ett decimaltal, bara 0 (noll) eller inget alls (""). Med fältet nBonus kan det se likadant ut, dvs. ett decimaltal, 0 eller "" (inget...).
Uträkningen ska ske enl. följande:

- Om nNettorake INTE är noll eller "" ska det räknas [i]nNettorake * procent_amount / 100[/i] (kan vara tex. 2.5% eller 5%.
- Om nNettorake ÄR noll eller "" OCH nBonus INTE är noll eller "" ska det vara [i]sumBRake - sumBonus * procent_amount / 100.[/i]
- Om nNettorake ÄR noll eller "" OCH nBonus ÄR noll eller "" ska det vara [i]sumBRake * percent_amount / 100.

Det är på det sistnämnda nått blir fel, för hur jag än gör så faller ifsatsen tillbaks på varken if eller else, utan result blir exakt samma som sumBRake

Har ni några förslag på vad jag gör fel?

Tack!

Medlem sedan dec. 20025 483 inlägg
#2

Testa

if isnumeric(nNettorake) and cdbl(nNettorake) <> 0 then
 'nNettorake * procent_amount / 100
else
 if not isnumeric(nBonus) or cdbl(nBonus) <> 0 then
  'sumBRake - sumBonus * procent_amount / 100
 else
  'sumBRake * percent_amount / 100
 end if
end if
Medlem sedan feb. 20034 441 inlägg
#3

Nu följde jag ditt exempel och får samma felmess som jag fått många gånger tidigare:

Körningsfel i Microsoft VBScript (0x800A005E)
Ogiltig användning av Null: 'Cdbl'
/*********.se/_newpage/cust_referred.asp, line 263

Koden ser ut såhär:

result = ""
sumBonus	= rsMonths("sumBonus")
sumBRake	= rsMonths("sumBRake")
nNettorake	= rsMonths("nNetto")

[red]If Isnumeric(nNettorake) And Cdbl(nNettorake) <> 0 Then[/red]
	result = nNettorake * procent_amount / 100
Else
	If Isnumeric(nBonus) Or Cdbl(nBonus) <> 0 Then
		result = sumBRake - sumBonus * procent_amount / 100
	Else
		result = sumBRake * percent_amount / 100
	End If
End If

Rad 263 är rödmarkerad ovan.

Medlem sedan juni 20014 421 inlägg
#4
If Isnumeric(nNettorake) then
 if Cdbl(nNettorake) <> 0 Then
   ...
 end if
end if
Medlem sedan feb. 20034 441 inlägg
#5

Nu funkar det nästan, men har en fråga.
Kolumner som är av typen "decimal(12,2)" i SQL Server, hur tolkar ASP kommatecken som decimaler.
Tror nämligen att det kan ställa tilll det, för på vissa ställen verkar jag ha punktdecimal.
Hur tolkas det och vilken av dessa är egentligen rätt?

Medlem sedan dec. 19996 721 inlägg
#6

Huruvida det är punkt eller komma är bara intressant om värdet representeras som en sträng, och det gör det ju inte med decimal(12,2).

När ASP konverterar strängvärden till decimalvärden (cdbl) så görs det baserat på regioninställningarna i systemet.

Medlem sedan feb. 20034 441 inlägg
#7

aha, tack, bra att veta.
Nu verkar jag ha fått till det,. det visas rätt överallt.

Saken är bara den att det här med uträkningar i ASP inte verkar lira som det ska.
De här sätten funkar inte:

resultat = x - y * z / 100
resultat = (x - y) * (z / 100)

z = z / 100
resultat = (x - y) * z

Så jag testade följande och då funkar det kanon, frågan är ju bara varför?

resultat = x - y
z = z / 100
resultat = resultat * z

Får inget fel på "dom som inte funkar", utan den struntar bara i att ta bort y från x samt att den struntar i att dela z med 100.

Skumt?

Medlem sedan feb. 20034 441 inlägg
#8

Tjena
Nu har jag dykt på problem igen med det här scriptet.
Även fast det i förekommer ett tal i nNettoRake så struntar scriptet i att basera uträkningen på detta, utan den tar iaf. brutto - bonus, vilket strular till sig på vissa ställen.

Så här ser scriptet ut:

result		= 0
sumBonus	= rsMonths("sumBonus")
sumBRake	= rsMonths("sumBRake")
nNettorake	= rsMonths("nNetto")
proc_amount	= percent_amount / 100
If Isnumeric(nNettorake) Then
	If Cdbl(nNettorake) <> 0 Then
		result = cdbl(nNettorake) * proc_amount
	End If
Else
	If Isnumeric(sumBonus) Or Cdbl(sumBonus) <> 0 Then
		result = cdbl(sumBRake) - cdbl(sumBonus)
		result = result * proc_amount
	Else
		result = cdbl(sumBRake) * proc_amount
	End If
End If
result = Round(result, 2)

Det som ska ske är alltså att uträkningen i första hand ska ske med nNettorake.

Några förslag?
Måste få ihop det här, tack!

Medlem sedan juni 200032 967 inlägg
#9

Exakt vad innehåller nNettorake när det inte funkar då?

Medlem sedan feb. 20034 441 inlägg
#10

@nders skrev:

Exakt vad innehåller nNettorake när det inte funkar då?

Det är lite lurigt.
Ibland innehåller det 0 (tal), ibland "" (helt tom sträng) och ibland ett decimaltal.
När nNettorake inte är 0 och ett tal så är det oftast ett tal med fyra decimaler.
Datatypen är decimal(12, 2) och DBMS SQL-Server 2000.

Det min uträkning ska göra är att _om_:
- nNettorake inte är tom, räkna nNettorake * procentsats / 100
- Om nNettorake är tom, räkna sumBRake - sumBonus * procentsats / 100
- Om nNettorake är tom, sumBonus är tom, räkna sumBRake * procentsats / 100

Det som spökar nu är alltså att den räknar sumBRake - sumBonus * procentsats / 100 trots att nNettorake innehåller 747,86.

Det konstiga är att den räknar bara fel såhär ibland, så det bör vara nått fel på själva posten, eller nått.

Medlem sedan juni 200032 967 inlägg
#11

Har du samma regional settings på sql server som webbserver? Om du får ett decimaltal med punkt och din webbserver vill ha decimaltal med komma så får du helt enkelt byta ut till rätt decimaltecken.

Medlem sedan feb. 20034 441 inlägg
#12

aha, undra om det kan vara så då?
Det konstiga är ju just att all statistik (som det här rör) reggas med decimalpunkt, eftersom det inte går att köra sqlfrågan med kommadecimal.

Webbhotellet är Surftown (Servrarna i Danmark..?!) och enl. dom ska det vara Dansk (Svensk) LCID när det gäller tid osv. så det bör väl vara samma med tal, eller..?

Vad vill SQL Server ha förresten?
Kollade lite snabbt precis i databasen och det är kommadecimal på de ställen jag ser.

Medlem sedan feb. 20034 441 inlägg
#13

Nu har jag nog fått till det.
Lade till If Not IsNull(nNettorake) Then nNettorake = Replace(nNettorake, ".", ",") End If precis under nNettorake = rsMonths("nNetto") och då blev det rätt på raden jag hängt upp mig på.
Kör vidare såhär ett tag och återkommer om det strular nått mer.

Tack!

Medlem sedan juni 200032 967 inlägg
#14

Vad vill SQL Server ha förresten?

I SQL-frågor: alltid punkt.

Kollade lite snabbt precis i databasen och det är kommadecimal på de ställen jag ser.

Vad kollade du med? Programmet du kollar med byter säkert decimaltecken till det som passar i given miljö.

Jag brukar, när jag råkar på dessa problem göra så här:

  1. Kolla med en division i asp vilket decimaltecken som gäller, typ ta tecken två i resultatet av 1/2.
  2. Byt ut punkt och komma till detta tecken med replace.
  3. Typkonvertera till double efter isnumeric-kontroll.
Medlem sedan feb. 20034 441 inlägg
#15

Aha, okej, alltså att man helt enkelt skriver ut Response.Write(Mid(1/2, 2)).
Ska kolla på dina övriga punkter lite mer, tack!

Medlem sedan juni 200032 967 inlägg
#16

Även om din hårdkodade replace hjälper dig nu, så funkar den inte nödvändigtvis överallt. Om du flyttar på din applikation till en annan server kan saker och ting sluta att fungera, därför brukar jag göra en funktion som kontrollerar vilket decimaltecken som gäller, och sedan ersätter till det. Vi har ett tiotal webb- och SQL-servrar som är lite olika installerade, som våra applikationer körs på, så för oss funkar det inte att hårdkoda någonting som har med regional settings att göra.

Medlem sedan feb. 20034 441 inlägg
#17

Aha, såpass... Då kanske det är vettigt att jag följer dina råd, då vi är pågång att sätta upp en dedikerad server med samma site både i tyskland och polen.

;)

Medlem sedan juni 20031 837 inlägg
#18

Hade precis problem med konvertering av sträng till decimaltal. i den ena applikationen fungerade det med punkt och i den andre med komma.En lösning var att tvinga applikationen att byta standard.

Jag körde också med replace innan men efter ett tag så slutade det fungera för mig. Tror jag bytta utvecklingsserver så jag fick olika inställningar.

Denna koden är i och för sig för C# .Net men man kan säkert lätt anpassa den för asp.

System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en-us");

Kanske inte den bästa lösningen men det fungerade bra för mig.

Medlem sedan juni 200032 967 inlägg
#19

Man kan använda sig av setlocale("en-us") i ASP, men man är ju fortfarande beroende av att SQL-servrar och annat levererar med rätt decimaltecken.

Då får man dock andra problem, till exempel att man måste hantera datum på ett totalt idiotiskt format.

Medlem sedan feb. 20034 441 inlägg
#20

Nu har jag följt din 3-stegslista ovan, @nders:

result		= 0
sumBonus	= rsMonths("sumBonus")
sumBRake	= rsMonths("sumBRake")
nNettorake	= rsMonths("nNetto")
[red]use_as_dec	= Mid(1 / 2, 2, 1)

If Not IsNull(sumBonus) Then 
	sumBonus	= Replace(sumBonus, ".", use_as_dec)
	sumBonus	= Replace(sumBonus, ",", use_as_dec)					
End If
If Not IsNull(sumBRake) Then 
	sumBRake	= Replace(sumBRake, ".", use_as_dec)
	sumBRake	= Replace(sumBRake, ",", use_as_dec)					
End If
If Not IsNull(nNettorake) Then 
	nNettorake	= Replace(nNettorake, ".", use_as_dec)
	nNettorake	= Replace(nNettorake, ",", use_as_dec)					
End If
[/red]
proc_amount = percent_amount / 100
If Isnumeric(nNettorake) Then
	[red]nNettorake = CDbl(nNettorake)[/red]
	result = CDbl(nNettorake) * proc_amount
Else
	If IsNumeric(sumBonus) Then
		[red]sumBonus = CDbl(sumBonus)[/red]
		result = CDbl(sumBRake) - sumBonus
		result = result * proc_amount
	Else
		[red]sumBRake	= CDbl(sumBRake)[/red]
		result		= sumBRake * proc_amount
	End If
End If
result = Round(result, 2)

Det rödfärgade är ditlagt nu.
Jag får inga felmess så allt verkar funka.
Har jag gjort rätt nu, kommer samma sida funka på en server där man har något annat tecken som decimal?

269 ms totalt · 4 externa anrop · v20260731065814-full.a51de22e
130 ms — deklarationer (db)
0 ms — hämta statistik (cache)
135 ms — hämta tråd, inlägg och bilagor (db)
131 ms — ändringar (db)