Consiglio se usare una tabella o no

martedì 01 settembre 2009 - 09.25

Anonimo Profilo | Senior Member

Ciao a tutti!
Il problema è il seguente: in una pagina ho una tabella dedicata al timesheet per i dipendenti. Su un'altra pagina voglio riportare una specie di tabella dove vorrei rappresentare sulle colonne i mesi dell'anno, e sulle righe il nome dei dipendenti. Se nel mese di gennaio/2009 il dipendente pippo ha lavorato 160 ore o di più questo timesheet per quel mese è completo, altrimenti è incompleto. In pratica questa pagina è per l'admin, per controllare lo stato dei timesheet per ogni dipendente. Quindi sul campo pippo - gennaio/2009 immetterò completo o incompleto, a seconda dello stato del timesheet di quel mese per quell'utente.
Come mi consigliate di farlo? Immaginate che i dipendenti sono circa 45, quindi verrebbero 45 - 46 righe per 12 - 13 colonne se facessi una tabella.. troppe righe!
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Direi che una Gridview paginata potrebbe essere una buona soluzione...
Gli bindi il tuo recordset con il quale hai estrapolato i dati che ti servono e potresti intercettare l'evento RowDataBound per gestire il discorso completo/incompleto. E' una possibilità, credo ci siano moltissime soluzioni e cmq direi che è molto consigliato l'utilizzo di una struttura a tabella.
Ciao

Anonimo Profilo | Senior Member

Vorrei fare una tabella normale ma non vorrei che diventasse pesante.
Se usassi Crystal Report? E' buono?
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Buono è buono ma viene utilizzato per generare report, è questo quello che vuoi?
Se vuoi usare una semplice tabella allora potresti usare un repeater, un item per ogni dipendente

Anonimo Profilo | Senior Member

Ok grazie ora provo il repeater (che tra l'altro sarà la prima volta che lo userò).
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Dai un'occhiata qui:

http://quickstarts.asp.net/QuickStartv20/aspnet/doc/ctrlref/data/repeater.aspx

Ciao

Anonimo Profilo | Senior Member

Grazie! E' abbastanza semplice.
E' più opportuno creare queste colonne ("mese/anno", "dipendente", "stato timesheet") oppure una colonna per ogni mese, e una riga per ogni dipendente? Spero di essermi spiegato bene.
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

La seconda che hai detto ... e nella cella il valore corrispettivo completo/incompleto

Anonimo Profilo | Senior Member

Mi trovo in una certa difficoltà. Nel db ho una tabella con i seguenti campi: ID_Stato (numero progressivo), ID_Timesheet (mm/aaaa), ID_Dipendente e Stato (completo/incompleto). Per le celle del repeater potrei eseguire un comando sql? Mi spiego meglio: nelle celle sotto le 12 colonne rappresentate i mesi dell'anno ho messo:

<td> <%# DataBinder.Eval(Container.DataItem, "Stato")%> </td>

...per ogni colonna. Quindi ho fatto 12 volte quella riga di codice.
Ho un unico record in quella tabella del db che è: '5', '08/2009', 'afantoni', 'Completo'.
Ma il problema è il seguente: quando avvio il debug nella pagina aspx mi legge chiaramente una riga sola ma con tutte le celle scritte "Completo". In pratica mi fa vedere che tutti i timesheet dell'anno 2009 sono completi, anche se nel db c'è solo un record per il mese di agosto! C'è un modo quindi di mettere una where con ID_Stato magari? Oppure ID_Timesheet uguale a l'Header text di ogni colonna?
Il problema successivo sarà quando dovrò calcolare il "completo/incompleto" usando la SUM delle ore di ogni timesheet..
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Scusa ma non avendo il quadro di insieme di tutte le tabelle che utilizzi non riesco a farmi un'idea chiara del modo in cui memorizzi i dati, cmq il problema che ti da il repeater è che in realtà tu gli passi sempre lo stesso campo, il recordset che gli bindi deve contenere un campo per ogni mese dell'anno preso in considerazione, praticamente nella query devi ricavarti lo stato (completo/incompleto) e associarlo ad un campo per esempio ... as gennaio, ... as febbraio, dopodichè nella markup assegni ad ogni td il valore di ogni mese...

Anonimo Profilo | Senior Member

>Scusa ma non avendo il quadro di insieme di tutte le tabelle
>che utilizzi non riesco a farmi un'idea chiara del modo in cui
>memorizzi i dati, cmq il problema che ti da il repeater è che
>in realtà tu gli passi sempre lo stesso campo, il recordset che
>gli bindi deve contenere un campo per ogni mese dell'anno preso
>in considerazione, praticamente nella query devi ricavarti lo
>stato (completo/incompleto) e associarlo ad un campo per esempio
>... as gennaio, ... as febbraio, dopodichè nella markup assegni
>ad ogni td il valore di ogni mese...

Scusa ripartiamo dal db.
Ho la tabella dei dipendenti e la tabella dei timesheet. Dipendenti contiene:

* ID_Dipendente (nome d'accesso al sito)
* Matricola
* Cognome
* Nome
* Centro_costo (settore di lavoro).

Timesheet invece:

* ID_Timesheet (mm/aaaa)
* ID_Dipendente
* Data_Timesheet (gg/mm/aaaa)
* Cod_Arca (codice cliente)
* ID_Commessa (codice commessa)
* Ore (ore lavorate)

Mi rendo conto che quella tabella Stato_timesheet non serve a nulla vero? Il repeater deve caricare dati da queste due tabelle di sopra che ti ho descritto giusto?
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Mi sembrano tabelle normalizzate quindi è inutile crearne un'altra, procedendo uno step alla volta, riesci a ricavare un recordset contenente i campi:

id_dipendente
somma delle ore lavorate a gennaio 2009
somma delle ore lavorate a febbraio 2009
etc... ?

Anonimo Profilo | Senior Member

Sì.
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

ora nel <ItemTemplate> del repeater inserisci:
<td> <%# DataBinder.Eval(Container.DataItem, "id_dipendente")%> </td>
<td> <%# DataBinder.Eval(Container.DataItem, "gennaio")%> </td>
<td> <%# DataBinder.Eval(Container.DataItem, "febbraio")%> </td>
etc

a questo punto ti dovrebbe visualizzare una tabella con i valori ricavati...

un passo successivo potrebbe essere quello di ricavare al posto delle ore lo stato completo/incompleto, si potrebbe realizzare già nella query utilizzando per esempio:

IF(totale_ore_gennaio<160,'Incompleto','Completo') AS gennaio, IF(totale_ore_febbraio<160,'Incompleto','Completo') AS febbraio

a questo punto il repeater al posto delle ore stampa la stringa voluta...

Anonimo Profilo | Senior Member

Stop!

Allora.. la query sarebbe questa:

select distinct ID_Dipendente, ID_Timesheet, sum(Ore)
from Timesheet
group by ID_Dipendente, ID_Timesheet

Affinché io possa scrivere nell'ItemTemplate:

<td> <%# DataBinder.Eval(Container.DataItem, "gennaio")%> </td>
<td> <%# DataBinder.Eval(Container.DataItem, "febbraio")%> </td>

come faccio a fargli capire "gennaio"... ?
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Devi cercare di avere tutte le info per ogni dipendente sulla stessa riga in questo modo si può lavorare tranquillamente sui dati

Anonimo Profilo | Senior Member

select distinct ID_Dipendente, sum(Ore) as Gennaio, sum(Ore) as Febbraio, sum(Ore) as Marzo
from Timesheet
group by ID_Dipendente

Il risultato sono 4 colonne (ID_Dipendente, Gennaio, Febbraio, Marzo), ma le somme sono uguali (per forza), non riesco a far capire che nella colonna Gennaio ci dev'essere solo la somma di Gennaio.
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Purtroppo non sono un esperto di database, cmq penso che potresti procedere in due modi:
ho cambi la struttura della tabella timesheet, in modo da avere già i dati divisi almeno per mese e magari con un campo anno per distinguere i record,
oppure,
nella query che hai scritto su usare delle select annidate per ricavare ogni singola somma delle ore...

Anonimo Profilo | Senior Member

Mi piacerebbe utilizzare le subquery a questo punto perché se tocco la tabella timesheet rovino un lavorone di almeno due mesi...
--------------------------------------------------------------------------

Allan Felipe

Anonimo Profilo | Senior Member

Qualcuno mi potrebbe aiutare riguardo questa query?
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Ho fatto questa prova per i mesi fino a marzo ipotizzando che il controllo sulla data sia sul campo id_timesheet,giusto?:

SELECT DISTINCT ID_Dipendente, (SELECT SUM(Ore) FROM timesheet WHERE LEFT(id_timesheet,2)='01' AND RIGHT(id_timesheet,4)='2009') AS Gennaio, (SELECT SUM(Ore) FROM timesheet WHERE LEFT(id_timesheet,2)='02' AND RIGHT(id_timesheet,4)='2009') AS Febbraio, (SELECT SUM(Ore) FROM timesheet WHERE LEFT(id_timesheet,2)='03' AND RIGHT(id_timesheet,4)='2009') AS Marzo
FROM Timesheet
GROUP BY ID_Dipendente

Anonimo Profilo | Senior Member

Cavolo io le subselect non ci sono riuscito a farle.. poi non me le ricordavo le funzioni left e right. Grazie mille!
Ora ci sarebbe da sostituire i risultati delle somme con lo stato del ts mensile, quindi usando l'if come dicevi prima no?
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Si metti la sub select dentro l'if così ti stampa la stringa invece della somma

Anonimo Profilo | Senior Member

Ho provato in due modi. Entrambi sbagliati:

SELECT DISTINCT ID_Dipendente, (IF(SELECT SUM(Ore) < 160,'Incompleto','Completo') AS Gennaio FROM Timesheet WHERE LEFT(ID_Timesheet,2)='01' AND RIGHT(ID_Timesheet,4)='2009'), (IF(SELECT SUM(Ore) < 160,'Incompleto','Completo') AS Febbraio FROM Timesheet WHERE LEFT(ID_Timesheet,2)='02' AND RIGHT(ID_Timesheet,4)='2009'), (IF(SELECT SUM(Ore) < 160,'Incompleto','Completo') AS Marzo FROM Timesheet WHERE LEFT(ID_Timesheet,2)='03' AND RIGHT(ID_Timesheet,4)='2009') FROM Timesheet GROUP BY ID_Dipendente

e...

SELECT DISTINCT ID_Dipendente, IF((SELECT SUM(Ore) < 160,'Incompleto','Completo') FROM Timesheet WHERE LEFT(ID_Timesheet,2)='01' AND RIGHT(ID_Timesheet,4)='2009') AS Gennaio, IF((SELECT SUM(Ore) < 160,'Incompleto','Completo') FROM Timesheet WHERE LEFT(ID_Timesheet,2)='02' AND RIGHT(ID_Timesheet,4)='2009') AS Febbraio, IF((SELECT SUM(Ore) < 160,'Incompleto','Completo') FROM Timesheet WHERE LEFT(ID_Timesheet,2)='03' AND RIGHT(ID_Timesheet,4)='2009') AS Marzo FROM Timesheet GROUP BY ID_Dipendente

Mi restituiscono errori in prossimità del primo IF e dei '<'. Abbi pazienza ma ho pochissima esperienza con la programmazione, credo si sia notato.
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Sbagliavi nel posizionare l'if, quello che devi controllare è la somma delle ore quindi all'interno dell'IF devi inserire l'intera sub select che era quella che ti dava appunto la somma, da così:

(SELECT SUM(Ore) FROM timesheet WHERE LEFT(id_timesheet,2)='01' AND RIGHT(id_timesheet,4)='2009') AS Gennaio

a così:

IF((SELECT SUM(Ore) FROM timesheet WHERE LEFT(id_timesheet,2)='01' AND RIGHT(id_timesheet,4)='2009')<160,'Incompleto','Completo') AS Gennaio

io ho messo <160 per gli incompleti, vedi tu se mettere <=

Anonimo Profilo | Senior Member

Continua a darmi errori:

Sintassi non corretta in prossimità della parola chiave 'IF'.
Sintassi non corretta in prossimità di ','. (dopo la WHERE)

Poi ho notato che inserendo più dipendenti si va a sommare e stampare la somma per quel mese di tutti i dipendenti.. tipo:

pippo nel giorno 01/01/2009 ha lavorato 8 ore.. e anche mario ha lavorato 8 ore quel giorno.
Mi restituisce due record, pippo e mario, con le somme di Gennaio di 16 ore per ognuno.
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Prova questo:

SELECT DISTINCT ID_Dipendente AS id_dip,
IF((SELECT SUM(Ore) FROM timesheet WHERE id_dipendente=id_dip AND LEFT(id_timesheet,2)='01' AND RIGHT(id_timesheet,4)='2009')<160,'Incompleto','Completo') AS Gennaio,
IF((SELECT SUM(Ore) FROM timesheet WHERE id_dipendente=id_dip AND LEFT(id_timesheet,2)='02' AND RIGHT(id_timesheet,4)='2009')<160,'Incompleto','Completo') AS Febbraio,
IF((SELECT SUM(Ore) FROM timesheet WHERE id_dipendente=id_dip AND LEFT(id_timesheet,2)='03' AND RIGHT(id_timesheet,4)='2009')<160,'Incompleto','Completo') AS Marzo
FROM Timesheet
GROUP BY ID_Dipendente

Anonimo Profilo | Senior Member

Errori negli if.

E se tolgo i vari if mi dà problemi nell'id_dip delle subquery.

"Il nome di colonna 'id_dip' non è valido."
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

una domanda... che db usi, io l'ho testa con mysql e va tutto bene...

Anonimo Profilo | Senior Member

SqlServer. Ecco perché. :azz
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

Purtroppo al momento non ho la possibilità di testarlo ma puoi provare con questo:

SELECT DISTINCT ID_Dipendente AS id_dip,
gennaio = CASE WHEN (SELECT SUM(Ore) FROM timesheet WHERE id_dipendente=id_dip AND LEFT(id_timesheet,2)='01' AND RIGHT(id_timesheet,4)='2009')<=160 THEN 'INCOMPLETO'
ELSE 'COMPLETO'
FROM Timesheet
GROUP BY ID_Dipendente

Anonimo Profilo | Senior Member

Ok grazie. Di questo ho fatto una piccola modifica, cioè: non faccio la where con ID_Timesheet ma con Data_timesheet, prendendo solo la parte destra mm/aaaa. E' meglio.

SELECT DISTINCT ID_Dipendente AS id_dip, Gennaio = CASE WHEN (SELECT SUM(Ore) FROM Timesheet WHERE ID_Dipendente=id_dip AND RIGHT(Data_timesheet,7)='01/2009')<160 THEN 'INCOMPLETO' ELSE 'COMPLETO' FROM Timesheet GROUP BY ID_Dipendente

Mi dà un problema in prossimità della from, prima del group by.
--------------------------------------------------------------------------

Allan Felipe

samar Profilo | Senior Member

inserisci

END,

prima del from

Anonimo Profilo | Senior Member

Nome di colonna non valido: id_dip

WHERE ID_Dipendente = id_dip
--------------------------------------------------------------------------

Allan Felipe
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2025
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5