OVH Cloud OVH Cloud

Erreur passage de parametre UDT

2 réponses
Avatar
Zeg
Je me retrouve avec cette erreur sur le passage des paramètres
'TabAllocCanal' et 'LeFichier' , j'ai compris qu'il n'aimait que je lui
passe un UDT mais je tourne toujours autour de ce problème:

Seuls les types publics définis par l>utilisateur dans les modules objet
publics peuvent être utilisés comme paramètres ou types renvoyés pour les
procédures publiques des modules de classe ou comme champs des types publics
définis par l>utilisateur .

Cause et solution de cette erreur :
Vous avez tenté d'utiliser un type public défini par l'utilisateur comme
paramètre ou comme type renvoyé pour une procédure publique d>un module de
classe, ou comme champ d>un type public défini par l>utilisateur. Seuls les
types publics définis par l>utilisateur dans un module d>objet public
peuvent être utilisés de cette façon.

qu'est ce que ça veut dire?


J'ai une fonction dans un .cls d'un projet Dll/ActiveX :
Public Function RechercheDichoGen(Inf As Integer, Sup As Integer,
ContenantAs Variant, Element As Variant, Compare As String, LireContenu As
String,Objet As Object) As Integer

Do While Inf <= Sup

Dim milieu As Integer
milieu = Int((Inf + Sup) / 2)

If CallByName(Objet, Compare, VbMethod, Element, _
CallByName(Objet, LireContenu, VbMethod, Contenant,
milieu)) Then

Sup = milieu - 1
Else

Inf = milieu + 1
End If
Loop

MsgBox Inf
Rem Resultat
RechercheDichoGen = Inf

End Function

et je fais un appel à cette fonction dans un autre .cls d'un autre projet
Dll/ActiveX:

Public Type CanalFichier
Nom As String
Numero As Integer
End Type

Public TabAllocCanal(99) As CanalFichier
Dim LeFichier As CanalFichier

RechercheDichoGen(LBound(TabAllocCanal), FTAC - 1, TabAllocCanal,
LeFichier, "LowerOrEqual", "LireTab", Me)



L'idée est d'appliquer l'algo de recherche dichotomique sur tout type de
contenu et de contenant.
Et plus particulièrement sur le tableau déclaré précédement contenant des
éléments de type CanalFichier mais aussi sur des lignes dans un fichier
binaire.

ça fait un moment que j'essaye de m'approcher de l'idée de généricité mais
...
Merci d'avance

2 réponses

Avatar
Pascal B.
Bonjour, Zeg

Moi-même, je n'ai jamais vraiment compris ce que cela voulais dire ce message...
En tout-cas, on ne peut pas passer un UDT publique comme argument dans une fonction publique.

Alors, l'astuce est de remplacer "Public Function" par "Friend Function".
Ainsi, on peut passer des UDT et la fonction reste publique.

Pascal



"Zeg" wrote in message news:409aaa8f$0$18309$
| Je me retrouve avec cette erreur sur le passage des paramètres
| 'TabAllocCanal' et 'LeFichier' , j'ai compris qu'il n'aimait que je lui
| passe un UDT mais je tourne toujours autour de ce problème:
|
| Seuls les types publics définis par l>utilisateur dans les modules objet
| publics peuvent être utilisés comme paramètres ou types renvoyés pour les
| procédures publiques des modules de classe ou comme champs des types publics
| définis par l>utilisateur .
|
| Cause et solution de cette erreur :
| Vous avez tenté d'utiliser un type public défini par l'utilisateur comme
| paramètre ou comme type renvoyé pour une procédure publique d>un module de
| classe, ou comme champ d>un type public défini par l>utilisateur. Seuls les
| types publics définis par l>utilisateur dans un module d>objet public
| peuvent être utilisés de cette façon.
|
| qu'est ce que ça veut dire?
|
|
| J'ai une fonction dans un .cls d'un projet Dll/ActiveX :
| Public Function RechercheDichoGen(Inf As Integer, Sup As Integer,
| ContenantAs Variant, Element As Variant, Compare As String, LireContenu As
| String,Objet As Object) As Integer
|
| Do While Inf <= Sup
|
| Dim milieu As Integer
| milieu = Int((Inf + Sup) / 2)
|
| If CallByName(Objet, Compare, VbMethod, Element, _
| CallByName(Objet, LireContenu, VbMethod, Contenant,
| milieu)) Then
|
| Sup = milieu - 1
| Else
|
| Inf = milieu + 1
| End If
| Loop
|
| MsgBox Inf
| Rem Resultat
| RechercheDichoGen = Inf
|
| End Function
|
| et je fais un appel à cette fonction dans un autre .cls d'un autre projet
| Dll/ActiveX:
|
| Public Type CanalFichier
| Nom As String
| Numero As Integer
| End Type
|
| Public TabAllocCanal(99) As CanalFichier
| Dim LeFichier As CanalFichier
|
| RechercheDichoGen(LBound(TabAllocCanal), FTAC - 1, TabAllocCanal,
| LeFichier, "LowerOrEqual", "LireTab", Me)
|
|
|
| L'idée est d'appliquer l'algo de recherche dichotomique sur tout type de
| contenu et de contenant.
| Et plus particulièrement sur le tableau déclaré précédement contenant des
| éléments de type CanalFichier mais aussi sur des lignes dans un fichier
| binaire.
|
| ça fait un moment que j'essaye de m'approcher de l'idée de généricité mais
| ...
| Merci d'avance
|
|
Avatar
Zoury
Salut Zeg! :O)

ça fait un moment que j'essaye de m'approcher de l'idée de généricité mais



Regarde l'exemple suivant :

' description :
' 1 projets ActiveX Exe
' 1 Module standard
' 3 Modules de classes
'
'
'***
' Module1 - module
Option Explicit

Private Sub Main()

Dim so As CSearchLib
Dim canaux(9) As CCanalFichier
Dim canalRecherche As CCanalFichier
Dim i As Long

' popule notre tableau
For i = 0 To 9
Set canaux(i) = New CCanalFichier
canaux(i).Nom = Chr$(97 + i)
canaux(i).Numero = i
Next i

' instancie un autre objet utilisé pour la recherche
Set canalRecherche = New CCanalFichier
canalRecherche.Nom = "e"

' trouve l'index du canal e
Set so = New CSearchLib
Debug.Print so.DoDichotomicSearch(canalRecherche, canaux)
' devrait obtenir l'index 4

End Sub
'***
' IComparable - module de classe
Option Explicit

Function CompareTo(ByRef o As Object, Optional Compare As VbCompareMethod vbBinaryCompare) As Long
End Function
'***
' CSearchLib - module de classe
Option Explicit

Public Function DoDichotomicSearch(ByRef Obj As IComparable, ByRef Objects
As Variant) As Long

Dim lMid As Long
Dim lHi As Long
Dim lLow As Long
Dim lTop As Long
Dim objs() As IComparable

lLow = LBound(Objects)
lHi = UBound(Objects)

' on recast notre tableau en IComparable()
ReDim objs(lHi) As IComparable
objs = Objects

Do

lMid = lLow + Int((lHi - lLow + lTop) / 2)

Select Case Obj.CompareTo(objs(lMid))
Case 1 ' sFind > sItems(lMid)
lLow = lMid
If (lTop = 0) Then lTop = 1
Case -1 ' sFind < sItems(lMid)
lHi = lMid
Case 0 ' sFind = sItems(lMid)
Exit Do
End Select

If (lLow = lHi) Then ' non trouvé..
lMid = -1
Exit Do
End If

Loop

DoDichotomicSearch = lMid

End Function

Private Function IsArrayBounded(vntArray As Variant) As Boolean
On Error Resume Next
IsArrayBounded = IsNumeric(UBound(vntArray))
End Function
'***
' CCanalFichier - module de classe
Option Explicit

Implements IComparable

Private m_sNom As String
Private m_iNumero As Integer

Public Property Get Nom() As String
Nom = m_sNom
End Property

Public Property Let Nom(ByRef sNom As String)
m_sNom = sNom
End Property

Public Property Get Numero() As Integer
Numero = m_iNumero
End Property

Public Property Let Numero(ByRef iNumero As Integer)
m_iNumero = iNumero
End Property

Public Function IComparable_CompareTo(o As Object, Optional Compare As
VbCompareMethod = vbBinaryCompare) As Long
Dim cf As CCanalFichier

If (TypeOf o Is CCanalFichier) Then
Set cf = o
IComparable_CompareTo = StrComp(m_sNom, cf.Nom, Compare)
End If
End Function
'***


Implementant l'interface IComparable, tu t'assures que la classe qui
l'implémente possède une méthode nommé CompareTo() que tu peux utiliser dans
ta fonction de recherche. Tu pourras ainsi utilisé cette technique sur tous
les objets dont tu veux faire ce type de recherche..

ps : je poste le projet dans le message suivant

--
Cordialement
Yanick Lefebvre - MVP pour Visual Basic
http://faq.vb.free.fr/?rubrique=0 - http://www.mvps.org/vbnet/
http://www.mentalis.org/agnet/apiguide.shtml - http://www.mztools.com/