Macros : ByVal doesn't work with parameters in a class object modul ...

classic Classic list List threaded Threaded
2 messages Options
Patrick Gelin Patrick Gelin
Reply | Threaded
Open this post in threaded view
|

Macros : ByVal doesn't work with parameters in a class object modul ...

Hi,

I'm using Libreoffice :

Version: 5.2.7.2
Build ID: 1:5.2.7-1
Threads CPU : 2; Version de l'OS :Linux 4.12; UI Render : par défaut;
VCL : gtk3;
Locale : fr-FR (fr_FR.UTF-8); Calc: group

Below is a complet macro to manage Vectors of variants (With french
coments) . I've got a problem with unitary test (Cf. Sub Main) because
call to procedure 'v.Ajouter(duolet)' use always passage by reference
instead of a passage by value (ByVal) ! For all that, I delicately
manage a passage by value in my function...

I tested with a call to New operator in order to build specifics
instances at each call, like this :

        duolet = new __TDuolet
        duolet.key = "MONTAGNE"
        duolet.Item = 3
        v.Ajouter(duolet)

And it's fine, the duolet variable is a new one instance. But I don't
want the caller do all this stuff. I would like easier way to do ...

I'm asking myself if it's a specific bug to my LibreOffice versin, or
with Variants and Struct type (__TDuolet) ?

What do you think about that ? What can I do to copy by val the
parameter into my function v.Ajouter(duolet) ?

Think you for your help...

Patrick

PS: Macro is below, it's a draft ...

---------------------------------------

REM  *****  BASIC  *****
Option Compatible
Option ClassModule

Option Explicit

Type __TDuolet
        key As String 'l'etiquette de l'objet
        item As Variant 'un objet quelconque
End Type

Private _Items As Variant
Private _n As Long
Private _Titre As String
Private _StepSize As Long

' #PROCEDURE# ==================================================================
' Name...........: Class_Initialize
' Description ...:
' Parameters ....:
' Syntax ........: Class_Initialize
' Return values .: Success - void
'                  Failure - sets @error
' Author ........: Patrick GELIN
' Modified.......:
' Remarks .......:
' Related .......:
' Link ..........:
' Example .......:
Private Sub Class_Initialize()
        _n = 0
        _Titre = Name
        _StepSize = 30
        _Items = DimArray(_StepSize+1)
End Sub

' #PROCEDURE# ==================================================================
' Name...........: Class_Terminate
' Description ...:
' Parameters ....:
' Syntax ........: Class_Terminate
' Return values .: Success - void
'                  Failure - sets @error
' Author ........: Patrick GELIN
' Modified.......:
' Remarks .......:
' Related .......:
' Link ..........:
' Example .......:
Private Sub Class_Terminate()
End Sub

Rem ***************************************************************************
Rem
Rem PROPRIETES
Rem
Rem ***************************************************************************
Public Property Let Titre(unTitre As String)
        _Titre  = unTitre
End Property

Public Property Get Titre As String
        Titre  = _Titre
End Property

Public Property Get AllItems As Variant
        AllItems = _Items
End Property

Public Property Let StepSize(ByVal delta As Long)
        _StepSize  = delta
End Property

Public Property Get StepSize As Long
        StepSize = _StepSize
End Property

Public Property Get NbElements As Long
        NbElements = _n
End Property

Public Property Get Taille As Long
        Taille = UBound(_Items) - LBound(_Items) + 1
End Property

Public Property Get UBound As Long
        UBound(_Items)
End Property

Public Property Get LBound As Long
        LBound(_Items)
End Property

Rem ***************************************************************************
Rem
Rem METHODES PRIVEES
Rem
Rem ***************************************************************************
Public Sub _Expend(Optional StepSize As Long, Optional isPresserved As Boolean = True)
       
        Dim IndexMax As Long
       
        If IsMissing(StepSize) Then StepSize = _StepSize
        IndexMax = UBound(_Items()) + StepSize
        If isPresserved Then
                Redim Preserve _Items(IndexMax) As Variant
        Else
                Redim _Items(IndexMax) As Variant
        EndIf
End Sub


Rem ***************************************************************************
Rem
Rem METHODES PUBLIQUES
Rem
Rem ***************************************************************************
' #PROCEDURE# ==================================================================
' Name...........: Ajouter
' Description ...: Ajouter un variant au vecteur.
' Parameters ....: Item (variant) : Un variant au vecteur.
' Syntax ........: Ajouter(Item)
' Return values .: N/A
' Author ........: Patrick GELIN
' Modified.......: 06/01/2018
' Remarks .......: ATTENTION : L'attribut ByVal ne fonctionne pas !
                                        'Le parametre Item doit donc avoir une instance spécifique,
                                        'sans réutiliser l'instance d'un autre Item déjà ajouté au vecteur
                                        'sinon ce premier aura la valeur de la dernière modification !
' Related .......:
' Link ..........:
' Example .......:
Public Sub Ajouter(ByVal Item As Variant)
       
        If (_n + 1) >= UBound(_Items) Then _Expend()
        _Items(_n) = Item
        _n = _n + 1
End Sub

' #PROCEDURE# ==================================================================
' Name...........: Execute
' Description ...:
' Parameters ....:
' Syntax ........: Execute()
' Return values .: Success - void
'                  Failure - sets @error
' Author ........: Patrick GELIN
' Modified.......:
' Remarks .......:
' Related .......:
' Link ..........:
' Example .......:
Public Sub Retirer(idx As Long)
        Dim i As Long
       
        if idx < 0 Then Exit Sub
       
        for i = idx to (_n - 1) step 1
                _Items(i) = _items(i+1)
        Next
        _n = _n -1
End Sub

Public Sub Inserer(idx As Long, ByVal Item As Variant)
        Dim i As Long
       
        if (idx < 0) OR (idx >= _n) Then Exit Sub
        If (_n + 1) >= UBound(_Items) Then _Expend()
       
        for i = _n to (idx + 1) step -1
                _Items(i) = _items(i-1)
        Next
        _Items(idx) = Item
        _n = _n + 1
End Sub


Public Sub Trace(oDebug As Object, Optional VisiteurTrace As Object)
        Dim i As Long
        Dim sIdx As String
       
        oDebug.Trace(Name, "==================================================")
        oDebug.Trace(Name, "Vecteur : " & Titre)
        oDebug.Trace(Name, "NbElements : " & NbElements)
        oDebug.Trace(Name, "Taille : " & Taille)
        oDebug.Trace(Name, "StepSize : " & StepSize)
        oDebug.Trace(Name, "..................................................")
        for i = LBound(_Items) to _n step 1
                sIdx = format(idx, "0000")
                If IsMissing(VisiteurTrace) Then
                        oDebug.Trace(Name, sIdx & " : " & _Items(i) + Chr(10))
                Else
                        oDebug.Trace(Name, sIdx & " : " & VisiteurTrace.Execute(_Items(i)) + Chr(10))
                EndIf
        Next
        oDebug.Trace(Name, "==================================================")
End Sub


Rem ********************************************
Rem Unitary tests
Rem ********************************************
Sub Main
        Dim duolet As __TDuolet
        Dim v As TVecteur
        Dim taille, NbElements As Long
       
        v = New TVecteur
        v.StepSize = 10
       
        taille = v.Taille
        NbElements = v.NbElements
       
        'duolet = new __TDuolet
        duolet.key = "MAISON"
        duolet.Item = 1
        v.Ajouter(ByVal duolet)
       
        'duolet = new __TDuolet
        duolet.key = "BATEAU"
        duolet.Item = 2
        v.Ajouter(ByVal duolet)

        duolet = new __TDuolet
        duolet.key = "MONTAGNE"
        duolet.Item = 3
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "FLEUR"
        duolet.Item = 4
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "SCOTCH"
        duolet.Item = 5
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "STYLO"
        duolet.Item = 6
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "ETOILE"
        duolet.Item = 7
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "INSERE"
        duolet.Item = 8
        v.Inserer(3, duolet)
       
        v.Retirer(3) 'MAISON
       
        taille = v.Taille
        NbElements = v.NbElements
       
        duolet = new __TDuolet
        duolet.key = "MAISON"
        duolet.Item = 9
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "BATEAU"
        duolet.Item = 10
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "MONTAGNE"
        duolet.Item = 11
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "FLEUR"
        duolet.Item = 12
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "SCOTCH"
        duolet.Item = 13
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "STYLO"
        duolet.Item = 14
        v.Ajouter(duolet)
       
        duolet = new __TDuolet
        duolet.key = "ETOILE"
        duolet.Item = 15
        v.Ajouter(duolet)
       
        taille = v.Taille
        NbElements = v.NbElements
       
        Erase v
End Sub


--
To unsubscribe e-mail to: [hidden email]
Problems? https://www.libreoffice.org/get-help/mailing-lists/how-to-unsubscribe/
Posting guidelines + more: https://wiki.documentfoundation.org/Netiquette
List archive: https://listarchives.libreoffice.org/global/users/
All messages sent to this list will be publicly archived and cannot be deleted
Jean-Francois Nifenecker Jean-Francois Nifenecker
Reply | Threaded
Open this post in threaded view
|

Re: Macros : ByVal doesn't work with parameters in a class object modul ...

Hi Patrick,

Le 06/01/2018 à 10:58, Patrick Gelin a écrit :

>
> Below is a complet macro to manage Vectors of variants (With french
> coments) . I've got a problem with unitary test (Cf. Sub Main) because
> call to procedure 'v.Ajouter(duolet)' use always passage by reference
> instead of a passage by value (ByVal) ! For all that, I delicately
> manage a passage by value in my function...
>
> I tested with a call to New operator in order to build specifics
> instances at each call, like this :
>
>     duolet = new __TDuolet
>     duolet.key = "MONTAGNE"
>     duolet.Item = 3
>     v.Ajouter(duolet)
>
> And it's fine, the duolet variable is a new one instance. But I don't
> want the caller do all this stuff. I would like easier way to do ...
>

This
     v.Ajouter(ByVal duolet)
won't do. The ByVal specifier is only present at the declaration level,
not the calling one.


You could just add a CreateDuolet() function to create the Duolets, like
this :

Function CreateDuolet(ByRef pKey As String, pItem As Variant) As __TDuolet

        Dim MyDuolet As __TDuolet

        MyDuolet.key = pKey
        MyDuolet.item = pItem

        CreateDuolet = MyDuolet

End Function

(note : this function is not a class member)

Then, the caller has just to specify:

duolet = CreateDuolet("MONTAGNE", 3)
v.Ajouter(duolet)

or you might also simply call
v.Ajouter(CreateDuolet("MONTAGNE", 3))


BTW, I've noticed some glitches elsewhere, eg: in the _Expend() method,
you've declared isPresserved as Optional but never test for its presence
or not in the method body. This might lead to strange results, don't you
think?
[BTW, BTW, shouldn't the method be called "_Expand" instead of "_Expend"?]


HTH,
--
Jean-Francois Nifenecker, Bordeaux


--
To unsubscribe e-mail to: [hidden email]
Problems? https://www.libreoffice.org/get-help/mailing-lists/how-to-unsubscribe/
Posting guidelines + more: https://wiki.documentfoundation.org/Netiquette
List archive: https://listarchives.libreoffice.org/global/users/
All messages sent to this list will be publicly archived and cannot be deleted