Double e time

lunedì 26 marzo 2012 - 00.07
Tag Elenco Tags  C#  |  .NET 3.0  |  Windows XP  |  Visual Studio 2008  |  MySQL 5.5

andreadp Profilo | Junior Member

Salve
Il problema è: ho un campo datetime quindi con data e ora. In un altro campo devo memorizzare la durata del tempo stabilito con granularità del quarto d'ora. cioè un'ora, un'ora e un quarto, un'ora e mezza, due ore e tre quarti..ecc..ecc
In un altro campo devo mettere data e ora finale derivante dalla somma dell'inizio più la durata.
Come mi consigliate di gestire il problema in termini di tipi in MySql?
grazie
Andrea

AntCiar Profilo | Expert

Ciao.

Il campo della data ovviamente di tipo Date.
Quello in cui metti l'intervallo lo puoi dichiarare come intero e dentro ci metti il tuo valore indicante i quarti d'ora (15, 30, 45, 60, 75....)

Poi per leggere i valori direttamente con MySql puoi utilizzare la funzione ADDTIME() oppure leggere i due valori da db ed utilizzare le funzioni presenti in VisualStudio degli oggetti datetime.

in MySql si fa così:

Select ADDTIME(DataField, CONCAT('0 0:', NumField, ':0')) as `Data` from tabella

DataField rappresenta il campo della tabella di tipo DateTime
NumField rappresenta il campo della tabella in cui scrivi gli intervalli
Cristian Barca

andreadp Profilo | Junior Member

ok..piccola precisazione. Nell'intervallo devo poter mettere non solo i quarti d'ora ma anche per esempio l'ora e un quarto oppure l'ora e tre quarti, quindi tipo: 1,15 oppure 1,45 quindi invece di int double?? Il risultato della somma va messo in un terzo campo..quindi abbiamo: inizio, durata e fine.
Andrea

AntCiar Profilo | Expert

ciao.
Non ti conviene gestire 'l'ora' come intendi tu.
Se devi andare sempre di 15 minuti in 15 minuti, ti conviene esprimere l'ora in step di 15.
Ad esempio 1 ora e mezza la esprimi come 75 (60 + 15). in pratica ti tieni sempre come unità di misura il minuto.
In questo modo non devi fare delle scelte in base ai valori che hai.
Cristian Barca

andreadp Profilo | Junior Member

mi sa che hai ragione..:-)
Quindi tramite l'addtime mi calcolo l'ora finale e la vado ad inserire nel campo fine
Andrea

AntCiar Profilo | Expert

Yes
Cristian Barca

andreadp Profilo | Junior Member

L'ultimo nodo: prelevo la data di inizio 23/05/2010 (per esempio) da un monthCalendar. Ora quando la utilizzo nella query SELECT * FROM tabella WHERE inizio=?? cosa devo mettere? se non sbaglio mysql mi concepisce la data nel formato (yyyy-mm-dd).
Andrea

AntCiar Profilo | Expert

allora:

se utilizzi una stringa per effettuare la select devi passare la data nel formato yyyy-mm-dd come hai detto tu.
Se non ti vuoi smazzare puoi usare le parametriche così non ti devi preoccupare tu di dover formattare i valori.

Per le parametriche si fa così:

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Cristian Barca

andreadp Profilo | Junior Member

ok poi per pescare le righe che ci sono nel data table faccio "tab.Rows[0].toString()" per prelevare la prima riga???

Andrea

AntCiar Profilo | Expert

No.
con tab.rows[0].tostrin() ti restituisce "System.Data.DataRow".

Per leggere il valore devi fare con tab.rows[0][x] dove x è l'indice a base zero della colonna di cui ti serve il valore, oppure per un codice più pulito, tab.rows[0]["nomecampo"] in questo modo passi direttamente il nome della colonna in modo che se un domani l'ordine delle colonne dovesse cambiare, il tuo codice funziona sempre.
Cristian Barca

andreadp Profilo | Junior Member

Perfetto.
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Usando però il precedente codice non mi viene prelevata correttamente la data. Inizio è un campi Datetime in una tabella MySql e dataCorrente è un DateTime di c#..:-( Dove stà l'errore???

praticamente non c'e nessuna riga alla posizione 0
Andrea

AntCiar Profilo | Expert

Ciao.

Il codice che hai postato è corretto. Dal quel poco però non riesco a capire il problema.
posta tutto il codice che hai usato per la select (parametrica) così posso controllare

le risposte possono essere:

1 - Il codice scritto per la query non è corretto (non penso sia questo)
2 - il parametro con cui stai filtrando non restituisce dati perchè nella tabella non vi sono dati per quel filtro.

Comunque in generale dopo che fai un Fill su un datatable, prima di accederci, controlla se contiene righe tramite
tab.Rows.Count > 0


Cristian Barca

andreadp Profilo | Junior Member

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Praticamente mi serve l'ora di inizio conoscendo la sua data
Andrea

AntCiar Profilo | Expert

>Praticamente mi serve l'ora di inizio conoscendo la sua data

questo cambia le cose.
Allora se ho capito bene nella tua tabella hai nel campo 'inizio' delle date con orario.
se eè così, allora quando crei la select devi dire a MySql che vuoi cercare tutti i record che hanno "solo la parte di data" = ad un certo valore.
Come l'hai fatto tu il filtro praticamente cerca all'interno di date con ora dei valori senza ora o con altri valori.
cambia la query mettendo: "WHERE DATE(inizio) = ?inizio;"

in questo modo fai il filtro sul campo 'inizio' indipendentemente dalla sua ora. poi se ti da risultati l'oggetto 'tabella' (perchè trovi righe) per accedere all'oggetto datetime puoi fare:

Datetime dt = Convert.ToDateTime(tabella[0]["inizio"]);

in questo modo in 'dt' hai l'oggetto datetime letto dal database.

ciao ciao







Cristian Barca

andreadp Profilo | Junior Member

In questo modo però mi da errore sulla query:
Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
?inizio in questo caso è un DateTime.

Dove sta l'errore??
Andrea

AntCiar Profilo | Expert

>In questo modo però mi da errore sulla query:
>da.SelectCommand.CommandText = "SELECT inizio FROM prenotazione
>WHERE (DATE)inizio= ?inizio;";
>?inizio in questo caso è un DateTime.
>
>Dove sta l'errore??
>Andrea


Hai sbagliato a ricopiare la query: le parentesi non vanno su DATE ma sul campo.
Di seguito la stringa corretta

da.SelectCommand.CommandText = "SELECT inizio FROM prenotazione WHERE DATE(inizio) = ?inizio;";
Cristian Barca

andreadp Profilo | Junior Member

Perfetto ora va alla grande grazie mille.
Mentre ci sono: tutti i valori "inizio" mi devono servire ad abilitare o meno dei bottoni. Praticamente questi bottoni hanno come text l'orario: se inizio è uguale a button.text allora disabilita il bottone. Per un valore di inizio riesco a farlo. Ma per tanti valori??



Andrea

AntCiar Profilo | Expert

spiegati meglio, non ho capito cosa devi fare.
Cristian Barca

andreadp Profilo | Junior Member

allora: con quella query mi tiro fuori per un determinato giorno l'ora di inizio e la durata d ogni operazione.
Questi valori mi servono per andare a pilotare una griglia d pulsanti. I pulsanti mi rappresentano le ore della giornata con granularità del quarto d'ora.
Le text dei pulsanti nn sono altro che gli orari.
i pulsanti che hanno come text un ora che corrisponde ad un inizio devono essere disabilitati cosi come quelli successivi dipendenti dalla durata.
Questo discorso sono riuscito a farlo per una sola ora d inizio..mentre per piu d una mi sono un po perso..:-(
Andrea

AntCiar Profilo | Expert

per quello che hai detto prima ok.

>Questo discorso sono riuscito a farlo per una sola ora d inizio..mentre
>per piu d una mi sono un po perso..:-(

qui mi sono perso io.

Cosa intendi per "più di una..."?
Devi scorrere l'insieme dei bottoni e fare le select, oppure devi generare automaticamente delle date a step di 15 minuti e fare le select ed attivare/disattivare i relativi bottoni?


Cristian Barca

andreadp Profilo | Junior Member

devo stampare i bottoni..e quelli che "corrisspondono" agli inizi e durata disabilitarli..(in quanto occupati)
Andrea

AntCiar Profilo | Expert

L'insieme dei bottoni con l'orario scritto nella text lo hai già creato?
Cristian Barca

andreadp Profilo | Junior Member

si però tutti abilitati.
Andrea

AntCiar Profilo | Expert

ok.

allora puoi fare in questo modo:

quando crei i bottoni, nel tag del bottone inserisci lla data con l'ora come oggetto datetime.
poi fatti un dizionario di tipo datetime,button e inseriscici dentro le date con l'ora e il relativo bottone.

Dictionary<DateTime, Button> defBT = new Dictionary<DateTime, Button>();

quando crei il bottone poi fai

defBT.add(dt, btn); dove dt è la data con l'ora associata al bottone e btn è l'oggetto bottone

poi fai la select passando come filtro invece della singola data un intervallo di date "WHERE DATE(inzio) >= ?start AND DATE(inizio) <= ?end"
dove passerai come parametro ?start il valore di data minima (quella sul primo bottone) e come ?end quello della data massima (ulimo bottone)


Dopo fatta la select ti scorri la tabella e per ogni riga controlli se la dataora è presente nel dizionario e disabiliti il bottone

if (defBT.ContainsKey(Convert.ToDateTime(tabella.Rows[n]["inizio"])))
{
defBT[Convert.ToDateTime(tabella.Rows[n]["inizio"])].Enabled = false;
}
Cristian Barca

andreadp Profilo | Junior Member

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

Questo è quello che avevo fatto io. Due metodi. Alle'evento dateselected del calendario..mi faccio la query e mi vado a richiamare in createButton.
Dove mi suggerisci di applicare le tue modifiche?

AntCiar Profilo | Expert

Ciao.
Scusa se non ti ho risposto subito ma ieri sera non mi sono connesso.

ti ho riscritto la CreateButton con le nuove modifiche. La funzione che ti riempe il datatable "tabella" rimane uguale a quella che hai fatto tu.
Devi solo richiamare la CreateButton2 passando il datetime del MonthCalendar e l'oggetto tabella appena riempito al di fuori del ciclo, come ti ho riportato in questo primo pezzo di codice:

if (da.SelectCommand.Connection.State == ConnectionState.Closed) { da.SelectCommand.Connection.Open(); } da.Fill(tabella); if (tabella.Rows.Count > 0) { this.CreateButton2(dataCorrente, tabella); } else MessageBox.Show("Nessun record");


di seguito la nuova CreateButton

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Cristian Barca

andreadp Profilo | Junior Member

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Eccolo qua il tuo codice.
Ho provato: i bottoni vengono generati correttamente...(e qui ho molto da imparare per esempio sul tag del button che non ho mai usato)
Non funziona però la disabilitazione degli stessi. Sono tutti abilitati. Ah dimenticavo una cosa. Nella tabella prenotazione in ogni record, oltre all'inizio, e alla fine ci stà anche il campo durata come avrai capito. La durata di ogni recordo, quindi di ogni inizio, mi serve per sapere quanti bottoni devo disabilitare a partire dal suo inizio (come ti dicevo a granularità di quarti..)
Comunque secondo te cosa c'è ancora che non va per il disability dei button?

Andrea

AntCiar Profilo | Expert

avevo capito male la struttura della tabella.
Mandami (se possibile) in un file excel i record che ti vengono restituiti dalla select all'interno dell'oggetto tabella così vedo e posso modificarti il codice di conseguenza.

Cristian Barca

andreadp Profilo | Junior Member

Eccolo. La durata è espressa in minuti.
Cosa avevi capito male?? Cosi almeno cerco di studiarmi il codice in base a ciò che avevi capito. E' abbastanza interessante.


Andrea

AntCiar Profilo | Expert

ho aggiornato la createButton. Ho dovuto creare e aggiungere anche una classe (la TimeInterval)


Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra
Cristian Barca

andreadp Profilo | Junior Member

Ok mitico.. Il grosso è fatto.
Unica cosa ancora da limare: Considerando inizio alle 08:00:00 con durata 120 minuti. Mi viene giustamente disabilitato il tasto delle 10:00:00.
Quasi quasi andrebbe bene cosi..La prenotazione dopo deve iniziare alle 10:15..che ne pensi?
Andrea

AntCiar Profilo | Expert

>Ok mitico.. Il grosso è fatto.
>Unica cosa ancora da limare: Considerando inizio alle 08:00:00
>con durata 120 minuti. Mi viene giustamente disabilitato il tasto
>delle 10:00:00.
>Quasi quasi andrebbe bene cosi..La prenotazione dopo deve iniziare
>alle 10:15..che ne pensi?


Effettivamente così perderesti 14 minuti. Questo perchè quando consideri due intervalli di 15 minuti consecutivi, 1 minuto è in comune a tutti e due.
Potrebbe essere comodo considerare il controllo escludento il parametro "=" all'interno della classe che verifica l'enabled; Prova a modificare all'interno del metodo timeIsintoCollection togliendo = sul confronto dopo &&. in questo modo considerando l'esempio che hai fatto tu, avresti un intervallo che va dalle 08.00 alle 10.00 e considerando il bottone con il tempo a "10.00" te lo metterebbe disabilitato
Cristian Barca

andreadp Profilo | Junior Member

Si ho afferrato e in effetti..lo stavo già vedendo. Non sono sicuro però se farlo...ora ci penso....forse è meglio lasciare il quarto d'ora vuoto..vediamo...
Piuttosto al click del button dinamico vorrei ricavare il suo text perchè mi servirebbe l'ora di inizio (assieme alla fine, alla durata e all'id utente) per fare l'update o l'insert nella tabella premendo poi un bottone nel form (la durata la prendo da un numericBox che mi viene visualizzato non appena pigio uno dei pulsanti
Andrea

AntCiar Profilo | Expert

per la gestione del click sui bottoni, basta che fai questo:

dopo la riga bt.Tag = ........

scrivi bt.Click+= e premi due volte il tasto TAB

ti verrà completato in automatico la riga e creato un metodo in automatico.
All'interno di questo metodo ci arrivi ogni volta che fai click su un bottone.
All'interno del metodo ci scrivi:

if (sender.GetType().Equals(typeof(Button)))
{
DateTime dt = ((Button)sender).Tag;
}

in questo modo in dt hai la data e l'ora associati al bottone.
Cristian Barca

andreadp Profilo | Junior Member

Grazie al vostro e in questo caso al tuo aiuto..ci sono riuscito. Grazie.
Mi manca adesso un ultimo passo:

praticamente sfruttando il metodo Timer_Elapsed riesco a fare quello che voglio io ogni tot tempo inserendo "quello che voglio fare" tra lo Stop e lo Start ok?
Ogni minuto devo controllare che nella tabella prenotazioni ci sia un campo inizio che corrisponde al dataTime.Now.Minute perché se è così devo cominciare una serie di operazioni:
- inserire l'orario di inizio nella tabella erogazioni (orario di inizio preso dalla tabella prenotazioni);
- sommare un determinato valore ritornato da un metodo (già fatto e creato)ad una variabile;
..
..
andare avanti così fin quando il dateTime.Now.Minute non corrisponde a quello finale relativo a quello iniziale che ha fatto partire l'operazione.
Se succede un evento "estraneo" che mi sarà dato dal cambio della variabile, allora si deve inserire subito la minute di fine nelle erogazioni ed uscire.

Ora teoricamente ho bene chiare le operazioni da fare...Praticamente avrei bisogno di qualche suggerimento per strutturare questa parte....:-(



Andrea

AntCiar Profilo | Expert

Allora se ho capito bene puoi fare in questo modo:

nella tua classe (presumo si tratti di una form) inserisci una variabile globale di tipo System.Timer e la inizializzi. Imposti il valore di interval ad 1 minuto (ossia 60000 perchè è in millisecondi) e ti gestisci l'evento Tick del timer.

All'Interno dell'evento Tick (che si scatena ogni minuto) come prima istruzione metti il nome del timer.Stop().
In questo modo fermi il timer.

Poi richiami una funzione che ti costruirai a cui passi due oggetti datetime riguardanti dataOra inizio e fine
Dopo questa chiamata fai ripartire il timer.


La funzione protrebbe essere strutturata in questo modo:

private void ElaborazioneOgniMinuto(datetime StartTime, datetime EndTime)
{
DataTable tab = new dataTable();
''Qui richiami una funzione che ti fa la select a database passando come parametro la StartTime

if (tab != null)
{
if (tab.Rows.Count >0)
{
//E' stato trovato il record appartenente alla DataInizio

//Richiami i metodi che hai gia fatto.
...
//Poi controlli se l'ora attuale è uguale a quella di fine

if (DateTime.Now >= EndTime)
{
//Scrivi il record di fine all'interno del database
}
}
}


}

Cristian Barca

andreadp Profilo | Junior Member

Ok sembra che comincia a funzionare.

Una cosa:
if (DateTime.Now >= EndTime)
fra le altre cose faccio un

this.erogazioneTableAdapter.Fill(gestione_impiantoDataSet.erogazione);

Dopo un po che l'istruzione è stata eseguita mi spunta un errore in debugger, questo:

Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints.

come mai?? Voglio dire mi compare senza che in quel momento l'istruzione viene eseguita!

InsettoScoppiettato Profilo | Junior Member

Andrea,
non conosco Sql, ma se potessi passare per un attimo in .NEt standard, la soluzione è allegata qui.
TI passo la soluzione completa con un piccolo form che ti fa vedere come faccio a fare la discretizzazione in 15 minuti alla volta (il form corregge anche il minutaggio nel caso in cui inserisci più di 60 mnuti, trasformandoli in ore).
A te il compito del casting verso SQL.

ciao

Alessandro Parma

andreadp Profilo | Junior Member

Bene grazie anche questo consiglio utilissimo.
Allora un'altra cosa: ogni minuto..come dicevo controllo se corrisponde al minuto di inizio di una prenotazione. Se è così, devo, fra le altre cose rendere visibile o meno una label sul form solo che facendolo nel modo classico mi viene detto che c'è un problema di protezione bla bla bla..dovrei usare i delegate?? Come mi consigliate di risolvere problemi simili?
Andrea

InsettoScoppiettato Profilo | Junior Member

il problema è che i controlli UI devono essere mossi dal Thread originale con cui il form è stato aperto.
Hai diverse soluzioni a riguardo, la migliore è la reflection, ti passo un esempio che puoi copiare ed incolare nel tuo codice.
Per esempio questa è una funzione che aggiorna una progress bar:

delegate void SetRefreshCallback(int n); private void BarUpdate(int sim) { if (this.progressBarSimulation.InvokeRequired) { SetRefreshCallback d = new SetRefreshCallback(BarUpdate); this.Invoke(d, new object[] { sim }); } else { progressBarSimulation.Value = (int)(sim * barScale); progressBarSimulation.Refresh(); } }
sta nel Form1.cs per esempio.
Da qui noti che se richiami la funzione dal Thread origine del form allora enstri nell'else, altrimenti se l'invoke Required restituisce true (entrando nell'if) significa che l'ID del thread corrente, è diverso dall'ID del thread nativo del controllo che vuoi manipolare.
Questo evita tutti gli errori cross-thread.

ciao

Alessandro Parma

andreadp Profilo | Junior Member

ok risolto pure questo.
Una considerazione: usando il tick del timer per fare questo controllo "perpetuo" non è "dispendioso"?! Cosa mi consigliate/suggerite?!

Grazie
Andrea

InsettoScoppiettato Profilo | Junior Member

Puoi gentilmente segnare il thread come completato?
Non so cosa stai usando come timer, ma ti consiglio di non usare quello di Windows.Form the ti rallenta l'interfaccia utente. Usa Windows.Timer.
TI sconsiglio invece di inserire quel blocco di codice dentro eventi standard che capitano spesso, tipo il refresh del form che rallentano molto l'applicazione e soprattutto vengono eseguiti sul thread nativo dell'interfaccia.
ciao

Alessandro Parma

andreadp Profilo | Junior Member

Si avrei dato la conclusione al post non appena avrei finito..non c'è problema..:-)
Ma volevi dire il System.Timers?? Invece che le System.Windows.Form.Timer ?
Andrea

InsettoScoppiettato Profilo | Junior Member

Si, perchè WIndows.Forms.Timer crea un oggetto che è legato al form e vive sullo stesso thread, accodandosi alla message pump della UI.
invece Windows.Timers crea un nuovo processo server-based.
Leggiti la msdn sull'argomento che è molto esplicativa, te ne allego qui il pezzo più interessante:

The Timer component is a server-based timer, which allows you to specify a recurring interval at which the Elapsed event is raised in your application. You can then handle this event to provide regular processing. For example, suppose you have a critical server that must be kept running 24 hours a day, 7 days a week. You could create a service that uses a Timer to periodically check the server and ensure that the system is up and running. If the system is not responding, the service could attempt to restart the server or notify an administrator.

The server-based Timer is designed for use with worker threads in a multithreaded environment. Server timers can move among threads to handle the raised Elapsed event, resulting in more accuracy than Windows timers in raising the event on time.

The Timer component raises the Elapsed event, based on the value of the Interval property. You can handle this event to perform the processing you need. For example, suppose that you have an online sales application that continuously posts sales orders to a database. The service that compiles the instructions for shipping operates on a batch of orders rather than processing each order individually. You could use a Timer to start the batch processing every 30 minutes.

Note
When AutoReset is set to false, the Timer raises the Elapsed event only once, after the first Interval has elapsed. To keep raising the Elapsed event on the Interval, set AutoReset to true.


IN pratica su devi settare a true AutoreSet, definire l'interval e poi associare un event handler all'evento Elapsed. POi lo lanci e te ne dimentichi. Istanzialo da main() e avvialo da dove vouoi, puoi anche metterlo public static in Program, che diventa ancora più accessibile.

ciao

Alessandro Parma

andreadp Profilo | Junior Member

quindi addirittura sul main..escluderlo completamente dal form in questione...wow....:-)

..mm se faccio così:
public static System.Timers.Timer aTimer = new System.Timers.Timer();
prima di
static void main....

nel form poi aTimer non mi viene visto.....
dove sbaglio?

InsettoScoppiettato Profilo | Junior Member

mettilo in program e istanzialo col new nel main. La classe program non ha costruttore, o melgio, il suo costruttore può essere il main.

Nota: system.TImers non eredita da Control, quindi non è inseribile nella COntrolCollection di un Form, in ogni caso non può appartenere strettamente a un form.
Alessandro Parma

andreadp Profilo | Junior Member

Ok intanziandolo nel main però nel form in questione non mi viene visto...glielo devo passare ovviamente (!?) o no..
Andrea

InsettoScoppiettato Profilo | Junior Member

come lo referenzi?
non puoi chiamarlo come un istanza di clase, per un motivo motlo semplice, Program è statica, quindi può solo avere membri statici, quindi non ha dati di classe istanziabili.
in main(), puoi referenziare il tuo
public static Timer aTimer
in un questo modo:
Program.aTimer = new Timer();

Se invece la tua domanda è del tipo: il mio form sta in una libreria separata e quindi non vedo program, allora il problema è diverso: in questco caso al form aggiungi una variabile dello stesso tipo, che invece di istanziare con il new, la linki a aTimer una volta che il programma sta girando con una funzione di callback.

Alessandro Parma

andreadp Profilo | Junior Member

ok perfetto..

Adesso mi trovo davanti ad una operazione: mi trovo in un form e pigiando un bottone devo agggioranare due data grid che stanno rispettivamente in altri due form diversi. Come mi consigliate di affrontare il problema.

Grazie
Andrea

andreadp Profilo | Junior Member

Riprendo questo post per il seguente motivo. Ho realizzato la griglia di bottoni come da voi suggerito. Bene PErfetto è stata ottima.
Per ottimizzare la cosa mi piacerebbe disabilitare i bottoni che in base all'orario in cui viene effettuata la prenotazione non servono più.
Come suggerite di fare??


grazie infinamente per il vostro apporto

Aspetto i vostri consigli
Andrea
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-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5