XL 2016 VBA - Comment passer une structure Private en argument d'une fonction ?

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Dudu2

XLDnaute Barbatruc
Bonjour,

On peut passer en argument d'une fonction une structure Public ByRef.
Excel refuse de le faire avec une structure Private.

1734968809644.png


Y a-t-il un moyen détourné de le faire en la mappant sur son adresse ou autre ?
 

Pièces jointes

Sinon, est-ce normal qu'il y ait une erreur de compilation avec #39 ?
J'ai reposté le fichier avec des #if VBA7 en supposant que c'est la cause de l'erreur vu que tu ne la précises pas.

Je n'ai toujours pas compris l'intérêt de se forcer à limiter la portée des variables et de pondre une usine à gaz pour contourner le problème engendré
@TooFatBoy, tu veux vraiment que je te repose le problème tel qu'énoncé en privé ?

Tu as 3 modules pré-construits: Module_A, Module_B, Module_C. (c'est précisément le cas ici)
Dans un classeur, tu peux utiliser les combinaisons suivantes:
Classeur1 -> Module_A et Module_B
Classeur2 -> Module_A et Module_C
Classeur3 -> Module_B et Module_C
Classeur4 -> Module_A et Module_B et Module_C

Explique-moi dans quel Module tu places la déclaration Public de la structure ? Sachant que tu peux n'avoir qu'une seule fois cette déclaration Public dans un classeur.
 
@TooFatBoy, tu veux vraiment que je te repose le problème tel qu'énoncé en privé ?
Non, en français correct comme ci-dessous c'est mieux car ça devient compréhensible. 😉


Tu as 3 modules pré-construits: Module_A, Module_B, Module_C. (c'est précisément le cas ici)
Dans un classeur, tu peux utiliser les combinaisons suivantes:
Classeur1 -> Module_A et Module_B
Classeur2 -> Module_A et Module_C
Classeur3 -> Module_B et Module_C
Classeur4 -> Module_A et Module_B et Module_C

Explique-moi dans quel Module tu places la déclaration Public de la structure ? Sachant que tu peux n'avoir qu'une seule fois cette déclaration Public dans un classeur.
Comme dit précédemment : dans le module que tu veux.
Autrement dit tu mets la déclaration dans les trois modules et selon les modules que tu mets dans ton classeur tu mets en commentaire dans le(s) module(s) ad hoc.

Sinon, le plus simple est que tu crées un quatrième module dans lequel tu définis ta variable. 😉
 
@TooFatBoy
Autrement dit tu mets la déclaration dans les trois modules et selon les modules que tu mets dans ton classeur tu mets en commentaire dans le(s) module(s) ad hoc.
Non car les modules sont pré-construits (à utiliser tels quels) pour qu'on n'ait précisément pas de question à se poser sur une modification obligatoire à faire ici ou là pour rendre une déclaration Public.

Sinon, le plus simple est que tu crées un quatrième module dans lequel tu définis ta variable. 😉
Oui, je l'aurais peut-être fait si le passage par adresse n'avait pas fonctionné. Mais c'est un truc en plus à gérer/trimbaler.

et de pondre une usine à gaz pour contourner le problème engendré
Justement, le passage par adresse, une fois le copymemory maîtrisé (c'est le plus délicat), est d'une extrême simplicité.
 
re
Bonjour à tous
oui moi aussi comme toofatboy je me pose des questions sur l'utilité d'un tel stratagème
les blocs type sont bien pratiques pour attribuer des membres a une variable
en public utilisable partout ,d'ailleurs je l'utilise de cette manière dans mon ScreenCatalog
même si j'ai apprécié le fait de travailler sur l'idée(c'est toujours intéressant de travailler en dehors des sentiers battus)
avec chatGPT qui pour une fois m'a donné la bonne voie
après certainement que @Dudu2 a ces raisons d'un tel besoin
 
@patricktoulon,

Tu veux dire qu'on aurait pu utiliser le pointeur ?
BOOL GetMonitorInfoW(
[in] HMONITOR hMonitor,
[out] LPMONITORINFO lpmi
);

Mais alors comment baser MONITORINFO sur ce pointeur ? En utilisation les copymemory ?
non je veux dire qu'il faut utiliser celle ci a la place de getmonitorinfoA
getmonitorinfo en dessous XP
au dessus GetmonitorinfoW ilest plus stable et d'autres membre dans le type monitorinfo peuvent être mis en place notamment le displayname qui ne fonctionne pas sur W10 avec getmonitorinfoA
du coup j'ai supprimé les api displaydevice de mon module
 
La correction de la version ChatGPT en fait la conversion à l’Unicode est incorrete puisque le texte de l'entrée est déjà quantifié sur 2 octets...

Actuellement on arrivant au point d'extraction de donné en string pourquoi ne pas sérialiser l'ensemble de structure en string et après la reconstituer aux format binaire correspondant c'est moins pire que l'utilisation de Copymemry
VB:
Private Function PtrToStringChatGPT(ByVal Ptr As LongPtr) As String
    Dim StrLen As Long
    Dim Buffer() As Byte

    ' Lire la longueur de la chaîne à partir de la mémoire
    CopyMemory StrLen, ByVal Ptr - 4, 4 ' Longueur Unicode

    ' Copier les données dans un tableau de bytes
    If StrLen > 0 Then
        ReDim Buffer(0 To (StrLen * 2) - 1) ' Chaque caractère = 2 octets (Unicode)
        CopyMemory Buffer(0), ByVal Ptr, StrLen * 2
        PtrToStringChatGPT = Buffer
    Else
        PtrToStringChatGPT = vbNullString
    End If
End Function
 
Si tu veux passer par cette version corrigée du ChatGPT alors il faut faire ça sinon le Len() du résultat est le double (6 au lieu de 3) même si on ne voit que "ABC", les autres étant des x'00'. Je ne sais pas comment VBA arrive à convertir un tableau de Bytes en String, mais il le fait, c'est magique !
VB:
Private Function PtrToStringChatGPT(ByVal Ptr As LongPtr) As String
    Dim StrLen As Long
    Dim Buffer() As Byte

    ' Lire la longueur de la chaîne à partir de la mémoire
    CopyMemory StrLen, ByVal Ptr - 4, 4 ' Longueur Unicode

    ' Copier les données dans un tableau de bytes
    If StrLen > 0 Then
        ReDim Buffer(0 To StrLen - 1)  ' Chaque caractère = 2 octets (Unicode)
        CopyMemory Buffer(0), ByVal Ptr, StrLen
        PtrToStringChatGPT = Buffer
    Else
        PtrToStringChatGPT = vbNullString
    End If
End Function

L'utilisation de copymemory ne me dérange pas. C'est clair.
Mapper en string les structures, c'est une promesse de galère selon ce qu'il y a dedans.
On a les fonctions VarPtr, StrPtr, ObjPtr. Autant s'en servir.
 
Dernière édition:
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

  • Question Question
XL 2021 VBA excel
Réponses
4
Affichages
69
Réponses
6
Affichages
113
Réponses
3
Affichages
231
Retour