Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

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

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.



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

Pièces jointes

  • Classeur1.xlsm
    22 KB · Affichages: 8

patricktoulon

XLDnaute Barbatruc
et c'est normal que ça fonctionne pas
ce bloc dans le module 1
VB:
Private Type MONTYPE
    L As Long
    S As String
End Type

et ce bloc dans le module 2
Code:
Private Type MONTYPE
    L As Long
    S As String
End Type

se sont pas les mêmes et combien même tu en mettrais un ou les deux en public
deux address mémoire différentes
ils porteraient un nom différent ça serait pareil

si mt est un exemplaire de montype du module 1 ,il ne peut pas être un exemplaire de montype du module2
rien ne t’empêche de transférer les valeurs mais il faut que leur portée soit public et qu'il aient un nom différent sinon on s'y retrouve plus
 

Dudu2

XLDnaute Barbatruc
Chez moi ce code fonctionne sans problème. Excel 2016.

Module 1
VB:
Private Type MONTYPE
    L As Long
    S As String
End Type

Sub a()
    Dim MT As MONTYPE
  
    MT = b
    MsgBox MT.S
End Sub

Module 2
Code:
Private Type MONTYPE
    L As Long
    S As String
End Type

Function b() As MONTYPE
    b.S = "Fonction b du Moodule 2"
End Function

 

Pièces jointes

  • Classeur2.xlsm
    23.1 KB · Affichages: 1

Dudu2

XLDnaute Barbatruc
En passant l'adresse de la structure ça peut fonctionner.
En 64bits je passe le pointer en LongLong. En Variant ça ne fonctionne pas.
Essaie de voir en 32 bits si tu dois le passer en Long ou en Currency.

 

Pièces jointes

  • Classeur1.xlsm
    24.8 KB · Affichages: 2

patricktoulon

XLDnaute Barbatruc
non là c'est le crash total
si je reste en lonptr il crash au bout de 2/3 fois
j'avais eu le même problème avec la sauvegarde du pointeur du ruban
et j'avais trouvé il fallait vider l'addresse mémoire allouée en fin (après le message )
je me souviens plus comment j'avais fait
 

Dudu2

XLDnaute Barbatruc
Ok, LongPtr en 32 bits c'est comme un Long.
De toutes façons, je ne vois pas pourquoi un copymemory serait ok en 64 bits et pas en 32 bits sauf problème de paramètres.
 
Dernière édition:

patricktoulon

XLDnaute Barbatruc
Bonjour @Dudu2
crash immédiat W10 office 2013 32
je me suis posé la question et aujourd'hui chatGPT est en forme
grosso modo le excel 32 gère très mal la mémoire avec copymemory selon le type de variable
et surtout le string
alors il faut décanter ce que m'a donné chatGPT fonctionne tres bien chez moi
comme je te l'ai dit hier il faut vider le block memoire(a ddress memory)utilisé après utilisation

voici le code du module 2 ce n'est pas de moi je le repete ca vient de chatGPT
VB:
Option Explicit

#If VBA7 Then
    #If Win64 Then
        Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
            Destination As Any, Source As Any, ByVal Length As LongPtr)
    #Else
        Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
            Destination As Any, Source As Any, ByVal Length As Long)
    #End If
#Else
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
        Destination As Any, Source As Any, ByVal Length As Long)
#End If

Private Type MONTYPE
    L1 As Long
    L2 As Long
    S As String
End Type

#If Win64 Then
Sub b(MTAdd As LongLong, Lg As Long)
#Else
Sub b(MTAdd As LongPtr, Lg As Long)
#End If
    Dim MT As MONTYPE
    Dim FixedPart() As Byte
    Dim PtrString As LongPtr

    ' Copier uniquement les parties fixes (L1, L2, et le pointeur de la chaîne)
    ReDim FixedPart(0 To LenB(MT) - 1)
    CopyMemory ByVal VarPtr(FixedPart(0)), ByVal MTAdd, LenB(MT)

    ' Reconstruire les parties fixes
    CopyMemory MT.L1, FixedPart(0), 4
    CopyMemory MT.L2, FixedPart(4), 4
    CopyMemory PtrString, FixedPart(8), LenB(PtrString) ' Adresse du contenu de la chaîne

    ' Reconstruire la chaîne de manière sûre
    If PtrString <> 0 Then
        MT.S = PtrToString(PtrString)
    End If

    ' Afficher les valeurs
    MsgBox MT.L1 & vbCrLf & MT.L2 & vbCrLf & MT.S
End Sub

Private Function PtrToString(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
        PtrToString = StrConv(Buffer, vbUnicode)
    Else
        PtrToString = vbNullString
    End If
End Function
je n'ai plus de problème
les explication de chatGPT
voilà
Patrick
 

patricktoulon

XLDnaute Barbatruc
Autrement dit si on examine bien le problème vient du fait qu'un des élément de mt est un string alors que les autres sont des long et en 32 la copymemory de mt génère un acces a une address mémoire érronnée
donc après le copymemory item 1 et 2 (qui sont des numérique
on copy la conversion de la variable "S" du bloc type avec son len(b)
on a ainsi un address mémoire exactement identique a l'address memoire de MT

voila
maintenant on sait d'ou vient l'erreur qui crash excel
 

Discussions similaires

Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…