Il mio consiglio è questo:
posta una richiesta alla volta creando appositi topic. In questo modo faciliterai il lavoro di noi che ti aiutiamo, eviti che più persone rispondano a cose diverse accavallando i messaggi in maniera contorta e disordinata e dai un titolo alle richieste per aiutare chi cercherà eventuali soluzioni a a problemi simili al tuo...
Ora continuiamo qui ma la prossima volta segui questa linea guida....
Il codice devi allegarlo al post e chiedere ad un moderatore che te lo carichi in area download...scrivi nel messaggio una breve descrizione del codice così appena pronto te lo alleghiamo...
1) crei un modulo e ci scrivi debntro la funzione dichiarandola publica. Se ad esempio il modulo si chiama MFiscale e la funzione CreaCodice allora la potrai richiamare con
Il mio consiglio e di fare in modo che la funzione accetti i vari parametri (Nome, cognome, data, etc...) e restituisca una stringa (il codice fiscale in pratica) così, se ad esempio vuoi far appparire lo stesso in una textbox dai:
textbox1.text = MFiscale.CreaCodice("Pippo", "Dei pippis", "10/02/85", ...)
2) Questo argomento è stato ampiamente trattato cerca bene tipo: "Come passare variabili tra form"
3) Delle lettere accentate si è già discusso. Cerca il topic...se non lo trovi ne discutiamo meglio in seguito
4) Questo è del tutto normale. Se tu crei un label e dall'ide gli togli il testo interno (solitamente del tipo labelX) allora esso sarà vuoto e dovrai impostarlo tu. Non ci vedo nulla di strano. Anche gli altri oggetti si comportano così.
5) Ti consiglio di guardare la funzione Format o, come feci io tempo fa, ti scrivi una funzione che ti "sistema l'ordine" come vuoi tu
6) Quello che vuoi fare tu è sia semplice che difficile. Semplice poichè puoi usare oggetti come VBox, HBox, panel e le proprietà Expand degli oggetti per fare in modo che tutto venga ridimensionato con il form, difficile perchè per molti oggetti devi lavorare un pochetto....
Ti rispondo in ordine.
Il problema risoluzione come lo intendi tu è facilmente risolvibile impostando la lunghezza della parte fissa come porzione proporzionale alle dimensioni del desktop. Ad esempio potresti fare in modo che la parte fissa sia sempre un terzo (1/3) delle dimensioni dello schermo così i restanti due terzi (2/3) li dedichi alle altre due porzioni....
Per il codice fiscale una classe è sicuramente sprecata poichè per la creazione del codice fiscale si richiede la chiamata di una funzione che la crei una sola volta. Questo può esser fatto con i moduli. Puoi creare una funzione che accetta i diversi parametri e restituisce la scringa codice fiscale. Ad esempio in un modulo di nome MCodice, inserisci questo codice:
PUBLIC FUNCTION CreaCodiceFiscale(Nome AS String, Cognome AS String, etc....) AS String
DIM $codice AS String
...qui calcoli il tuo codice fiscale e lo inserisci in $codice
RETURN $codice
END
Potrai così creare i tuoi codici fiscali semplicemente dando
$StringaQualsiasi = MCodice.CreCodiceFiscale("Gino", "Geppetto", .......)
Capito?
Il primo metodo che mi viene in mentre è creare un array di nome Persona[] di tipo stringa dove ogni indice equivale a qualcosa tipo nome, cognome, data di nascita, etc....
Poi con un ciclo for ti passi tutti gli indici e controlli che non siano vuoti
DIM Persona AS String[3]
DIM i AS Integer
Persona[0] = "Pippo"
Persona[1] = "Pluto"
Persona[2] = "30/12/30"
FOR i = 0 TO Persona.Count - 1
IF Persona[i] = "" THEN RETURN
NEXT
Edit per Golia
mi sono dimenticato di dirti che il codice che ho postato ridimensiona tutti i controlli del form tranne quelli presenti in altri controlli.
Per esempio hai un Panel, il codice ridimensiona il Panel ma non i controlli al suo interno.
Per ridimensionare tutti i controlli anche quelli nidificati cambia le due righe:
FOR EACH hControl IN ME.Children
con
FOR EACH hControl IN ME.Controls
Ceskho,
quello dell'array è un'ottima soluzione, ma sempre su variabile (locale/globale)
Io pensavo esistesse qualcosa di simile ad un metodo .item() della classe che ho creata, che mi restituisca ogni metodo o proprietà della mia classe CPersona, ed il relativo valore...
Se io alla mia classe CPersona ho assegnato:
- CPersona.cognome,
- CPersona.nome,
- CPersona.datanascita, ecc...
non esiste un'istruzione che mi restituisca ogni metodo della classe, tipo: CPersona.items() --> "cognome", "nome", "datanascita"...
:-\
Scusa se insisto, ma vorrei trovare una soluzione sfruttando le classi. :)
Se ho capito bene l'unico metodo è quello delle variabili globali....oppure crei delle variabili private e poi te le fai restituire da una funzione tipo:
PRIVATE $Cognome AS String
PUBLIC FUNCTION GetCognome() AS String
RETURN Cognome
END
ed ottieni il cognome, ad esempio, con:
PRINT Modulo.GetCognome()
Oppure in alternativa:
PRIVATE nome, cognome, datanascita AS String
PUBLIC FUNCTION GetData(Data AS String) AS String
IF data = "Nome" THEN
RETURN Nome
ELSE IF data = "Cognome" THEN
RETURN Cognome
ELSE IF data = "Data" THEN
RETURN datanascita
END IF
END
e poi richiamai, ad esempio il cognome con
PRINT Modulo.GetData("Cognome")
Ovviamente puoi usare SELECT CASE ma era giusto per rendere l'idea....
Non ho letto tutto il post :-[ ma se ho capito tu vorresti fare una classe CPersona con le proprietà Cognome, Nome, DataNascita ?
Bhe allora il modo corretto di creare delle proprietà e' questo:
' Gambas class file
Property Cognome As String
Private $Cognome As String
Property Nome As String
Private $Nome As String
Property DataNascita As Date
Private $DataNascita As Date
Private Function Cognome_Read() As String
Return $Cognome
End
Private Sub Cognome_Write(Value As String)
$Cognome = Value
End
Private Function Nome_Read() As String
Return $Nome
End
Private Sub Nome_Write(Value As String)
$Nome = Value
End
Private Function DataNascita_Read() As Date
Return $DataNascita
End
Private Sub DataNascita_Write(Value As Date)
$DataNascita = Value
End
Cosi' facendo quando dai: Persona.Cognome = "Rossi"
non fai altro che invocare la sub Cognome_Write
mentre con variabile = Persona.Cognome invochi Cognome_Read
Cosi' facendo puoi anche intercettare il momento in cui vai a settare o richiamare una determinata proprietà della classe Persona....
Bhe sicuramente il codice fiscale puoi inserirlo come una proprietà della classe CPersona:
Property Read CodiceFiscale as String
Private Function CodiceFiscale_Read() As String
...
' Codice di calcolo codice fiscale
' se uno o piu' elementi che compongono il codice fiscale non sono dichiarati dai un bel Return ""
' altrimenti ritorni il codice fiscale calcolato
End
La proprietà rimane in sola lettura e soltanto quando le varie proprietà da te scelte sono settate, restituisce il codice... Naturalmente il 'vedere' se ogni proprietà e' settata e' una procedura che metterai all'interno della classe stessa, in modo da essere sempre disponibile in qualsiasi punto del tuo programma che richiama il codice fiscale della classe...
Se vuoi mi scarico il tuo programmino che hai postato la volta scorsa e ti faccio una bozza di classe, cosi' almeno ci capiamo meglio ;)
@ dex
ci do un'occhiata e ti dico (naturalmente in un altro post, appena l'avrai aperto ;) )
Millo, non ho parole!
Riscrivendomi il codice mi hai dato tanti spunti che ignoravo.
Le cose che mi sembra di aver capito sono che:
1) Le proprietà della classe che vengono create hanno dei metodi _read() e _write() che vengono invocati quando si legge o si scrive una di queste proprietà della classe. Quindi sono ottimi quando si vuol fare un controllo oppure quando si vuol tentare il calcolo di una funzione, ecc.
La proprietà CodiceFiscale è l'unica di sola lettura... perché giustamente deve essere calcolata (e non inserita a mano).
2) La funzione CalcoloCodiceFiscale() restituisce un booleano... quindi se tutti i termini sono stati specificati, calcola il $CodiceFiscale e restituisce un TRUE, altrimenti se ci sono errori restituisce FALSE ed invoca la funzione NoCodice() --> questa attribuisce "" a $CodiceFiscale e... (qui ho un grosso dubbio) con RAISE (http://gambasdoc.org/help/lang/raise?it) richiama CalculateCode della FMain?
3) La funzione CalculateCode della FMain attribuisce $CodiceFiscale (ossia Persona.CodiceFiscale) alla txtCodiceFiscale... e se Persona.CodiceFiscale è vera (ossia diversa da "" ???) allora inserisce i .Caption alle Label della tessera sanitaria.
4) Ogni volta che viene editata una proprietà in scrittura (cognome, nome, datanascita, ecc.), se il CalcoloCodiceFiscale() è TRUE, allora invoca CalculateCode della FMain... e si torna al punto 3).
5) Chiaramente quando viene chiesto se CalcoloCodiceFiscale è TRUE o FALSE implicitmente viene fatto eseguire... quindi assegnerebbe $CodiceFiscale se fosse TRUE...
Questo è quello che sono riuscito a capire, e spero sia corretto. :-[
Ho anche una grossa lacuna quando nella FMain dichiari:
...che vuol dire che l'istanzi con...
Persona = NEW CPers As "Persona"
???
PS: vedi la parte di codice quando comincia la funzione CalcoloCodiceFiscale()...
If $Cognome = "" Then Return NoCodice()
If $Nome = "" Then Return NoCodice()
If IsNull($DataNascita) Then Return NoCodice()
If $CodiceIstat = "" Then Return NoCodice()
If $Sesso = "" Then Return NoCodice()
Io mi chiedevo se esiste una funzione che esegua il controllo tipo:
FOR EACH proprietà IN CPers
IF proprietà = "" then Return NoCodice()
NEXT
Se i campi da controllare fossero tanti sarebbe un buona alternativa a tutti gli IF...
1) :ok:
2) il comando Raise scatena l'evento dichiarato con l'istruzione Event, all'interno della classe contenitore (in questo caso in FMain)
3) :ok:
4) No, in questo caso l'Evento CalculateCode viene comunque scatenate anche se il CodiceFiscale non puo' essere calcolato. In pratica l'evento mi serve solamente per tener aggiornato la textbox che contiene il codice. Se il calcolo del codice genera errore, la textbox assumerà un valore nullo. Questo e' un punto che volendo si puo' anche riscrivere, facendo in modo che l'evento si scateni una sola volta se il calcolo del codice e' errato; allo stato attuale l'evento viene scatenato ogni qualvolta ci sia un aggiornamento nelle proprietà della classe
5) vedi punto 4 :)
Ho anche una grossa lacuna quando nella FMain dichiari:
Codice:
Private Persona As CPers
...che vuol dire che l'istanzi con...
Codice:
Persona = NEW CPers As "Persona"
Quando scrivo:
Private Persona As CPers
dichiaro che la variabile Persona e' di tipo CPers, ma l'oggetto vero e proprio ancora non esiste in memoria.
Persona = NEW CPers As "Persona"
qui invece istanzio l'oggetto in memoria, quindi creo 'fisicamente' l'oggetto Persona e gli assegno una 'etichetta' dopo l'istruzione As che identifica nella classe contenitore i vari eventi dell'oggetto creato.
Diciamo che Persona puo' essere tante Persone, ma alla fine le caratteristiche sono sempre quelle della classe CPers
Quindi io posso anche avere:
Persona1 = NEW CPers As "Persona1"
Persona2 = NEW CPers As "Persona2"
Persona3 = NEW CPers As "Persona3"
Persona4 = NEW CPers As "Persona4"
ogni persona a nome, cognome .... e codice fiscale diversi, ma proprietà, metodi ed eventi uguali...
PS: vedi la parte di codice quando comincia la funzione CalcoloCodiceFiscale()...
Codice:
If $Cognome = "" Then Return NoCodice()
If $Nome = "" Then Return NoCodice()
If IsNull($DataNascita) Then Return NoCodice()
If $CodiceIstat = "" Then Return NoCodice()
If $Sesso = "" Then Return NoCodice()
Io mi chiedevo se esiste una funzione che esegua il controllo tipo:
FOR EACH proprietà IN CPers
IF proprietà = "" then Return NoCodice()
NEXT
Se i campi da controllare fossero tanti sarebbe un buona alternativa a tutti gli IF...
Sinceramente non mi sono mai posto il problema, anche perche' il codice di controllo lo scrivi solamente una volta...
Con l'oggetto Class, dandogli come riferimento la classe CPers, puoi richiedere quali siano le sue proprietà, metodi ed eventi e con Object.GetProperty fai il controllo in questione es.:
Dim x As Class
Dim Txt As String
x = Object.Class(Me)
For Each txt In x.Symbols
If x[txt].Kind = x.Property Then
If IsString(x[txt].Value) Then Print Object.GetProperty(Me, txt)
End If
Next
Il codice e' sotto inteso che sia scritto nella classe CPers.
Ps.
Per spiegare certe cose non sono tanto bravo, non ho studiato informatica e uso un linguaggio terra terra, diciamo che certe cose le ho capite e altre le intuisco... per tutto il resto c'e' mastercard... :)
ti rimando anche a questo link per una spiegazione piu' esauriente ;) http://it.wikipedia.org/wiki/Oggetto_(informatica)
milio sei il re delle classi
Ora capisco perché! :ok: :ok:
Ho sostituito il controllo della "sequenza degli IF" con questo codice (mettendo i commenti delle cose che penso di aver capito :-[ ):
Dim x As Class 'x è un oggetto classe
Dim txt As String 'txt è una stringa
x = Object.Class(Me) 'Object.Class(Me) che cos'è?
For Each txt In x.Symbols 'x.Symbols che cos'è?
If x[txt].Kind = x.Property Then 'x[txt].Kind restituisce in formato numerico il tipo: "2" è una proprietà, "4" è una funzione, "3" è riferita a _new, ecc...; mentre x.Property restituisce il tipo in formato numerico delle proprietà dell'oggetto x (sempre 2)... PS: potrei sostituire direttamente x.Property con "2", visto che a me interessano le proprietà, in scrittura?
If x[txt].name <> "CodiceFiscale" Then 'x[txt].name credo restituisca il nome della proprietà della classe
If IsNull(Object.GetProperty(Me, txt)) Then Return NoCodice() 'Object.GetProperty(Me, txt) restituisce il valore della proprietà...
End If
End If
Next
Non ho ancora capito bene il funzionamento, però è proprio ciò che cercavo!!! Fantastico Milio! :)
Ora dovrò studiarmelo bene, approfondendo i vari argomenti.