OVH Cloud OVH Cloud

Accéder à un nom de label par concaténation

21 réponses
Avatar
jerome
Bonjour,

J'ai un problème de syntaxte VB que j'arrive pas à régler.

J'ai 3 labels dans un formulaire
label1, label2, label3

Je récupère des champs dans une base de données et je voudrais que ces
labels prennent la valeur de ces champs

J'essaie, rst étant un curseur

I=0
Do While rst.cur.EOF = False
I = I+1
ligne = "label" & CStr(I)
myForm.ligne.Caption = rst.cur!maValeur
rst.cur.MoveNext
Loop

Mais ça ne fonctionne pas.

Comment pourrais-je faire ?

Merci par avance

10 réponses

1 2 3
Avatar
Patrice Henrio
En fait le problème posé au départ est un problème souvent posé en
programmation. Cela rappelle le tableau de cézanne : ceci n'est pas une pipe
(ce n'est que la représentation d'une pipe).

Lorsque que l'on écrit
Ligne="Label1"
Cela représente seulement la chaîne de caractères décrivant le nom du label.
un peu comme "2006" n'est que l'écriture d'une entité numérique représentant
la valeur 2006.
On ne peut donc pas utiliser la valeur de Ligne ("label1") comme étant
l'objet Label1 lui-même (ils ne sont pas du même type).
De même que l'on ne peut additionner "2006" et 1 pour obtenir 2007.

A priori l'écriture

myForm.ligne.Caption="Test"

attend une propriété ligne définie avec l'objet form ou un contrôle nommé
ligne dans la forme.

Donc si j'ai un label de name "Ligne"

Dim Ligne as string
Ligne="Label1"
MyForm.ligne.Caption=Ligne

affichera le texte "Label1" dans le label Ligne et non dans le label Label1.


"jerome" a écrit dans le message de news:
%
Merci.

Effectivement avec les groupes de contrôle ça fonctionne.

Merci encore
.
"Clive Lumb" wrote in message
news:
jerome wrote:
> Bonjour,
>
> J'ai un problème de syntaxte VB que j'arrive pas à régler.
>
> J'ai 3 labels dans un formulaire
> label1, label2, label3
>
> Je récupère des champs dans une base de données et je voudrais que ces
> labels prennent la valeur de ces champs
>
> J'essaie, rst étant un curseur
>
> I=0
> Do While rst.cur.EOF = False
> I = I+1
> ligne = "label" & CStr(I)
> myForm.ligne.Caption = rst.cur!maValeur
> rst.cur.MoveNext
> Loop
>
> Mais ça ne fonctionne pas.
>
> Comment pourrais-je faire ?
>
> Merci par avance

Solution la plus simple
Créer un groupe de contrôles "MonLabel"
Ensuite on accède au texte de chaque membre par MonLabel(I).Caption

(Pour créer le groupe de façon simple, créer un label puis copier/coller


et
repondre "Oui" quand VB vous demande si vous voulez créer un groupe.


Repeter
à souhait)

Clive








Avatar
Clive Lumb
"Patrice Henrio" a écrit dans le message de
news:%
En fait le problème posé au départ est un problème souvent posé en
programmation. Cela rappelle le tableau de cézanne : ceci n'est pas une


pipe
(ce n'est que la représentation d'une pipe).

Lorsque que l'on écrit
Ligne="Label1"
Cela représente seulement la chaîne de caractères décrivant le nom du


label.
un peu comme "2006" n'est que l'écriture d'une entité numérique


représentant
la valeur 2006.
On ne peut donc pas utiliser la valeur de Ligne ("label1") comme étant
l'objet Label1 lui-même (ils ne sont pas du même type).
De même que l'on ne peut additionner "2006" et 1 pour obtenir 2007.

A priori l'écriture

myForm.ligne.Caption="Test"

attend une propriété ligne définie avec l'objet form ou un contrôle nommé
ligne dans la forme.

Donc si j'ai un label de name "Ligne"

Dim Ligne as string
Ligne="Label1"
MyForm.ligne.Caption=Ligne

affichera le texte "Label1" dans le label Ligne et non dans le label


Label1.



Bravo pour une explication très imagée, la première fois que je vois VB et
Cézanne dans un même phrase.

Je crois que peut aussi aider à la compréhension de pourquoi cela ne marche
pas et pensant à ce qui se passe lors de la compilation.
Un label est un contrôle, membre de la collection de contrôles de la
formulaire.
Il se trouve l'index "n" dans la liste de contrôles et lorsque l'appli est
compilé toute référence à ce label se fait par son index, pas par son nom.

Si on veut absolument y accéder par son nom en runtime - par exemple composé
par programmation ou lu dans une BdD - on peut toujours utiliser la methode
suivante

Public Sub ModifCaption(NomLabel As String, Texte As String)
Dim MonControl As Control
For Each MonControl In Me.Controls
If TypeOf MonControl Is Label Then
If MonControl.Name = NomLabel Then
MonControl.Caption = Texte
End If
End If
Next
End Sub

Clive
Avatar
Patrice Henrio
Je crois me souvenir de mes études d'il y a 15 ans (et plus) que cela
portait un nom le fait de pouvoir se référer à un objet à partir de la
chaîne représentant le nom, un peu comme d'appeler une fonction ou une sub à
partir de son nom (le mot décrivant ce nom). Mais je ne me rappelle plus
comment cela s'appelle.


"Clive Lumb" a écrit dans le message
de news: 452f3f27$0$31934$

"Patrice Henrio" a écrit dans le message de
news:%
En fait le problème posé au départ est un problème souvent posé en
programmation. Cela rappelle le tableau de cézanne : ceci n'est pas une


pipe
(ce n'est que la représentation d'une pipe).

Lorsque que l'on écrit
Ligne="Label1"
Cela représente seulement la chaîne de caractères décrivant le nom du


label.
un peu comme "2006" n'est que l'écriture d'une entité numérique


représentant
la valeur 2006.
On ne peut donc pas utiliser la valeur de Ligne ("label1") comme étant
l'objet Label1 lui-même (ils ne sont pas du même type).
De même que l'on ne peut additionner "2006" et 1 pour obtenir 2007.

A priori l'écriture

myForm.ligne.Caption="Test"

attend une propriété ligne définie avec l'objet form ou un contrôle nommé
ligne dans la forme.

Donc si j'ai un label de name "Ligne"

Dim Ligne as string
Ligne="Label1"
MyForm.ligne.Caption=Ligne

affichera le texte "Label1" dans le label Ligne et non dans le label


Label1.



Bravo pour une explication très imagée, la première fois que je vois VB et
Cézanne dans un même phrase.

Je crois que peut aussi aider à la compréhension de pourquoi cela ne
marche
pas et pensant à ce qui se passe lors de la compilation.
Un label est un contrôle, membre de la collection de contrôles de la
formulaire.
Il se trouve l'index "n" dans la liste de contrôles et lorsque l'appli est
compilé toute référence à ce label se fait par son index, pas par son nom.

Si on veut absolument y accéder par son nom en runtime - par exemple
composé
par programmation ou lu dans une BdD - on peut toujours utiliser la
methode
suivante

Public Sub ModifCaption(NomLabel As String, Texte As String)
Dim MonControl As Control
For Each MonControl In Me.Controls
If TypeOf MonControl Is Label Then
If MonControl.Name = NomLabel Then
MonControl.Caption = Texte
End If
End If
Next
End Sub

Clive




Avatar
Vincent Guichard
A noter qu'il est possible de créer une fonction réalisant cela:

'Dans toutes les forms ou la fonction doit être accessible
Public Function GetByName(n As String) As Control
Dim c As Control
For Each c In Me.Controls
If c.Name = n Then
Set GetByName = c
Exit Function
End If
Next c
End Function

'Utilisation:
Form1.GetByName("Text1").Caption = "Texte"

Vincent Guichard
Avatar
Clive Lumb
"Patrice Henrio" a écrit dans le message de
news:
Je crois me souvenir de mes études d'il y a 15 ans (et plus) que cela
portait un nom le fait de pouvoir se référer à un objet à partir de la
chaîne représentant le nom, un peu comme d'appeler une fonction ou une sub


à
partir de son nom (le mot décrivant ce nom). Mais je ne me rappelle plus
comment cela s'appelle.




Moi aussi, et moi non plus, si tu vois ce que je veux dire ...

La fonction s'appelé souvent "eval".
Et je crois que l'action est "Canonical Coercion" ??
Avatar
Patrice Henrio
Joli !

Bravo.

A plus
"Vincent Guichard" a écrit dans le message de
news: 452f5470$0$5094$
A noter qu'il est possible de créer une fonction réalisant cela:

'Dans toutes les forms ou la fonction doit être accessible
Public Function GetByName(n As String) As Control
Dim c As Control
For Each c In Me.Controls
If c.Name = n Then
Set GetByName = c
Exit Function
End If
Next c
End Function

'Utilisation:
Form1.GetByName("Text1").Caption = "Texte"

Vincent Guichard


Avatar
Vincent Guichard
Patrice Henrio a écrit :
Joli !

Bravo.

A plus


Bah, c'est à peu de chose prêt ce qu'a posté Clive dans sa réponse.
Elle serait d'ailleurs arrivée plus tôt sur mon serveur, je n'aurais pas
posté la mienne .

Vincent Guichard
Avatar
Clive Lumb
"Vincent Guichard" a écrit dans le message de
news:452f7f63$0$5069$
Patrice Henrio a écrit :
> Joli !
>
> Bravo.
>
> A plus
Bah, c'est à peu de chose prêt ce qu'a posté Clive dans sa réponse.
Elle serait d'ailleurs arrivée plus tôt sur mon serveur, je n'aurais pas
posté la mienne .



Et Clive avait pensé à faire la même chose, mais a préferé une solution
labello-centrique pour éviter la gestion des erreurs si on donne le nom d'un
autre type de contrôle.

Au fait, est-ce qu'un d'entre vous aurait pris le temps d'écrire un fonction
pour remplacer "TypeOf" pour permettre plus de facilité...?
Style:
sub MonTypeOf(Mycontrol)
if typeof MyControl is Label then MonTypeOf="Label" : exit sub
if etc.
end sub
Avatar
Vincent Guichard
Clive Lumb a écrit :
sub MonTypeOf(Mycontrol)
if typeof MyControl is Label then MonTypeOf="Label" : exit sub
if etc.
end sub


Je viens d'aller jeter un oeil à la doc (ce qu'il faudrais toujours
faire), et celle-ci indique:

Vous pouvez passer la collection Controls(index) à une fonction dont l'argument est spécifié en tant que classe Controls. Vous pouvez aussi accéder aux membres à partir de leur nom. Par exemple :

Controls("Command1").Top

Vous pouvez utiliser le mot-clé TypeOf avec l'instruction If, ou la fonction TypeName, pour déterminer le type d'un contrôle dans la collection Controls.





Donc en fait, plutôt que ma fonction, un simple
Form1.Controls("Text1").Caption = "Texte"
marche aussi bien (voire mieux) :)

Et TypeName est la fonction que tu cherches :)
Debug.Print TypeName(Form1.Controls("Text1")) 'Affiche TextBox

Vincent Guichard (si seulement j'avais le temps d'aprendre MSDN par
coeur ^^)
Avatar
Clive Lumb
Vincent Guichard wrote:
Clive Lumb a écrit :
sub MonTypeOf(Mycontrol)
if typeof MyControl is Label then MonTypeOf="Label" : exit sub
if etc.
end sub


Je viens d'aller jeter un oeil à la doc (ce qu'il faudrais toujours
faire), et celle-ci indique:

Vous pouvez passer la collection Controls(index) à une fonction dont
l'argument est spécifié en tant que classe Controls. Vous pouvez
aussi accéder aux membres à partir de leur nom. Par exemple :

Controls("Command1").Top

Vous pouvez utiliser le mot-clé TypeOf avec l'instruction If, ou la
fonction TypeName, pour déterminer le type d'un contrôle dans la
collection Controls.





Donc en fait, plutôt que ma fonction, un simple
Form1.Controls("Text1").Caption = "Texte"
marche aussi bien (voire mieux) :)



En plus c'est logique.
J'ai bien utilisé un syntaxe semblable pour accèder aux labels d'un
DataReport, pourquoi n'y avais-je pensé ?


Et TypeName est la fonction que tu cherches :)
Debug.Print TypeName(Form1.Controls("Text1")) 'Affiche TextBox



Tiens !
Je suis passé totalement à coté de celui-là, jamais connu, jamais utilisé.
Comme quoi on peut toujours apprendre.
Je me coucherai moins bête ce soir (mais avec quelques neurones en moins)

Merci
1 2 3