lundi 26 août 2013

Problème de table non disponible sur la fenêtre des requêtes

Un de mes collègues à été confronté à un problème quelque peu tordu lorsqu'il a voulu modifier une query dans AX. En effet, lorsqu'il a voulu ajouter une nouvelle table dans sa query en passant par le menu relation "1:n", il n'a pas trouvé sa table, alors que la relation était bien présente.

Il constata ce problème sur son serveur de production mais pas sur son serveur de développement alors que les tables étaient "à priori" strictement identique. Le fait que cela fonctionne sous le serveur de développement lui a permis de passer en debug la fenêtre de query d'AX. Il s'est alors aperçu que le menu "1:n" s'appuyait sur le contenu de la table "xRefTableRelation".

En creusant encore un peu plus (il lâche rien le bougre !), il est tombé sur une classe "xRefTableRelationUpdate" qui permettait justement de mettre à jour cette fameuse table. Il a donc exécuter cette classe et "Oh ! Miracle"... sa table est apparue sur son environnement de production...

Merci à Jonathan pour l'info...

vendredi 22 juin 2012

Lenteur des méthodes display

Il est courant de vouloir afficher des informations calculées dans une grid. Pour cela il est possible (entre autres) d'utiliser des méthodes "display".

Il est ainsi possible de définir une méthode "display" sur une table, avec la syntaxe suivante :
display str MyDisplayMethod()
{
     return "Ma méthode display";
Cette méthode peut alors être utilisée dans une grid dont le datasource est la table contenant notre méthode "display".

Rapidement se pose alors un problème de performance. En effet, les grid sous AX étant ce qu'elles sont, on ne peut pas dire que l'optimisation de l'affichage soit leur point fort. L'utilisation des méthodes "display" (pour peu qu'elles contiennent des accès à la base) devient vite problématique du fait de lenteur insoutenables de la grid.

Pour remédier à cela, il est possible de mettre en cache une méthode display. Sur votre form, placez vous sur le datasource mappé sur votre datatable. Il vous suffit d'overrider la méthode "init" du datasource, ainsi :


public void init()
{
    super();
    this.cacheAddMethod(tablemethodstr(MyDataTable,  MyDisplayMethod ));
}

Vous  noterez alors une très nette accélération de l'affichage de la grid.

vous trouvez ici un peu plus de détails sur la méthode de mise en cache.

mercredi 21 mars 2012

Crash d'un client AX

Ce matin au lancement de mon environnement de développement sous AX (et donc du client AX) j'ai eu la mauvaise surprise de tomber sur une erreur Windows qui provoque le crash de l’exécutable AX32.exe.

Bien entendu j'avais à ma disposition un minium d'information, juste un code exception 0xc0000005. J'avais sur mon poste deux autres lanceurs :

  • un pour l'environnement de pré-production
  • un pour l'environnement de production
Le premier plantait comme mon lanceur de dev alors que le second fonctionnement correctement. Le problème ne pouvait donc pas venir de l'installation de mon client AX. Mais pourquoi deux lanceurs différents plantaient-ils de la même façon ?


J'avais sur un autre poste, un lanceur de dev. En me connectant à ce poste sous mon nom, le lanceur fonctionnait correctement. Le problème ne venait donc pas de mon compte AX qui aurait pu être "vérolé".

J'ai ai donc conclu que le problème ne pouvait venir que d'un cache qui se trouverait en local sur mon poste et qui concernerait uniquement l'environnement de développement et de préprod. Pourquoi ces deux lanceurs ?

Il se trouve que ces deux environnements se trouvaient sur le même serveur....

Il m'était arrivé plusieurs fois de partir en quête d'un cache AX mais en abandonnant car ne trouvant pas l'information (par manque de temps aussi). Mais là je n'avais pas le choix.

Et bien le voilà ce fameux cache, vous le trouverez dans le répertoire AppData\Local de votre profil (donc dans "C:\Utilisateurs\<Votre profil>", le cache porte le nom de votre serveur + votre compte AX + extension .auc.

Ce qui explique mon problème de 2 lanceurs puisque mes deux environnements posant problème pointant sur un serveur identique où nous avons deux instances d'AX.

En supprimant le fichier .auc j'ai réglé mon problème.

vendredi 7 octobre 2011

Récupération du chemin du lanceur

Pour récupérer le chemin du fichier de configuration utilisé pour lancer AX, voici le code à utiliser :

box::info("AX Configuration file path: " + XInfo::configuration());

lundi 30 mai 2011

Afficher la requête générée par un objet Query

Dans le cas d'un objet "Query" créé dynamiquement, il peut être intéressant d'avoir une vue de la requête SQL (au format AX) générée. Pour cela il suffit d'utiliser la commande suivante :
info(QueryObject.DataSourceNo(1).toString();)

jeudi 3 mars 2011

CP1.3 - Modification de la form

Après avoir créer notre champ en base, il ne nous reste plus qu'à faire le nécessaire pour qu'il soit alimenté.

La mise à jour de ce champ passe par une saisie dans une form, dans notre cas il s'agit de la form "Relations commerciales" portant le nom "smmBusRelTable".

Notre nouveau champ ("SP_TestCombo") est désormais présent dans le datasource "smmBusRelTable". C'est ce champ qu'il va nous falloir placer sur notre form. Pour cela voici les actions à effectuer :
  • Déplier la branche correspondant à l'emplacement où vous souhaitez voir apparaitre votre champ, dans notre cas, voici l'arborescence que nous déplions :
  • Par un glisser/déplacer, vous déposez le champ "SP_TestCombo" issu du datasource "smmBusRelTable" dans le goup "Identification".
Il ne vous reste plus qu'à lancer l'écran "Relations commerciales", vous devriez obtenir le résultat suivant :


CP1.2 - Création du champ en base

Dans le billet précédent, nous avons vu dans quelle table nous devions créer notre champ et le nom que nous allions lui donner. Il nous reste à définir son type.

Pour rappel, ce champ se destine à accueillir une liste de valeur. Sous AX le type de champ à utiliser est "Enum". Les valeurs de cette énumération sont connues, il faut donc les définir :
  • 0 : Test 1
  • 1 : Test 2
  • 2 : Test 3
0, 1 et 2 étant les valeurs stockées en base de données et "Test 1", "Test 2" et "Test 3" les valeurs d'affichage.

Etape 1 - Création de l'énumération :

Voici les actions à réaliser :
  1. Se placer dans l'AOT (Control+D) sur la branche "Data Dictionary\Base Enums"
  2. Ouvrir le menu contextuel et sélectionner l'option "Nouveau Base Enum"
  3. Affecter à ce base enum le nom "SP_TestCombo"
  4. Ouvrir le menu contextuel correspondant à ce base enum et sélectionner l'option "Nouveau Element"
  5. Valoriser les propriétés "Name", "Label" et "EnumValue" avec les valeurs suivantes : "Test1", "Test 1",0
  6. Répéter ces deux dernières actions pour obtenir les valeurs "Test 2" et "Test 3"
Voici ce que vous devez obtenir :

Etape 2 - Création de l'extended data types :

Il s'agit ici de créer le type de données sur lequel notre champ va s'appuyer, voici les actions à réaliser :
  1. Dans l'AOT (Control+D) se placer sur la branche "Data Dictionary\Extended Data Types"
  2. Ouvrir le menu contextuel et sélectionner l'option "Nouveau\Enum"
  3. Affecter à ce type le nom "SP_TestComboType"
  4. Valoriser les propriétés "Label", "HelpText" et "EnumType" avec les valeurs suivantes : "Test", "Test d'une liste de valeur","SP_TestCombo"
 Voici ce que vous devez obtenir :

Etape 3 - Ajout du champ dans la table :

Le champ est désormais prêt à être ajouté à la table, voici les actions à réaliser :
  1. Dans l'AOT (Control+D) se placer sur la branche "Data Dictionary\Tables\smmBusRelTable\Fields" ("smmBusRelTable" étant le nom de la table des relations commerciales)
  2. Ouvrir le menu contextuel et sélectionner l'option "Nouveau\Enum"
  3. Affecter à ce champ le nom "SP_TestComboType"
  4. Valoriser la propriété "ExtendedDataType" avec la valeur "SP_TestComboType" correspondant au type précédemment créé.
 Voici ce que vous devez obtenir :

Une fois ces différentes étapes effectuées, notre table est à jour, il ne nous reste plus qu'à mettre à jour notre "form", c'est ce que nous allons voir dans le billet suivant "CP1.3 - Modification de la form".