Configuration

Windows® XP SP3, VISTA, 7

.NET Framework 2.0, 3.0, 3.5

.NET Framework 4.0

 

Office 2003, 2007, 2010

Sérialisation & Consommation de services

Découvrez comment sérialiser des types complexes, appeler des macros depuis l’environnement VBA et exécuter des tâches asynchrones.


 

 Principe de la sérialisation

La sérialisation/déserialisation est un concept important lorsque vous souhaiterez intéragir entre du code VBA et vos macros mais aussi lorsque vous créerez des fonctions Excel.

La déserialisation consiste à recréer les paramètres attendus par la macro à partir des types primitifs fournis par l'hôte. La sérialisation représente l'étape inverse lorsqu'il s'agit de transformer l'un de vos types vers un type compréhensible par l'hôte.

Ce mécanisme géré nativement par le Framework Rio est entièrement customisable par le développeur. Il permet de découpler la construction des paramètres de l’appel de fonction. Ceci permet d’avoir une meilleure écriture de ses fonctions ainsi qu' une meilleure lisibilité de son code. Il permet de plus de créer des fonctions prenant en paramètres des types abstraits inconnus de leur hôte.

Prenons le cas d'une fonction Excel dont le but est d'interpoler un point à partir d'une courbe. La courbe peut revêtir plusieurs formes. Cela peut être un ensemble de date/valeur, un code identifiant la courbe en base de données ou bien des paramètres issus d’un modèle plus complexe. D’une façon générale régler ce type de problème conduit à créer plusieurs fonctions suivant les paramètres attendus. Le principe de sérialisation permet de ramener ce nombre dans la plupart des cas à une seule fonction.

Dans l’exemple précèdent on peut modéliser la courbe via l'interface suivante:

    [SerializedBy(typeof(CurveSerializer))]    
    public interface ICurve
    {
        double GetValue(DateTime t);
    }

A une date donnée, on récupère le point interpolé sur la courbe. L'attribut SerializedBy indique que la construction du type ICurve sera pris en charge par un object de type CurveSerializer.

Ce mécanisme permet d'exporter dans Excel une fonction du type suivant: 

        [WorksheetFunction]
        public double Interpolate(ICurve curve, DateTime t)
        {
            return curve.GetValue(t);
        }

Créer un "sérialiseur" est trés simple il suffit d'implémenter l'interface suivante:

 
    public interface ISerialize<TType>
    {
        TType Deserialize(object param);

        object Serialize(TType param);
    }

La méthode Deserialize permet à partir d'un type primitif de créer l'objet souhaité.

La méthode Serialize réalise l'étape inverse, à partir de l'objet cible elle le transforme en type primitif.


 Appeler des macros depuis l'environnement VBA

Il est possible d’appeler des macros Rio depuis du code VBA. Pour cela le Framework Rio fournit un ensemble d’objets VBA destiné à cet usage.

Le principe est très simple depuis un objet de type RIOEnv il est possible de récupérer une référence sur une macro sous la forme d'un objet de type IRMacro. Ceci quel que soit le plugin dans lequel se trouve votre macro.

Le type IRMacro possède une méthode Execute prenant en argument une collection de paramètres permettant d'invoquer la macro comme le montre l’exemple ci-dessous.


        [MacroFunction]
        public void Format(Range selection)
        {
            //...
        }

Le code VBA permettant d'invoquer la macro.

    Dim env As RIOEnv
    Dim params As RParams
    Dim macro As IRMacro
    Dim result As Variant
    
    Set env = New RIOEnv
    Set params = New RParams
    params.Add Range("A1:E14")
        
    Set macro = env.Macros("Format")
    result = macro.Execute(params)
    
    
    Set macro = Nothing
    Set params = Nothing
    Set env = Nothing

 Consommez des services distants

Il est très fréquent de nos jours de trouver des systèmes d’information architecturés autour de services. Service d’authentification, service d'accès aux données etc. L'interrogation de ces services peut dans certains cas demander beaucoup de temps de calcul.

Le Framework Rio permet d’exécuter des tâches en arrière-plan tout en permettant à l’interface graphique de rester disponible à son utilisateur. Via le service IAsyncService vous disposez d’un moyen simple permettant d’exécuter des tâches de manière asynchrone sans bloquer l’interface utilisateur.

Cette interface possède un certain nombre de méthodes dont une permet de lancer une tâche en arrière plan et d’exécuter une macro à la fin de l’exécution de celle-ci. Ce type de fonctionnalité est très utile car le développeur est sûr que la macro s’exécutera sur le thread UI, il pourra donc effectuer une action ou agir sur l’interface de son hôte.

L’exemple suivant montre la mise en oeuvre d’un appel de service distant.


        [MacroFunction]
        public void StartTask()
        {
            object param1 = null, param2 = null;
            // Initialize param1,param2 ...

            //Get IAsyncService from Context.
            IAsyncService service = context.GetService<IAsyncService>();

            // Create a Task.
            AsyncTask task = new AsyncTask(this.AsyncMethod, new object[] { param1, param2 }, "OnTaskComplete");
            service.AsyncExecute(task);
        }

        // The asynchronous method.
        object AsyncMethod(object[] Params)
        {
            object result = null;
            // Perform asynchronous work...
            return result;
        }

        [MacroFunction("OnTaskComplete")]
        public void Macro1(AsyncTask task)
        {
            // Get asynchronous result.
            object o = task.Result;
            // ...
        }