09. december 2006 - 12:04Der er
21 kommentarer og 2 løsninger
Beregne brændstofforbrug
Jeg har en tabel der indeholder felterne: Køretøj, dato, km stand, liter, snit periode, snit total Der indtaster jeg som det nok kan gættes, nogle data hver gang jeg fylder brændstof på en bil (køretøj er fordi der er flere biler) Hvordan laver jeg nemmest en funktion der løber tabellen igennem og beregner snit periode og snit total. Jeg har det lavet i et regneark, men af forskellige årsager er jeg nødt il at kunne lave det i Access også.
Det er desværre ikke så simpelt. Så vidt jeg kan se skal jeg have lavet en funktion der løber tabellen igennem og læser 2 records ad gangen ind og laver beregningerne. Der skal jo bruges tal fra 2 records for at beregne antal km mellem aktuelle tankning og sidste tankning for at kunne beregne snit pr. liter
In a query it should be possible to make a sub select which finds the previous records kM and subtracts it from the current records KM then devide that with the ltrs.
Unless it is more complicated than that it shouldnt be necessary to make a function
Synes godt om
Slettet bruger
11. december 2006 - 23:32#5
Hvis du nu kalder din tabel: tblBrændstofForbrug
Så lav en forespørgsel, som du kalder Snit total:
SELECT tblBrændstofForbrug.Køretøj, (Max([Km stand])-Min([km stand]))/(Sum([liter])-First([liter])) AS [Snit total] FROM tblBrændstofForbrug GROUP BY tblBrændstofForbrug.Køretøj ORDER BY tblBrændstofForbrug.Køretøj;
Så en forespørgsel, som du kalder Snit periode:
SELECT tblBrændstofForbrug.Køretøj, (Max([Km stand])-Min([km stand]))/(Sum([liter])-First([liter])) AS [Snit periode] FROM tblBrændstofForbrug WHERE (((tblBrændstofForbrug.Dato) Between [Dato fra:] And [Dato til:])) GROUP BY tblBrændstofForbrug.Køretøj ORDER BY tblBrændstofForbrug.Køretøj;
og til sidst en forespørgsel, den kunne hedde Snit:
Tja, det nemmeste er nok at lave lidt kode, som gennemløber tabellen og opdaterer den, for som du jo selv er inde på, så er SQL i sig selv ikke en ørn til beregninger, som baserer sig på to på hinanden følgende rækker. Så mit forslag ville være en kode som ligner denne:
Public Sub Beregnforbrug() Dim rs As Recordset Dim NuvKøretøj As String Dim TidlKilometerstand as Long Dim TidlLiterantal as Integer Dim SumKilometer as Integer Dim SumLiterAntal as Integer Dim FørsteMåling As Boolean : FørsteMåling = True Set rs = CurrentDb.OpenRecordset("SELECT * FROM tblBrændstofForbrug ORDER BY Køretøj, dato") Do While not rs.EOF If FørsteMåling = True Then NuvKøretøj = rs.Fields("Køretøj") TidlKilometerstand = rs.Fields("Kilometerstand") TidlLiterantal = rs.Fields("Liter") SumKilometer = 0 SumLiterantal = 0 rs.Fields("SnitPeriode") = Null rs.Fields("SnitTotal") = Null FørsteMåling = False Else rs.Fields("SnitPeriode") = (rs.Fields("Kilometerstand") - TidlKilometerstand) / TidlLiterAntal SumKilometer = SumKilometer + (rs.Fields("Kilometerstand") - TidlKilometerstand) SumLiterantal = SumLiterAntal + TidlLiterantal rs.Fields("SnitTotal") = SumKilometer / SumLiterantal End If rs.Update rs.MoveNext If not rs.EOF And rs.Fields("Køretøj") <> NuvKøretøj Then FørsteMåling = True End If Loop End Sub
Der er ikke tale om aftestet kode, så ingen garanti, men du kan forhåbentlig få en idé om, hvad jeg mener... :-)
Indtil videre siger jeg tak for indlæg - på grund af arbejdssituation går der lige lidt inden jeg får tid til at teste, men jeg vender tilbage hurtigst muligt.
kjulius> jeg har brugt dit forslag som oplæg til en funktion der gør det jeg gerne vil have den til (ser det i hvert fald ud til :-) ) så smid lige et svar så du kan få point
spg> du har ret i at man 'normalt' ikke gemmer beregninger i en tabel, men nogen gange kan det være hensigtsmæssigt at gøre det, f.eks. af hastighedsmæssige årsager. Her er der tale om at skulle vise nogle tal i en subform og det går simpelthen for langsomt at bregne hver gang der flyttes en record så jeg vil hellere have lidt ventetid første gang formen åbnes og så undgå brok når der bladres.
Men tak for dit bud som sandsynligvis vil kunne gøre det også, men jeg holder mig i dette tilfælde altså til funktionen.
SELECT tblHugo.Køretøj, tblHugo.dato, tblHugo.km, tblHugo.liter, ([km]-CLng(nz((SELECT max(km) from tblHugo H WHERE H.[køretøj] = [tblHugo].[Køretøj] and h.dato < [tblHugo].[dato]),0)))/[liter] AS AvgPer, ([km]-CLng(nz((SELECT max(km) from tblHugo H WHERE H.[køretøj] = [tblHugo].[Køretøj] and h.dato < [tblHugo].[dato]),0))) AS KmPeriod, ([km]-(SELECT min(km) from tblHugo H WHERE H.[køretøj] = [tblHugo].[Køretøj]))/(SELECT sum(liter) from tblHugo H WHERE H.[køretøj] = [tblHugo].[Køretøj] and h.dato <= [tblHugo].[dato]) AS AvgTot, (SELECT sum(liter) from tblHugo H WHERE H.[køretøj] = [tblHugo].[Køretøj] and h.dato <= [tblHugo].[dato]) AS tLtrs FROM tblHugo;
Jeg er godt klar over, at min lille funktion også kan laves i en forespørgsel, men SQL er bare ikke optimeret til at beregne ud fra data i to på hinanden følgende rækker. Men selvfølgelig kan det gøres hvis hver række kan identificeres via en unik værdi, og jeg har da også før givet eksempler på, hvordan det kan gøres . Eksempelvis her:
Det spørgsmål jeg referer til er godt nok vedr. MySQL, men det ændrer ikke noget i den grundlæggende funktionalitet i SQL forespørgslen, selv om syntaxen kan være lidt forskellig i de to databaser.
Terry fik lidt for sin query som ser ud til at gøre det også, men da jeg brugte funtionsoplæget, så får den størstedelen
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.