IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Result qui ne se vide pas dans une fonction


Sujet :

Langage Delphi

  1. #1
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 426
    Points : 3 064
    Points
    3 064
    Par défaut Result qui ne se vide pas dans une fonction
    Bonjour

    Voilà un code qui affiche les infos des moniteurs !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
    // -----------------------------------------------------------------------------------------------------
    // This code was generated by the Wmi Delphi Code Creator (WDCC) Version 1.9.9.482
    // http://code.google.com/p/wmi-delphi-code-creator/
    // Blog http://theroadtodelphi.wordpress.com/wmi-delphi-code-creator/
    // Author Rodrigo Ruz V. (RRUZ) Copyright (C) 2011-2015
    // -----------------------------------------------------------------------------------------------------
    //
    // LIABILITY DISCLAIMER
    // THIS GENERATED CODE IS DISTRIBUTED "AS IS". NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED.
    // YOU USE IT AT YOUR OWN RISK. THE AUTHOR NOT WILL BE LIABLE FOR DATA LOSS,
    // DAMAGES AND LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING OR MISUSING THIS CODE.
    //
    // ----------------------------------------------------------------------------------------------------
    program GestionMoniteurs;
     
    {$APPTYPE CONSOLE}
     
     
    uses
      SysUtils,
      ActiveX,
      ComObj,
      Variants;
     
    function OleVariantArrayUInt16ToString(const PostData: OleVariant): string;
    var
      K: Integer;
    begin
      //Result := '';
      if VarIsNull(PostData) then
        Exit('');
      for K    := VarArrayLowBound(PostData, 1) to VarArrayHighBound(PostData, 1) do
        Result := Concat(Result, Chr(UInt16(PostData[K])));
      Result   := Trim(Result);
    end;
     
    // Monitor ID
     
    procedure GetWmiMonitorIDInfo;
    const
      WbemUser            = '';
      WbemPassword        = '';
      WbemComputer        = 'localhost';
      wbemFlagForwardOnly = $00000020;
    var
      FSWbemLocator : OleVariant;
      FWMIService   : OleVariant;
      FWbemObjectSet: OleVariant;
      FWbemObject   : OleVariant;
      oEnum         : IEnumvariant;
      iValue        : LongWord;
    begin;
      FSWbemLocator  := CreateOleObject('WbemScripting.SWbemLocator');
      FWMIService    := FSWbemLocator.ConnectServer(WbemComputer, 'root\WMI', WbemUser, WbemPassword);
      FWbemObjectSet := FWMIService.ExecQuery('SELECT * FROM WmiMonitorID', 'WQL', wbemFlagForwardOnly);
      oEnum          := IUnknown(FWbemObjectSet._NewEnum) as IEnumvariant;
      while oEnum.Next(1, FWbemObject, iValue) = 0 do
      begin
        Writeln(Format('Active            : %s', [String(FWbemObject.Active)])); // Boolean
        Writeln(Format('InstanceName      : %s', [String(FWbemObject.InstanceName)])); // String
        Writeln(Format('ManufacturerName  : %s', [OleVariantArrayUInt16ToString(FWbemObject.ManufacturerName)]));// Array of Uint16
        Writeln(Format('ProductCodeID     : %s', [OleVariantArrayUInt16ToString(FWbemObject.ProductCodeID)])); // Array of Uint16
        Writeln(Format('SerialNumberID    : %s', [OleVariantArrayUInt16ToString(FWbemObject.SerialNumberID)]));  // Array of Uint16
        Writeln(Format('UserFriendlyName  : %s', [OleVariantArrayUInt16ToString(FWbemObject.UserFriendlyName)])); // Array of Uint16
        Writeln(Format('WeekOfManufacture : %d', [Integer(FWbemObject.WeekOfManufacture)])); // Uint8
        Writeln(Format('YearOfManufacture : %d', [Integer(FWbemObject.YearOfManufacture)])); // Uint16
        Writeln('');
        FWbemObject := Unassigned;
      end;
    end;
     
    begin
      try
        CoInitialize(nil);
        try
          GetWmiMonitorIDInfo;
        finally
          CoUninitialize;
        end;
      except
        on E: EOleException do
          Writeln(Format('EOleException %s %x', [E.Message, E.ErrorCode]));
        on E: Exception do
          Writeln(E.Classname, ':', E.Message);
      end;
      Writeln('Press Enter to exit');
      Readln;
     
    end.
    Vous pouvez voir dans la fonction que j'ai commenté la ligne : //Result := '';

    Voilà le résultat sur XE7 :

    Active : True
    InstanceName : DISPLAY\XEC1130\5&f01f744&0&UID4353_0
    ManufacturerName : XEC
    ProductCodeID : 1130
    SerialNumberID : 1
    UserFriendlyName : CM22X3
    WeekOfManufacture : 35
    YearOfManufacture : 2023

    Active : True
    InstanceName : DISPLAY\GSM5678\5&f01f744&0&UID4355_0
    ManufacturerName : XECGSM
    ProductCodeID : 11305678
    SerialNumberID : 1395986
    UserFriendlyName : CM22X3W2242
    WeekOfManufacture : 9
    YearOfManufacture : 2008

    Press Enter to exit
    Regardez et comparez les lignes
    ManufacturerName : XEC
    ProductCodeID : 1130

    ManufacturerName : XECGSM
    ProductCodeID : 11305678

    Maintenant si je décommente la ligne dans la fonction :

    Active : True
    InstanceName : DISPLAY\XEC1130\5&f01f744&0&UID4353_0
    ManufacturerName : XEC
    ProductCodeID : 1130
    SerialNumberID : 1
    UserFriendlyName : CM22X3
    WeekOfManufacture : 35
    YearOfManufacture : 2023

    Active : True
    InstanceName : DISPLAY\GSM5678\5&f01f744&0&UID4355_0
    ManufacturerName : GSM
    ProductCodeID : 5678
    SerialNumberID : 395986
    UserFriendlyName : W2242
    WeekOfManufacture : 9
    YearOfManufacture : 2008

    Press Enter to exit
    Comme vous pouvez le voir, ma fonction ne donne pas du tout le même résultat.
    Comme si Result n'était remis à '' à chaque appel de la fonction.

    Est-ce normal ???
    J-L aka Papy pour les amis

  2. #2
    Membre régulier
    Homme Profil pro
    libre
    Inscrit en
    Mai 2024
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Mai 2024
    Messages : 49
    Points : 100
    Points
    100
    Par défaut
    Le compilateur va émettre un avertissement pour avoir utilisé un variable non initialisé cela indique que le risque d'avoir un comportement ambigu est présent.

    dans ce contexte le Result contient l'adresse du variable qui recevra le valeur de la fonction si ce denier n'est pas vide sa valeur peut être accessible

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function toTxt(value: integer):string;
    begin
      Result := Result + value.ToString
    end;
     
    var
     s :string;
    begin
       s := 'Text';
     
       s := toTxt(1000);
     
       Showmessage(s); // Text1000

  3. #3
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 667
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 667
    Points : 6 996
    Points
    6 996
    Par défaut
    Pas d'accord.
    Ton exemple donne 1000, comme je m'y attendais.
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  4. #4
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 724
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 724
    Points : 13 219
    Points
    13 219
    Par défaut
    L'exemple de Volid est correct.

    Le comportement dépend du type de résultat. Pour une chaîne, Delphi traduit la fonction comme s'il y avait un paramètre var supplémentaire sur une procédure : procedure ToTxt(Value :integer; var Result :string). Result (s) est initialisé et la chaîne est concaténée.

  5. #5
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 426
    Points : 3 064
    Points
    3 064
    Par défaut
    Désolé mais sur mon poste, l'exemple de volid renvoie bien 1000 comme pour Lung

    Nom : 2024-05-03_103057.jpg
Affichages : 109
Taille : 148,8 Ko
    J-L aka Papy pour les amis

  6. #6
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 426
    Points : 3 064
    Points
    3 064
    Par défaut
    Après, ça dépend peut-être de la version de Delphi ??

    L'un de vous aurait-il testé le DPR pour vérifier si ça fait pareil sur une autre version que XE7 ?
    J-L aka Papy pour les amis

  7. #7
    Membre régulier
    Homme Profil pro
    libre
    Inscrit en
    Mai 2024
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Mai 2024
    Messages : 49
    Points : 100
    Points
    100
    Par défaut
    L'un de vous aurait-il testé le DPR pour vérifier si ça fait pareil sur une autre version que XE7 ?

    J'ai fait le test sur Delphi Tokyo et Delphi7 et j'obtiens le même comportement (application vcl) mais comme c'est lié au fonctionnement interne il faut vérifier comment le code est compilé ..Probablement compilateur introduit un variable temporaire pour y mettre la valeur renvoyée par la fonction et comme le string est un type protégé et initialisé par défaut ce comportement n'est pas visible mais si la fonction renvoie une structure on obtiendra des valeurs farfelues.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    function TstRect(value: integer):TRect;
    begin
      Result.Right :=  Result.Right + value
    end;
     
    procedure TForm1.Button3Click(Sender: TObject);
    var
     R:TRect;
    begin
       fillchar(R, SizeOf(R), 0);
       R.Right := 1000;
       R := TstRect(100);
     
       Showmessage(inttostr(R.Right) ); 
     
    end;

  8. #8
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 724
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 724
    Points : 13 219
    Points
    13 219
    Par défaut
    Tu n'es pas dans le même cas de figure.

    Une variable globale est connue à travers toute l'unité, il n'est logiquement pas nécessaire d'ajouter une référence à la procédure (mais ça ne ressort pas de la doc).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      s :string;
     
    begin
      s := 'Text';
      s := toTxt(1000);
     
      WriteLn(s); // 1000
      ReadLn;
    end.
    alors que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    begin
      var s := 'Text';
      s := toTxt(1000);
     
      WriteLn(s); // Text1000
      ReadLn;
    end.
    On constate l'importance d'initialiser Result

  9. #9
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 426
    Points : 3 064
    Points
    3 064
    Par défaut
    ok mais dans XE7, ça, ça ne fonctionne pas

    var s := 'Text';

    Je suis bien dans le premier cas que tu donnes en exemple.
    Donc, ça devrait bien me donner le bon résultat ?

    Ou alors, je suis vraiment "à la rue"


    De plus, dans mon code, je n'assigne pas le résultat de la fonction à une variable.
    Je transmets le résultat directement à writeln.
    J-L aka Papy pour les amis

  10. #10
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 724
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 724
    Points : 13 219
    Points
    13 219
    Par défaut
    Si tu veux vraiment tester dans une console, passe par une routine intermédiaire. Là Result de ToTxt1 est passé en var à ToTxt.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function toTxt(value: integer):string;
    begin
      Result := Result + value.ToString
    end;
     
    function toTxt1(value: integer):string;
    begin
      Result := 'Text';
      Result := ToTxt(value);
    end;
     
    var
      s :string;
     
    begin
      s := toTxt1(1000);
     
      WriteLn(s); // Text1000
      ReadLn;
    end.
    Sinon une app GUI :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function toTxt(value: integer):string;
    begin
      Result := Result + value.ToString
    end;
     
    var
      s1 :string;
     
    procedure TForm1.FormCreate(Sender: TObject);
    var
      s2 :string;
    begin
      s1 := 'Text';
      s1 := toTxt(1000);
      ShowMessage(s1); // 1000
     
      s2 := 'Text';
      s2 := toTxt(1000);
      ShowMessage(s2); // Text1000
    end;

  11. #11
    Membre régulier
    Homme Profil pro
    libre
    Inscrit en
    Mai 2024
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : libre

    Informations forums :
    Inscription : Mai 2024
    Messages : 49
    Points : 100
    Points
    100
    Par défaut
    De plus, dans mon code, je n'assigne pas le résultat de la fonction à une variable.
    Je transmets le résultat directement à writeln.
    les valeurs renvoyées par les appels à la fonction sont placées dans des variables temporaires avant d'appeler Writelin et ces mêmes variables non vides seront utilisés à la prochaine boucle

    On peut récrire le code pour comprendre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
      while oEnum.Next(1, FWbemObject, iValue) = 0 do
      begin
        tmp1 :=  OleVariantArrayUInt16ToString(FWbemObject.ManufacturerName)
        Writeln(tmp1);
     
        tmp2 :=  OleVariantArrayUInt16ToString(FWbemObject.ProductCodeID)); 
        Writeln(tmp2);
         ...
      end;
    Un test avec boucle:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    program GestionMoniteurs;
    {$APPTYPE CONSOLE}
     
    uses
      SysUtils;
     
    function toTxt(value: integer):string;
    begin
      Result := Result +  Inttostr(value)
    end;
     
    procedure Test;
    var
      I:integer;
    begin;
      for I := 0 to 1 do
      begin
        Writeln(toTxt(11));
        Writeln(toTxt(22));
        Writeln('');
      end;
    end;
     
    begin
     
      Test();
      Readln;
     
    end.
    le test affiche:
    boucle 0
    11
    22

    boucle 1
    1111
    2222


    finalement Result qu'il soit de type string ou autre doit être traité comme n'importe quel autre variable local et devrait d’être initialisé avant toute utilisation.

  12. #12
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 426
    Points : 3 064
    Points
    3 064
    Par défaut
    Eh ben c'est un bon piège ce truc là !

    Donc, j'ai modifié ma fonction comme suit et je n'ai plus le problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    function OleVariantArrayUInt16ToString(const PostData: OleVariant): string;
    var
      K: Integer;
      B: Char;
      S: string;
    begin
      if not VarIsNull(PostData) then
        for K := VarArrayLowBound(PostData, 1) to VarArrayHighBound(PostData, 1) do
        begin
          B := Chr(UInt16(PostData[K]));
          if B = #0 then
            Break;
          S := Concat(S, B);
        end;
      Result := S;
    end;
    Merci à tous pour vos éclaircissements
    J-L aka Papy pour les amis

  13. #13
    Expert confirmé
    Avatar de anapurna
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2002
    Messages
    3 434
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Mai 2002
    Messages : 3 434
    Points : 5 846
    Points
    5 846
    Par défaut
    salut

    moi ce qui me choque c'est ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    function toTxt(value: integer):string;
    begin
      Result := Result +  Inttostr(value)
    end;
    A moins d'être dans une boucle je ne vois pas trop l'intérêt de cette construction
    il aurait été plus simple de faire


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    function toTxt(value: integer):string;
    begin
       Result :=  Inttostr(value)
    end;
    Nous souhaitons la vérité et nous trouvons qu'incertitude. [...]
    Nous sommes incapables de ne pas souhaiter la vérité et le bonheur, et sommes incapables ni de certitude ni de bonheur.
    Blaise Pascal
    PS : n'oubliez pas le tag

  14. #14
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 724
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 724
    Points : 13 219
    Points
    13 219
    Par défaut
    Citation Envoyé par Papy214 Voir le message
    Donc, j'ai modifié ma fonction comme suit et je n'ai plus le problème
    S ou Result, même combat ! S doit être initialisé.

    ps : A+B est plus rapide que concat(A,B).

  15. #15
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 426
    Points : 3 064
    Points
    3 064
    Par défaut
    Citation Envoyé par Andnotor Voir le message
    S ou Result, même combat ! S doit être initialisé.

    ps : A+B est plus rapide que concat(A,B).
    ça fonctionne pourtant très bien sans initialiser la variable S :-(

    Active : True
    InstanceName : DISPLAY\XEC1130\5&f01f744&0&UID4353_0
    ManufacturerName : XEC
    ProductCodeID : 1130
    SerialNumberID : 1
    UserFriendlyName : CM22X3
    WeekOfManufacture : 35
    YearOfManufacture : 2023

    Active : True
    InstanceName : DISPLAY\GSM5678\5&f01f744&0&UID4355_0
    ManufacturerName : GSM
    ProductCodeID : 5678
    SerialNumberID : 395986
    UserFriendlyName : W2242
    WeekOfManufacture : 9
    YearOfManufacture : 2008
    pour le concat, je ne savais pas.
    J-L aka Papy pour les amis

  16. #16
    Rédacteur/Modérateur
    Avatar de Andnotor
    Inscrit en
    Septembre 2008
    Messages
    5 724
    Détails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Septembre 2008
    Messages : 5 724
    Points : 13 219
    Points
    13 219
    Par défaut
    Tu joues avec le feu

    Les variables locales ne sont pas initialisées contrairement aux variables globales.

  17. #17
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 426
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 426
    Points : 3 064
    Points
    3 064
    Par défaut
    Par contre, ton conseil sur le concat m'a incité à autre faire autre chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    function OleVariantArrayUInt16ToString(const OleData: OleVariant): string;
    var
      K: Integer;
      B: Char;
      S: string;
    begin
      if not VarIsNull(OleData) then
      begin
        SetLength(S, VarArrayHighBound(OleData, 1) + 1);
        for K := VarArrayLowBound(OleData, 1) to VarArrayHighBound(OleData, 1) do
        begin
          B := Chr(UInt16(OleData[K]));
          if B = #0 then
            Break;
          S[K + 1] := B;
        end;
      end;
      Result := S.Trim;
    end;
    Au deuxième appel, S reprend les premiers caractères placés dans la chaîne lors du premier appel.
    C'est le SetLength qui récupère la même zone mémoire.

    Pour ce qui est de jouer avec le feu, j'essaie surtout d'analyser tout ça. Bien sûr qu'au bout du compte je vais initialiser Result

    Au final, ça va donner ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    function OleVariantArrayUInt16ToString(const OleData: OleVariant): string;
    var
      K, T: Integer;
      B: Char;
      S: string;
    begin
      T := VarArrayHighBound(OleData, 1);
      S := StringOfChar(#32, Succ(T));
      if not VarIsNull(OleData) then
      begin
        for K := VarArrayLowBound(OleData, 1) to T do
        begin
          B := Chr(UInt16(OleData[K]));
          if B = #0 then
            Break;
          S[K + 1] := B;
        end;
      end;
      Result := S.Trim;
    end;
    J-L aka Papy pour les amis

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [ADO] Requete qui ne s'execute pas dans une transaction
    Par Faboul dans le forum VBA Access
    Réponses: 1
    Dernier message: 17/07/2007, 13h30
  2. [MySQL] Valeur qui ne s'ajoute pas dans une BDD
    Par Luverger dans le forum PHP & Base de données
    Réponses: 9
    Dernier message: 09/02/2007, 11h04
  3. Réponses: 10
    Dernier message: 15/12/2006, 07h34
  4. Réponses: 5
    Dernier message: 02/10/2006, 19h24
  5. excel: colonne qui ne s'affiche pas dans une liste
    Par fast&furious dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 19/07/2006, 18h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo