Jag vill visa information om en anställd och dennes frånvaro med hjälp av koden nedan.
Man kan naturligtvis lägga till flera olika frånvaroperioder för en anställd.
Nu är det så att info om en anställd bara ska visas en gång - men i koden nedan visas info om den anställde lika många gånger som den anställde har frånvaroperioder. Ni förstår? ;)
Hur som helst, lite fakta om koden:
- jag använder mig av användarkontroller
- jag använder mig av en codebehindfil med två klasser, en som ärver Page och en som ärver UserControl. Den klass som ärver UserControl är den nu berörda.
- all info visas på default.aspx
Användarkontrollen för att presentera info från databasen (visa_anstalld.ascx):
procedur som körs för att visa diverse info om specifik anställd
sub visa_anstalld()
'felhantering med Try .. Catch
Try
'anslut till databasen
dim Cn as new OleDbConnection(CnStr)
'kör en SQL-fråga för att hämta data ur tabellerna tbl_anstallda och tbl_franvaro
dim SQL as string = "SELECT tbl_anstallda.fornamn,tbl_anstallda.efternamn,tbl_anstallda.dt_anstallning,
tbl_anstallda.timlon,manadslon,tbl_anstallda.telnr_hem,tbl_anstallda.telnr_mobil,tbl_anstallda.anstallningsid,
tbl_franvaro.dt_start,tbl_franvaro.dt_slut,tbl_franvaro.f_orsak FROM tbl_anstallda,tbl_franvaro
WHERE tbl_anstallda.id=" & fixr(Request.Querystring("id")) & " AND tbl_anstallda.id = tbl_franvaro.aid"
dim Cm as new OleDbCommand(SQL,Cn)
dim dbRead as OleDbDataReader
dim Container as object
Cn.Open()
dbRead = Cm.ExecuteReader()
'bind data till Repeatern (finns i edit.ascx)
anstalld_fr.Datasource = dbRead
anstalld_fr.DataBind()
dbRead.Close()
Cn.Close()
'fånga felmeddelande
'Catch ex as exception
lbl_error.Visible = True
lbl_error.Text = "Ett fel uppstod.<br />Error: " & ex.Message & "<br />"
'end Try
end sub
Som ni ser skrivs info om den anställde ut 2 ggr, lika många gånger som det finns frånvaroperioder. Som ni ser så är frånvaroperioderna 12/1 - 16/1 resp. 18/1 - 26/1.
Det går ju att köra två SQL-frågor i stället för en och på så sätt lösa problemet, men det borde ju kunna gå med en SQL-fråga. :)
Problemet är din SQL fråga.
Prova att skriva SELECT DISTINCT i början av satsen...tror dock inte att det kommer att hjälpa så mitt förslag är att du selectar alla anvöndare stoppar in de i en dataset...
Tar ut varje id och select frånvaro rapporter för varje användare.
Du får ursäkt att jag inte kan VB kod så jag gör ett litet exempel i pseudokod...
för varje användare i datasettet
{
Kör select satsen för varje användare för att hämta frånvaro grejerna. Och stoppa in dem i ds.
}
Matcha ihop datan från frånvaro med användarna och visa det.
Jag trodde inte heller att det skulle gå att lösa det på set sättet.
Ledsen att säga det...men ditt problem löses enklast igenom två frågor. Eller flera...beror lite på lösningen.
Eller så får du göra en funktion som kollar alla rader med data och matachar ihop dem med samma användar id. Läser ut Namn och all annan statisk information om användaren från första raden och sedan läser du ut frånvaro rapporterna från varje rad som till hör den användaren.
Ett sätt att göra detta är att ta en tabell ur datasetet och köra en select på den....tex. ds.MinTabell.Select("userID = 1") som sedan retunerar en datarow array.... Om du vill ha kodexempel från mig får du det tyvärr bara i C#...
Du får svaret med två frågor för att den är helt klart överlägsen i kod mängd. Den kommer oxå bli mycket snabbare i med SP.
mittTypadeDataSet ds = new mittTypadeDataSet();
sqlAdapter = new SqlDataAdapter("SP_getAnv", sqlCon);
sqlAdapter.fill(ds, "tblAnv");
sqlAdapter = new SqlDataAdapter("SP_getFranvaro", sqlCon);
sqlAdapter.fill(ds, "tblFranvaro");
for(int i = 0; i < ds.tblUser.Rows.Count; i++)
{
//Här stoppar jag in datan för användaren i presenationsmediet.
DataRow[] anvData = ds.tblUserField.Select("anvID = " + ds.tblAnv[i].anvID);
for(int j = 0; j < anvData.Lenght; j++)
{
//stoppa in datan i presentationsmediet under användaren
}
}
SP_getAnv ser ut så här:
SELECT * FROM tblAnv
SP_getFranvaro ser ut så här:
SELECT * FROM tblFranvaro
Använd dig av C#...kan du inte typade datasett lär dig det!