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

Macros et VBA Excel Discussion :

Windows API longueur de String (VBA.Len vs. VBA.LenB)


Sujet :

Macros et VBA Excel

  1. #1
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut Windows API longueur de String (VBA.Len vs. VBA.LenB)
    Bonjour,

    A force de creuser le sujet, je me suis rendu-compte qu'il était préférable de récupérer la longueur d'une String (peut-être que c'est à différencier d'un buffer ?) via VBA.LenB. Hors, le code suivant plante en 64 bits.

    Le bout de code suivant permet de lire le contenu d'une console MS-DOS.

    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
     
        '...
     
        Dim lpCharacter As String: lpCharacter = VBA.Space$(8192) 'je pourrais augmenter la taille, mais ça me suffit
     
        'a priori, je devrais écrire nLength:=VBA.LenB(lpCharacter) au lieu de nLength:=VBA.LenB(lpCharacter) pour assurer une compatibilité mixte 32 vs. 64 bits, mais ça plante en 64 bits
        API.ReadConsoleOutputCharacter hConsoleOutput:=hConsoleOutput, _
            lpCharacter:=lpCharacter, _
            nLength:=VBA.Len(lpCharacter), _
            dwReadXY:=0&, _
            lpNumberOfCharsRead:=lpNumberOfCharsRead 'dwReadXY est remplacé par dwReadCoord dans la déclaration officielle
     
        pStr = VBA.left$(lpCharacter, lpNumberOfCharsRead)
     
        '...
    Pouvez-vous s'il vous plaît m'en dire davantage concernant ce type de subtilité ?

    Merci

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut
    En utilisant la fonction PointToLongLong, je me suis rendu comte que lenB(ll) = 2, alors que VBA.LenB(ll) = 8.

    Je sais qu'utiliser VBA.LenB pour une structure personnalisée conduit à l'erreur suivante (notamment pour initialiser cbSize dans la plupart des structures de l'API Windows) :

    Nom : 2019-11-18 23_03_31-Clipboard.png
Affichages : 436
Taille : 3,7 Ko

    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
    'copies a API.POINT into a LongLong. For an API requiring a ByVal API.POINT parameter, this LongLong can be passed in instead
    #If Win64 Then
    Function PointToLongLong(ByRef pt As API.POINT) As LongLong
     
        Dim ll As LongLong
     
        Dim cbLongLong As LongPtr: cbLongLong = LenB(ll) 'VBA.LenB(ll) is wrong here
     
        'makes sure the contents will fit
        If LenB(pt) = cbLongLong Then API.CopyMemory Destination:=ll, Source:=pt, length:=cbLongLong
     
        PointToLongLong = ll
     
    End Function
    #End If
    Pouvez-vous m'en dire davantage à ce sujet ?

  3. #3
    Expert confirmé
    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Par défaut
    Attention : VBA.lenB n'est pas la même fonction que lenB

    Dans la bibliothèque VBA, lenB est une méthode la classe String qui permet de connaître la taille occupée en octets par une chaîne de caractère.
    Si on lui donne un numérique, il est d'abord transformé en String.
    Si on lui donne une structure, la conversion en String ne peut se faire d(où l'erreur je pense.

    LenB tout court est une instruction du langage.
    C'est celle-ci qui permet de connaître la taille d'une variable en octet, quelque soit son type.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Dim aa As Long
    aa = 12345
    VBA.LenB (aa) => 10
    LenB(aa) => 4
    12345 est converti par la première fonction en "12345", qui nécessite 10bytes (car unicode)
    Alors que la taille réelle du Long est bien 4.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Dim aa As String
    aa = "12345"
    VBA.LenB (aa) => 10
    LenB(aa) => 10
    Ici pour du String les deux sont identiques.

  4. #4
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut
    Merci pour ces précisions, ne s'agirait-il pas plutôt de la classe Strings (elle-même de la librairie VBA) ? Car, j'ai bien un VBA.Strings.LenB(...) qui est identique à VBA.LenB(...). Est-ce que du coup, LenB est une instruction "ancéstrale" (BASIC) au même titre que Open, Write, Close par exemple ?

    Merci encore !

  5. #5
    Expert confirmé
    Avatar de Arkham46
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    5 865
    Détails du profil
    Informations personnelles :
    Localisation : France, Loiret (Centre)

    Informations forums :
    Inscription : Septembre 2003
    Messages : 5 865
    Par défaut
    Oui c'est ça, bibliothèque VBA, classe Strings (vu son nom, pas étonnant que c'est prévu pour des String).

    LenB tout court doit être une fonction du coeur de vba, on ne trouve qu'un lenB dans l'explorateur d'objets (celui de la bibliothèque vba).

    Personnellement je n'avais jamais utilisé vba.lenb.

  6. #6
    Membre éclairé
    Homme Profil pro
    Ingénieur aéronautique
    Inscrit en
    Octobre 2018
    Messages
    216
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur aéronautique

    Informations forums :
    Inscription : Octobre 2018
    Messages : 216
    Par défaut
    Je viens de faire une nouvelle découverte ... et tout s'explique, mais quand même !!

    Si j'écris LenB(Expression:="Blabla"), ça ne compile pas, alors que VBA.LenB(Expression:="Blabla") ou VBA.Strings.LenB(Expression:="Blabla") passe très bien

    Nom : Capture.PNG
Affichages : 401
Taille : 1,9 Ko

    En fait, dans un soucis de rigueur, j'ai pris l'habitude de toujours nommé les noms des arguments, même s'ils sont flagrants, mais je me rends compte que pour certains, ça ne passe pas, comme CallByName. Dois-je en conclure que toutes les instructions VBA n'acceptent pas les arguments nommés ? Je vais voir de plus près ce qu'est au juste une instruction VBA .

Discussions similaires

  1. Windows API
    Par couet dans le forum Windows
    Réponses: 4
    Dernier message: 15/05/2006, 13h31
  2. Réponses: 2
    Dernier message: 15/03/2006, 10h13
  3. Prb de longueur dans STRING
    Par jbaudin dans le forum Access
    Réponses: 14
    Dernier message: 06/09/2005, 16h46
  4. Windows API
    Par datax dans le forum Windows
    Réponses: 1
    Dernier message: 22/08/2005, 10h58
  5. [Windows]Api win32 pour java
    Par cpanette dans le forum API standards et tierces
    Réponses: 1
    Dernier message: 27/06/2005, 15h06

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