Newsgroup: it.comp.lang.visual-basic
Titolo: Classi e variabili Date

Salve a tutti,
forse mi sto intrecciando da solo, ma mi sto trovando davanti ad una
cosetta noiosa.
Ho una classe Persona
	Cognome As String
	Nome As String
	DataNascita As Date
	ecc.
Ora questa classe mi deve interagire con una form con delle textbox, quindi
carico dalla classe e salvo sulla classe.
txtTab(ctlDataNascita).Text= Format$(oPersona.DataNascita,"dd/mm/yyyy")
oPersona.DataNascita = txtTab(ctlDataNascita).Text
Mi interessa che nella primo caso, venga visualizzata una stringa vuota, e
non 31/12/1899 o quel che č.
Nel secondo caso, la txtTab puň essere vuota o una data validata, e volevo
passarla al volo.
Per adesso il primo caso l'ho risolto con una function nella classe:
--------------------------------------------------------------------
txtTab(ctlDataNascita).Text = oPersona.Data2Text(oPersona.DataNascita)
--------------------------------------------------------------------
Public Function Data2Text(CampoData As Date) As String
  Dim DataVuota As Date
  If CampoData = DataVuota Then
    Data2Text = ""
  Else
    Data2Text = Format$(CampoData, "dd/mm/yyyy")
  End If
End Function
--------------------------------------------------------------------
Nel secondo ho modificato Let/Get passando un variant:
--------------------------------------------------------------------
Public Property Let DataNascita(ByVal vData As Variant)
    Dim DataVuota As Date
    mvarDataNascita = DataVuota
    If Not IsNull(vData) Then
      If IsDate(vData) Then
        mvarDataNascita = vData
      End If
    End If
End Property
--------------------------------------------------------------------
Public Property Get DataNascita() As Variant
    DataNascita = mvarDataNascita
End Property
--------------------------------------------------------------------
Ma non sono soddisfatto della cosa, pensando che potrei avere classi con
una decina di campi Date...
Grazie

 carico dalla classe e salvo sulla classe.
[...]
Non hai tanto spazio di manovra temo; in mancanza di ereditarieta',
l'unica che mi viene in mente per evitare di spargere il codice in
giro per tutte le classi è questa:
lascia le property come prima, quindi con Get/Let di tipo Date, quindi
prendi la tua funzione Date2String, fanne una speculare String2Date
che prende in input una stringa e restituisce Date (simile alla Let
che avevi modificato) e mettile entrambe in una classe a parte (o
anche in un semplice Bas); ogni volta che devi interagire tra classe e
interfaccia grafica usi le funzioni come filtro:
txtTab(ctlDataNascita).Text=
DateUtils.Date2String(oPersona.DataNascita)
oPersona.DataNascita =
DateUtils.String2Date(txtTab(ctlDataNascita).Text)

 Nel secondo caso, la txtTab può essere vuota o una data validata, e

Io farei una nuova classe NullableDate, con proprietà Value As Variant, 
metodi ToString() As String e Parse(ByVal Text As String) il cui scopo 
dovrebbe essere intuitivo...
Poi nella classe Persona trasformerei ogni proprietà Date in NullableDate.
Ok, è molto .NET-ish, lo so...
Bye
Raf

 - Mostra testo citato
... e sarebbe la cosa migliore infatti; il grosso problema di simulare
questa cosa in VB6 è che non puoi avere la classe come Value Type ma
solo come Reference Type, a quel punto rischi di innescare un sacco di
problemi subdoli perche' ti aspetti che il valore venga copiato, come
con il tipo nativo Date, quando invece verrebbe referenziato.
Bisognerebbe rivedere tutto il codice per assicurarsi che lo stesso
valore non venga settato su piu' di una istanza, un lavoraccio...

 Ok, č molto .NET-ish, lo so...
Ho fatto come mi hai detto, solo che non mi č chiaro il metodo Parse.
Quando assegno ad una txt farņ
text1.text= oPersona.DataNascita.ToString 
Quando assegno alla classe mi serve la possibilitą di assegnare anche Null
(se da recordset), quindi usavo direttamente la .Value
oPersona.DataNascita.Value= Rs.Fields("DATANASCITA").Value
Per caso la Parse era SOLO per i campi string?
oPersona.DataNascita.Value= Text1.Text
Non sarebbe meglio mettere il codice nella Let Value? Almeno la sfrutto sia
per recordset (variant) che stringhe
Tnx
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
Option Explicit
Private mvarValue As Variant 'Copia locale.
Public Function Parse(ByVal Testo As String) As Integer
  If Len(Testo) > 0 Then
    mvarValue = CDate(Testo)
    Parse = 1
  Else
    mvarValue = Null
    Parse = 0
  End If
End Function
Public Function ToString() As String
  ToString = Format$(mvarValue, "dd/mm/yyyy")
End Function
Public Property Let Value(ByVal vData As Variant)
'Utilizzato per l'assegnazione di un valore alla proprietą, a sinistra di
un'assegnazione.
'Syntax: X.Value = 5
    mvarValue = vData
End Property
Public Property Set Value(ByVal vData As Variant)
'Utilizzato per l'assegnazione di un oggetto a una proprietą, a sinistra di
un'istruzione Set.
'Syntax: Set x.Value = Form1
    Set mvarValue = vData
End Property
Public Property Get Value() As Variant
'Utilizzato per recuperare il valore di una proprietą, a destra
dell'assegnazione.
'Syntax: Debug.Print X.Value
    If IsObject(mvarValue) Then
        Set Value = mvarValue
    Else
        Value = mvarValue
    End If
End Property
*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

 valore non venga settato su piu' di una istanza, un lavoraccio...
Emh questo mi ferma un pochino :)
Per ora allora mi sa che lascio la classe da un parte, in attesa di tempo
per studiarci sopra :)
Tnx

 End Property
Io poi aggiungerei un'ulteriore property, potrebbe sempre essere utile:
Public Property Get IsNull() As Boolean
    IsNull = Not IsDate(mvarValue)
End Property
Ciao
Raf 



In generale forse avresti ragione, ma io mi sono sempre salvato da questi 
problemi con alcune accortezze, come:
- definire per le property di tipo NullableDate solo l'accessor Get
- impostare Value come proprietà default della classe NullableDate
<Classe Persona>
    Private mDataNascita As New NullableDate
    Public Property Get DataNascita As NullableDate
        Set DataNascita = mDataNascita
    End Property
...
Così da avere:
oPersona1.DataNascita = #1/1/1950#
...
oPersona2.DataNascita = oPersona1.DataNascita
senza possibilità di confusione, non avendo definito property Set.
Bye
Raf