Max M

Max M specjalista, devim

Temat: Obliczanie czasu na podstawie daty bieżącej i następnej

Witam, mam następujący niby prosty temat z działaniem na rekordzie bieżącym i następnym: Tabela1 i w niej sukcesywnie zapisywane pola: Data, Stan, i inne...

Potrzebuję zbudować relację tej Tabeli 1 do tabeli wirtualnej Tabela 2, która ma o 1 przesunięty rekord w dół w stosunku do Tabeli 1.

Tabela1 Tabela2(=Tabela1 przesunięta o 1 rekord!)
2013.07.02 - 2013.07.09 Czas= 2013.07.09 - 2013.07.02 = 7 dni
2013.07.09 - 2013.07.23 Czas= ....
2013.07.23 - 2013.07.31
2013.07.31 - 2013.08.13
2013.08.13 - 2013.09.19
2013.09.19 - Now()

Jednym słowem, m.in. chcę otrzymywać czas jako różnicę na daty następnej do bieżącej - czas przebywania urządzenia w danym stanie, itp. Jak to zrobić, skoro daty są całkiem dowolne (z minutami!)?
Wojciech Muszyński

Wojciech Muszyński Tworzenie aplikacji
bazodanowych
(Oracle, APEX,
Access)

Temat: Obliczanie czasu na podstawie daty bieżącej i następnej

Jeżeli dane są wprowadzane sukcesywnie i kolejność dat jest zgodna z ID (autonumerowanie) rekordu to sprawa jest stosunkowo prosta.
(Uwaga! Nie działa jeżeli stosowana jest replikacja bazy i ID są losowe, lub dane nie są wprowadzone po kolei)

Należy użyć funkcji agregującej DMax do ustalenia czasu poprzedniego rekordu.

W siatce kwerendy wpisujemy:
data_poprzednia: DMax("data";"tblTabela";"id< " & tblTabela.id)
i otrzymujemy datę

Podobnie otrzymujemy różnicę:
roznica: [data]-DMax("data";"tblTabela";"id< " & [tblTabela].[id])
Wynik otrzymujemy w dniach. Godziny i minuty są przedstawione jako ułamki dnia.
Np. 6 h to 0,25
5h:59min to 0,2499

Jeżeli chcemy godziny mieć w sensownym formacie to najłatwiej podzielić różnice na dwie części:
dni i godziny.
roznica_dni: Int([data]-DMax("data";"tblTabela";"id< " & tblTabela.id))
roznica_godzin: [data]-DMax("data";"tblTabela";"id< " & tblTabela.id)-Int([data]-DMax("data";"tblTabela";"id< " & tblTabela.id))
Dni wyświetlamy jako liczbę , natomiast polu z różnicą godzin przypisujemy maskę godzina_długa

Pełny przykład na którym testowałem. Tabela tblTreningi, zapytanie zwracające czas od poprzedniego treningu:


SELECT tblTreningi.id,
tblTreningi.aktywnosc,
tblTreningi.data,
tblTreningi.km,
DMax("data","tblTreningi","id< " & tblTreningi.id) AS data_poprzedniego_treningu,
[data]-DMax("data","tblTreningi","id< " & tblTreningi.id) AS roznica,
Int([data]-DMax("data","tblTreningi","id< " & tblTreningi.id)) AS roznica_dni,
[data]-DMax("data","tblTreningi","id< " & tblTreningi.id)-Int([data]-DMax("data","tblTreningi","id< " & tblTreningi.id)) AS roznica_godzin
FROM tblTreningi;
Max M

Max M specjalista, devim

Temat: Obliczanie czasu na podstawie daty bieżącej i następnej

Właśnie dane mogą być wprowadzane nie w kolejności występowania tych dat, czyli nie będzie to zgodne z prawdziwym ID rekordu -nic się nie da zrobić?
Wojciech Muszyński

Wojciech Muszyński Tworzenie aplikacji
bazodanowych
(Oracle, APEX,
Access)

Temat: Obliczanie czasu na podstawie daty bieżącej i następnej

Można - teoretycznie w Dmax może występować też data. Ale tylko teoretycznie, bo w testach wyszły mi null'e.

W warunku na kryteria - trzeba tak sformułować aby data była sformatowana funkcją format.
Z tym, że trzeba się dobrze zastanowić nad składnią tego kryterium. I dla dużej ilości rekordów może być to bardzo powolne.
Max M

Max M specjalista, devim

Temat: Obliczanie czasu na podstawie daty bieżącej i następnej

Datę mogę zapisywać jako liczbę real... i taką pobierać -będą jednak ułamki dni, bo data z dokładnością do minut...
Wojciech Muszyński

Wojciech Muszyński Tworzenie aplikacji
bazodanowych
(Oracle, APEX,
Access)

Temat: Obliczanie czasu na podstawie daty bieżącej i następnej

w takim przypadku wystarczy wywołanie:
DMax("data";"tblTabela";"id< " & tblTabela.id)
zamienić na:
DMax("data";"tblTabela";"data_jako_real< " & tblTabela.data_jako_real)

gdzie
data_jako_real nazwą kolumny w bazie
Max M

Max M specjalista, devim

Temat: Obliczanie czasu na podstawie daty bieżącej i następnej

Dzięki wielkie!! Ja potrzebuję tylko datę z następnego rekordu, żeby obliczyć jak długo trwa stan zapisany w rekordzie bieżącym, zmodyfikowałem to tak:

Ddata_nast: CDate(DMin("Data";"T1";"Data>" & [T1].[Data]))

gdzie Data typ: Single
Czy to zadziała zawsze, nawet wtedy, gdy rekordy nie będą wpisywane w kolejności rosnącej dat?
Dla ost. rekordu data_nst daje #Błąd -jak to rozpoznać, próbowałem isError ale nie działa.

Następna dyskusja:

Obliczanie wieku na podstaw...




Wyślij zaproszenie do