Vous êtes sur le site Web historique de la documentation de 4D. Les documentations sont progressivement déplacées vers developer.4d.com |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
4D v20 R7
Guide du typage
|
Case à cocher |
Case a cocher 3D |
Bouton |
Bouton inversé |
Bouton invisible |
Bouton 3D |
Bouton image |
Grille de boutons |
Bouton radio |
Bouton radio 3D |
Radio image |
Menu image |
Menu déroulant hiérarchique |
Liste hiérarchique |
Règle |
Cadran |
Thermomètre |
List box (type sélection) |
Note : Les variables de type Règle, Cadran et Thermomètre seront toujours typées comme des Numériques, même si vous avez choisi l’option Entier long par défaut pour le type des boutons dans les Préférences.
Pour ces variables, vous ne pouvez jamais vous trouver dans un conflit de types puisqu’elles ne peuvent avoir d’autres types que ce type-là, qu’on soit en interprété ou en compilé.
Les seuls conflits de types possibles sur l’une de ces variables viendraient du fait que le nom d’une variable serait le même que celui d’une autre variable placée à un autre endroit dans l’application. Dans ce cas, le remède consiste à renommer cette deuxième variable.
Une zone externe est toujours un Entier long. Il ne peut jamais y avoir de conflit de types.
Les seuls conflits de types possibles sur une variable Zone externe viendraient du fait que le nom de cette variable serait le même que celui d’une autre variable placée à un autre endroit dans l’application. Dans ce cas, le remède consiste à renommer cette deuxième variable.
Les zones 4D Write Pro et 4D View Pro sont toujours des variables de type objet. Il ne peut pas y avoir de conflit de type, hormis si le même nom de variable a été utilisé dans un autre endroit de l'application.
Ces variables sont les suivantes :
Variable non-saisissable, |
Variable saisissable, |
Liste déroulante, |
Menu/liste déroulante, |
Zone de défilement, |
Combo box, |
Pop-up Menu, |
Onglet, |
Zone Web |
Colonne de list box (type tableau). |
Ces variables se divisent en deux catégories :
• les variables simples (variables saisissables et variables non-saisissables),
• les variables d’affichage de tableaux (listes déroulantes, menus/listes déroulantes, zone de défilement, pop-up menu, combo box, onglets, colonnes de list box).
Chaque list box ajoute plusieurs variables dans les formulaires. Le type par défaut des variables dépend du type de list box :
List box type tableau | List box type sélection | List box type collection/entity selection | |
List box | Tableau booléen | Numérique (non utilisé) | Collection ou entity selection |
Colonne de list box | Tableau texte | Typage dynamique | Typage dynamique |
En-tête | Numérique | Numérique | Numérique |
Pied | Typage dynamique | Typage dynamique | Typage dynamique |
Tableau de contrôle des lignes | Tableau booléen (Tableau Entier long accepté) | - | - |
Styles | Tableau Entier long | Entier long | Entier long |
Couleurs de police | Tableau Entier long | Entier long | Entier long |
Couleurs de fond | Tableau Entier long | Entier long | Entier long |
Veillez à identifier et typer correctement ces variables et tableaux pour ne pas générer de conflit à la compilation.
Si vous utilisez des pointeurs dans vos applications, vous avez pu profiter de la puissance et de la flexibilité de cet outil dans 4D. Le compilateur en conserve intégralement les avantages.
Un pointeur peut pointer indifféremment sur une table, une variable ou un champ. Un même pointeur peut pointer sur des variables de type différent : veillez à ne pas générer des conflits artificiellement, en attribuant à une même variable des types différents.
Faites simplement attention à ne pas changer en cours de route le type de la variable sur laquelle pointe le pointeur en faisant, par exemple, une manipulation du type suivant :
LaVariable:=5,3
LePointeur:=->LaVariable
LePointeur->:=6,4
LePointeur->:=Faux
Dans ce cas de figure, votre pointeur dépointé est une variable Numérique. En affectant à cette variable une valeur booléenne, vous provoquez un conflit de types.
Si vous avez besoin dans une même méthode d’utiliser les pointeurs pour des propos différents, prenez soin de définir votre pointeur :
LaVariable:=5,3
LePointeur:=->LaVariable
LePointeur->:=6,4
LeBool:=Vrai
LePointeur:=->LeBool
LePointeur->:=Faux
Un pointeur n’a aucune existence propre. Il est toujours défini en fonction de l’objet qu’il représente. C’est pourquoi le compilateur ne peut pas détecter des conflits de types générés par une utilisation sans contrôle des pointeurs. Vous n’aurez donc pas, en cas de conflit, de message d’erreur durant la phase de typage ou celle de compilation.
Cela ne veut pas dire que lorsque vous utilisez des pointeurs, vous travaillez sans filet. Le compilateur vérifiera vos utilisations de pointeurs (sauf si la fonctionnalité de contrôle d'exécution est désactivée pour le code concerné).
Le compilateur a besoin, au moment de la compilation, des définitions des commandes des plug-ins utilisées dans la base à compiler, c’est-à-dire du nombre et du type des paramètres de ces commandes. Les risques d’erreur de typage sont inexistants à partir du moment où le compilateur trouve effectivement dans l’application ce que vous avez déclaré.
Assurez-vous que vos plug-ins sont installés dans le dossier PlugIns, à l'un des emplacements autorisés par 4D : à côté du fichier de structure de la base ou à côté de l’application exécutable (Windows) / dans le paquet (macOS). Pour plus d'informations, reportez-vous à la page Installer des plugins ou des composants.
Le compilateur ne duplique pas le fichier mais tient compte des déclarations des commandes sans rien vous demander en supplément.
Si vos plug-ins sont placés ailleurs, le compilateur vous demande de les localiser lors du typage, via une boîte de dialogue d’ouverture de documents.
Certains plug-ins, par exemple 4D Write, utilisent des commandes qui provoquent l’appel implicite à des commandes 4D.
Prenons un exemple avec 4D Write. Vous disposez d’une commande appelée . La syntaxe de cette commande est :
(LaZone;Evénement;MéthodeEvénement)
Le dernier paramètre que vous passez à cette routine est le nom d’une méthode, que vous aurez vous-même écrite dans 4D. Cette méthode sera appelée par 4D Write chaque fois que l’événement attendu sera reçu et cette méthode recevra automatiquement les paramètres suivants :
Paramètres | Type | Description |
$0 | Entier long | Retour de fonction |
$1 | Entier long | Zone 4D Write |
$2 | Entier long | Touche Maj. |
$3 | Entier long | Touche Alt (Windows), Option (Mac OS) |
$4 | Entier long | Touche Ctrl (Windows), Commande (Mac OS) |
$5 | Entier long | Type d’événement qui a provoqué l’appel |
$6 | Entier long | Valeur variant en fonction du paramètre Evénement |
Afin que le compilateur connaisse l’existence de ces paramètres et les prenne en compte, vous devez vous assurer qu’ils peuvent effectivement être typés, soit par une directive de compilation, soit parce que leur utilisation, suffisamment explicite, permet de déduire leur type.
4D permet de créer et de manipuler des composants. Un composant 4D est un ensemble d’objets 4D représentant une ou plusieurs fonctionnalité(s) groupée(s) dans un fichier de structure (appelé base matrice), qu’il est possible d’installer dans différentes bases (appelées bases hôtes).
Une base hôte exécutée en mode interprété peut utiliser indifféremment des composants interprétés ou compilés. Il est possible d’installer des composants interprétés et compilés dans la même base hôte. En revanche, une base hôte exécutée en mode compilé ne peut pas utiliser de composant interprété. Dans ce cas, seuls des composants compilés peuvent être employés.
Une base hôte interprétée contenant des composants interprétés peut être compilée si elle ne fait pas appel à des méthodes du composant interprété. Dans le cas contraire, une boîte de dialogue d’alerte apparaît lorsque vous tentez de compiler l'application et la compilation est impossible.
Un conflit de nom peut se produire lorsqu’une méthode projet partagée du composant a le même nom qu’une méthode projet de la base hôte. Dans ce cas, lorsque du code est exécuté dans le contexte de la base hôte, c’est la méthode de la base hôte qui est appelée. Ce principe permet de “masquer” une méthode du composant avec une méthode personnalisée (par exemple pour obtenir une fonctionnalité différente). Lorsque le code est exécuté dans le contexte du composant, c’est la méthode du composant qui est appelée. Un masquage est signalé par un warning lors de la compilation de la base hôte.
Si deux composants partagent des méthodes du même nom, une erreur est générée au moment de la compilation de la base hôte.
Pour plus d'informations sur les composants, reportez-vous au manuel Mode Développement.
Les manipulations des variables locales suivent toutes les règles déjà énoncées. De même que toutes les autres variables, elles ne peuvent être retypées en cours de méthode.
Dans ce paragraphe, nous abordons deux cas de figure où l’inattention pourrait conduire à des conflits de types :
Il n’est pas possible de retyper une variable. Il est, en revanche, tout à fait possible de faire pointer un pointeur successivement sur des variables de type différent.
Un exemple nous permet d’illustrer ce propos : écrivons une fonction qui nous renvoie l’occupation mémoire d’un tableau à une dimension suivant son type. Le résultat est un numérique dans tous les cas sauf deux : dans le cas des tableaux Texte et des tableaux Image, la taille mémoire occupée par le tableau dépend de valeurs inexprimables sous forme numérique (cf. section Tableaux et mémoire).
Dans le cas des tableaux Texte et des tableaux Image, nous renverrons comme résultat une chaîne de caractères. Cette fonction requiert un paramètre : un pointeur sur le tableau dont on veut connaître l’occupation mémoire.
Pour effectuer cette opération, vous avez le choix entre deux méthodes :
$Taille:=Taille tableau($1->)
$Type:=Type($1->)
Au cas ou
:($Type=Est un tableau numérique)
$0:=8+($Taille*10) ` $0 est un Numérique
:($Type=Est un tableau entier)
$0:=8+($Taille*2)
:($Type=Est un tableau entierlong)
$0:=8+($Taille*4)
:($Type=Est un tableau date)
$0:=8+($Taille*6)
:($Type=Est un tableau texte)
$0:=Chaine(8+($Taille*4))+("+Somme des longueurs des textes") ` $0 est un Texte
:($Type=Est un tableau image)
$0:=Chaine(8+($Taille*4))+("+Somme des tailles des images") ` $0 est un Texte
:($Type=Est un tableau pointeur)
$0:=8+($Taille*16)
:($Type=Est un tableau booléen)
$0:=8+($Taille/8)
Fin de cas
Dans la méthode ci-dessus, il y a changement de type de $0 suivant les valeurs de $1.
Fonction OccupMém en mode interprété et compilé (exemple pour Macintosh) $Taille:=Taille tableau($1->)
$Type:=Type($1->)
VarNum:=0
Au cas ou
:($Type=Est un tableau numérique)
VarNum:=8+($Taille*10) ` VarNum est un Numérique
:($Type=Est un tableau entier)
VarNum:=8+($Taille*2)
:($Type=Est un tableau entierlong)
VarNum:=8+($Taille*4)
:($Type=Est un tableau date)
VarNum:=8+($Taille*6)
:($Type=Est un tableau texte)
VarText:=Chaine(8+($Taille*4))+("+Somme des longueurs des textes")
:($Type=Est un tableau image)
VarText:=Chaine(8+($Taille*4))+("+Somme des tailles des images")
:($Type=Est un tableau pointeur)
VarNum:=8+($Taille*16)
:($Type=Est un tableau booléen)
VarNum:=8+($Taille/8)
Fin de cas
Si(VarNum#0)
$0:=->VarNum
Sinon
$0:=->VarText
Fin de si
Il faut noter la différence entre ces deux séquences :
Le compilateur gère la puissance et la souplesse de l’indirection sur les paramètres. En mode interprété, 4D vous donne toute latitude concernant le nombre et le type des paramètres. Vous gardez en mode compilé cette même liberté à condition de ne pas introduire de conflit de types et de ne pas utiliser, dans la méthode appelée, plus de paramètres que vous en avez passés, ce qui est facile.
Afin de contourner un éventuel conflit, les paramètres adressés par indirection doivent tous être du même type.
Pour une bonne gestion de cette indirection, il est important de respecter la convention suivante : si tous les paramètres ne sont pas adressés par indirection, ce qui est le cas le plus fréquent, il faut que les paramètres adressés par indirection soient passés en fin de liste.
A l’intérieur de la méthode, l’adressage par indirection se fait sous la forme : ${$i}, $i étant une variable numérique. ${$i} est appelé paramètre générique.
Illustrons notre propos par un exemple : écrivons une fonction qui prend des valeurs, fait leur somme et renvoie cette somme formatée suivant un format qui peut varier avec les valeurs.
A chaque appel à cette méthode, le nombre de valeurs à additionner peut varier. Il faudra donc passer comme paramètre à notre méthode les valeurs, en nombre variable, et le format, exprimé sous forme d’une chaîne de caractères.
Un appel à cette fonction se fera de la façon suivante :
Résultat:=LaSomme("##0,00";125,2;33,5;24)
La méthode appelante récupérera dans ce cas la chaîne : 182,70, somme des nombres passés, formatée suivant le format spécifié. D’après ce que l’on a vu plus haut, les paramètres de la fonction doivent être passés dans un ordre précis : le format d’abord et ensuite les valeurs, dont le nombre peut varier d’un appel à l’autre.
Examinons maintenant la fonction que nous appelons LaSomme :
$Somme:=0
Boucle($i;2;Nombre de paramètres)
$Somme:=$Somme+${$i}
Fin de boucle
$0:=Chaine($Somme;$1)
Cette fonction pourra être appelée de diverses manières :
Résultat:=LaSomme("##0,00";125,2;33,5;24)
Résultat:=LaSomme("000";1;18;4;23;17)
De même que pour les autres variables locales, la déclaration du paramètre générique par directive de compilation n’est pas obligatoire. Si elle est nécessaire (cas d’ambiguïté ou d’optimisation), elle se fait avec la syntaxe suivante :
C_ENTIER LONG(${4})
La commande ci-dessus signifie que tous les paramètres à partir du quatrième (inclus) seront adressés par indirection. Ils seront tous de type Entier long. Les types de $1, $2 et $3 pourront être quelconques. En revanche, si vous utilisez $2 par indirection, le type utilisé sera le type générique. Il sera donc de type Entier long, même si pour vous, par exemple, il était de type Réel.
Note : Le compilateur utilisant cette commande durant le typage, le nombre, dans la déclaration, doit toujours être une constante et jamais une variable.
Des variables et des constantes de 4D ont un type et une identité fixés par le compilateur. On ne peut donc créer une nouvelle variable, une méthode, une fonction ou une commande de plug-in portant le nom d’une de ces variables ou d’une de ces constantes. Bien entendu, vous pouvez tester leur valeur et les utiliser comme vous le faites en mode interprété.
Voici la liste complète des Variables système de 4D accompagnées de leur type.
Variable | Type |
OK | Entier long |
Document | Texte |
FldDelimit | Entier long |
RecDelimit | Entier long |
Error | Entier long |
Error method | Texte |
Error line | Entier long |
Error formula | Texte |
MouseDown | Entier long |
KeyCode | Entier long |
Modifiers | Entier long |
MouseX | Entier long |
MouseY | Entier long |
MouseProc | Entier long |
Lorsqu’on crée une colonne calculée dans un état, 4D crée automatiquement une variable C1 pour la première, C2, C3... pour les autres. Généralement, cette création est faite de façon transparente pour vous.
Dans le cas où vous utiliseriez ces variables dans des méthodes, souvenez-vous que, comme les autres variables, les variables C1, C2... ne peuvent être retypées.
La liste des constantes prédéfinies de 4D peut être consultée dans ce manuel via la Liste des thèmes de constantes, vous pouvez également les visualiser dans l’Explorateur, en mode Développement.
Conseils d’optimisation
Messages d'erreurs
Précisions de syntaxe
Utilisation des directives de compilation
Variables système
Produit : 4D
Thème : Compilateur
Nom intl. : Typing Guide
Modifié : 4D v15 R4
4D - Langage ( 4D v20 R7)