Forse sono ancora legato ai vecchi metodi di programmazione, ma dovrei automatizzare dei processi e mi risultavano comodi gli array per i controlli, es
For x = 1 to xxx
txtCampi[x].Enabled = False
Next
Si può fare qualcosa di simile?
Grazie
Luca
Quando ne ho parlato io mi avete massacrato "usa le classi, sono meglio di qui, meglio di la ecc. ecc..." e adesso sei qui a consigliare di usarle?
Devi riportarmi il post, nel quale io ti ho massacrato per aver tu suggerito di usare le Strutture.
:o E' paradossale la tua affermazione ! Io faccio abbondante uso della risorsa Struttura, in particolar modo nelle chiamate a funzioni esterne a Gambas con Extern.
Al fine di sottolineare la mia particolarissima attenzione alle Strutture in genere, mi preme a questo punto ricordare i miei due mattoni micidiali sullo studio per l'adattamento delle Strutture esterne, scritte in C, con Gambas:
1) http://www.gambas-it.org/wiki/index.php?title=Gestire_con_sicurezza_le_Strutture_esterne
2) http://www.gambas-it.org/wiki/index.php?title=Gestire_con_un_Puntatore_le_Strutture_esterne
Per chiarire la mia attenzione per le Strutture, ti passo, allora, questa mia chicca esemplificativa, che fa riferimento alla pagina sub 1), di come poter adattare in un'applicazione Gambas con codice Gambas una Struttura esterna molto complessa, scritta in C (in questo caso l'esempio è stato effettuato su una semplice Struttura del file header /usr/include/aio.h ):
Library "/tmp/libadhoc"
' int Dim_aiocb()
' Ottiene la dimensione della Struttura "aiocb":
Private Extern Dim_aiocb() As Integer
' void Scrive_aio_fildes(struct *aiocb)
' Scrive un valore nel membro "aio_fildes"
Private Extern Scrive_aio_fildes(po As Pointer, v As Integer)
' int Legge_aio_fildes(struct *aiocb)
' Legge il valore contenuto dal membro "aio_fildes"
Private Extern Legge_aio_fildes(po As Pointer) As Integer
' void Scrive_lio_opcode(struct *aiocb)
' Scrive un valore nel membro "aio_lio_opcode"
Private Extern Scrive_aio_lio_opcode(po As Pointer, v As Integer)
' int Legge_lio_opcode(struct *aiocb)
' Legge il valore contenuto dal membro "aio_lio_opcode"
Private Extern Legge_aio_lio_opcode(po As Pointer) As Integer
Public Sub Main()
Dim i As Integer
Dim p As Pointer
CreaSo("/usr/include/aio.h", "struct aiocb", ["aio_fildes", "aio_lio_opcode"], "/tmp/libadhoc")
i = Dim_aiocb()
Print "La dimensione della Struttura è: ", i; " byte"
p = Alloc(i)
Scrive_aio_fildes(p, 99)
i = Legge_aio_fildes(p)
Print "Valore letto dal membro 'aio_fildes':", i
Scrive_aio_lio_opcode(p, 200)
i = Legge_aio_lio_opcode(p)
Print "Valore letto dal membro 'aio_fildes':", i
Free(p)
End
Private Procedure CreaSo(Percorso_del_file_header As String, Nome_della_Struttura As String, Nome_dei_Membri As String[], libreria_adhoc As String)
Dim s As String
Dim b As Byte
s = "#include <" & Percorso_del_file_header & ">\n\n" &
"int Dim_" & LTrim(Replace(Nome_della_Struttura, "struct", Null)) & "() {\n" &
" return sizeof(" & Nome_della_Struttura & ");\n}" &
"\n\n\n"
For b = 0 To Nome_dei_Membri.Max
s &= "void Scrive_" & Nome_dei_Membri[b] & "(" & Nome_della_Struttura & " *p, int valore) {\n" &
" p->" & Nome_dei_Membri[b] & " = valore;\n}"
"\n\n\n" &
"int Legge_" & Nome_dei_Membri[b] & "(" & Nome_della_Struttura & " *p) {\n" &
" return p->" & Nome_dei_Membri[b] & ";\n}"
Next
File.Save(libreria_adhoc & ".c", s)
Shell "gcc -o " &/ libreria_adhoc & ".so " &/ libreria_adhoc & ".c -shared" Wait
End
E', inoltre, arcinota la disquisizione fra me e Gianluigi proprio sulle Strutture (...laddove io vesto sempre i panni dello strenuo difensore proprio delle Strutture); così come è altrettanto noto in modo sommo che tuttte le pagine della nostra WIKI, afferenti direttamente od indirettamente alla risorsa Struttura, sono state scritte da me.
Tra l'altro, come Gianluigi sa bene, io sono molto restio ad usare i Variant, in favore invece proprio delle Strutture !
Pertanto, per me è stato naturale consigliare a luca.decarlo l'uso delle Strutture. :-\
Sono arrivato al momento di definire nel campo group dei controlli interessati al test il valore grp1
poi nello specifico eseguo:
For Each oControl In grp1
oControl.Enabled = True
Next
Chiaramente oControl è definito come Objects, ma ottengo errore su grp1 che non esiste.
Grazie Gianluigi,
sto studiando il materiale che mi hai indicato, mi perdo sempre per strada, ovvero tutti gli esempi sono su oggetti che vengono creati da codice, non riesco a trovare la connessione tra questi appena detti e quelli invece creati da ide.
Ho delle form piene di TextBox e le nel campo group ci metto in tutte lo stesso nome, ora da codice devo abilitarle o disabilitarle tutte.
Con vb6 avevo un indice di controlli e facevo un semplice for dallo 0 all'indice massimo e via!
Non sono sicuro di aver compreso quello che mi stai chiedendo, non confondere gli eventi con le proprietà se devi disabilitare alcune textbox di una maschera che siano già disegnate dall'ide o disegnate dal codice poco importa ad esempio:
Public Sub Button1_Click()
Dim c As Control
For Each c In FMain.Controls
If c.Name Like "TextBox[1,3,5]" Then
c.Enabled = False
Endif
Next
End
Come già ti ha precisato Gianluigi, il Gruppo (group) è afferente alla sola sollevazione degli Eventi: tutti gli oggetti che appartengono ad un Gruppo potranno sollevare quel determinato Evento, facente riferimento nel codice alla sua sub-routine (sottoprocedura).
Public Sub NomedelGruppo_Click()
Print Last.Name; " ha sollevato questo evento _Click() ! "
End
Ti segnalo questa pagina della nostra WIKI:
http://www.gambas-it.org/wiki/index.php?title=Gli_eventi
Riguardo, poi, al tuo problema di disattivare due o più oggetti di tipo TextBox, qualora sul Form vi siano solo TextBox, puoi anche più semplicemente fare così:
Public Sub Form_Open()
Dim tb As TextBox
' Per ciascun "TextBox" presente sul Form corrente...
For Each tb In Me.Children
' ...viene assegnato il valore False alla proprietà .Enabled:
tb.Enabled = False
Next
End
@vuott
come chiesto da luca.decarlo il codice che hai postato agisce su tutte le textbox e come hai sottolineato funziona solo se sulla form hai messo unicamente TextBox, per questa ragione credo sia il caso di approfittare della proprietà Tag; ad esempio si possono selezionare tutte le textbox interessate e impostare tag ad 1 in un colpo solo quindi:
Public Sub Button1_Click()
Dim c As Control
For Each c In FMain.Controls
If c.Tag = 1 Then c.Enabled = False
Next
End
:ciao:
..... funziona solo se sulla form hai messo unicamente TextBox, per questa ragione credo sia il caso di approfittare della proprietà Tag
L'uso della proprietà .Tag è una possibilità, sì.
Però si può anche evitare di scomodare questa proprietà, verificando invece il tipo di oggetto-Figlio presente sul Form.
Nell'esempio che segue sul Form abbiamo oltre ad alcune TextBox anche altri oggetti. Per individuare e, quindi, disabilitare soltanto le TextBox, possiamo adottare la seguente soluzione:
Public Sub Form_Open()
Dim ob As Object
' Per ogni oggetto-figlio presente sul Form corrente...
For Each ob In Me.Children
' ...verifichiamo il suo "tipo". SE l'oggetto è una "TextBox", allora - e solo in tal caso - la disabilitiamo:
If Object.Type(ob) = "TextBox" Then ob.Enabled = False
Next
End
E perché non così? (sempre nel ciclo):
If Left(c.Name, 7) = "TextBox" Then c.Enabled = False
:ciao:
E perché non così?
....sai meglio di me che spesso nella programmazione esistono molti modi per dare soluzione ad un problema....
Public Sub Form_Open()
Dim c As Control
' Per ogni Controllo posto nel Form...
For Each c In FMain.Controls
' ...se detto Controllo appartiene alla Classe "TextBox", allora lo disabilitiamo:
If Object.Is(c, "Textbox") Then c.Enabled = False
Next
End
;D
Basta mi arrendo .....
Adesso usando i Puntatori, penetro nella memoria di ciascun oggetto posto sul Form, individuando il nome della propria Classe.... così t'affondo la Corazzata: :rotfl:
Public Sub Form_Open()
Dim ob As Object
Dim p1, p2 As Pointer
For Each ob In Me.Children
p1 = Object.Address(ob)
p2 = Pointer@(p1)
if String@(Pointer@(p2 + 24)) = "TextBox" then ob.Enabled = False
Next
End
(http://www.trentoincina.it/images/barham.jpg)
Dopo le vostre spiegazioni ho una subbettina che funzione perfettamente, che, in base ad un valore bool che gli passo abilita o disabilita i controlli che mi interessano.
Ora provavo ad implementarla, visto che fa già un ciclo sui controlli del form, passando un'altro bool, facendogli azzerare il valore del controllo.
es:
Public Sub EnaDisa(bValue As Boolean, bAzzero As Boolean)
Dim c As Control
For Each c In FSoggetti.Controls
If c.Tag = 1 Then
c.Enabled = bValue
Print c.Name
If c.Name Like "TextBox[2,3,4,5]" And bAzzero = True Then
c.Text = ""
Else If c.Name Like "TextBox[6,7]" And bAzzero = True Then
c.Text = 0
Else If c.Name Like "ComboBox" And bAzzero = True Then
c.Index = -1
Endif
Endif
Next
End
nella line c.Text = "" ottendo un errore: "Unknow symbol 'Text' in class Control"
Luca
Fatto prova veloce così e sembra funzionare tutto!!
Dim o As Object
For Each o In Me.Children
If o.Tag = 1 Then
o.Enabled = bValue
If o.Name Like "TextBox[2,3,4,5]" And bAzzero = True Then
o.Text = ""
Else If o.Name Like "TextBox[6,7]" And bAzzero = True Then
o.Text = 0
Else If o.Name Like "ComboBox" And bAzzero = True Then
o.Index = -1
Endif
Endif
Next
... credo tu debba assegnare il tipo di controllo.
Se l'oggetto è un pulsante allora devi assegnare button e dovrebbe funzionare.
Nel caso tu voglia ricercare sempre tramite la proprietà nome e tu abbia anche la necessità di accedere a controlli annidati puoi usare il mio precedente suggerimento che credo funzioni:
Public Sub EnaDisa(bValue As Boolean, bAzzero As Boolean)
Dim c As Control, o As Object
For Each c In FSoggetti.Controls
' Dovrebbe andar bene anche qui'
' o = c
'
If c.Tag = 1 Then
c.Enabled = bValue
Print c.Name
If c.Name Like "TextBox[2,3,4,5]" And bAzzero = True Then
o = c
o.Text = ""
Else If c.Name Like "TextBox[6,7]" And bAzzero = True Then
o = c
o.Text = 0
Else If c.Name Like "ComboBox*" And bAzzero = True Then ' Se ti riferisci a tutte!'
o = c
o.Index = -1
Endif
Endif
Next
End
Ritorno all'utilizzo del "Like" ma utilizza solo 1 carattre "variabile"??
Ovvero:
Dim o As Object
For Each o In Me.Children
If o.Tag = 1 Then
o.Enabled = bValue
If o.Name Like "TextBox[2,3,4,5,6,7,8,9,10,11,12,13]" And bAzzero = True Then
o.Text = ""
'Else If o.Name Like "TextBox[6,7]" And bAzzero = True Then
' o.Text = 0
Else If o.Name Like "ComboBox*" And bAzzero = True Then
o.Index = -1
Endif
Endif
Next
Azzera solo fino alla textbox9 dalla 10 in poi nulla!
Guarda io di espressioni regolari ne so veramente poco, in giro per il web ci sono dei tutorial ...
Questo ad esempio funziona:
Public Sub Button1_Click()
Dim c As Control
Dim $OK As Boolean = True
For Each c In FMain.Controls
If c.Name Like "TextBox[2-9]" Or c.Name Like "TextBox[1][0-3]" And $OK = True Then
c.Enabled = False
Endif
Next
End
A proposito:
A te il mio codice sulle combo funziona? Oppure fa come a vuott?
NB: Ho spostato la domanda sulla ComboBox qui (http://www.gambas-it.org/smf/index.php?topic=4679.msg37751#msg37751)
Visto il suo esempio, se lui non ha più di 13 TextBox e vuole disabilitarli tutti tranne il primo, si può più agevolmente scrivere:
...Like "TextBox*[2-9]"...
e più precisamente:
If c.Name Like "TextBox*[2-9]" And bAzzero Then
......
Visto il suo esempio, se lui non ha più di 13 TextBox e vuole disabilitarli tutti tranne il primo, si può più agevolmente scrivere:
...Like "TextBox*[2-9]"...
...
A me non funziona, esclude 1, 10 e 11, come potrebbe agire se 0 e 1 vengono esclusi? Il carattere (*) significa un qualunque numero di qualsiasi carattere escluso 0 e 1 un po come questo codice:
c.Name Like "TextBox*[^0-1]"
Che brutta cosa la vecchiaia, c'ero già caduto ma non mi sono ricordato, basta che invece delle parentesi quadre uno usi le parentesi graffe e il codice postato da Luca funziona, esempio:
If c.Name Like "TextBox{2,3,4,5,6,7,8,9,10,11,12,13}" And $OK = True ... Then