VBA, erreur : type d'argumentation Byref incompatible

cs_cecile64 Messages postés 15 Date d'inscription vendredi 15 juin 2012 Statut Membre Dernière intervention 17 août 2012 - 14 août 2012 à 17:04
xranto Messages postés 90 Date d'inscription mardi 6 octobre 2009 Statut Membre Dernière intervention 31 mars 2014 - 17 août 2012 à 13:01
bonjour à tous,
J'ai crée une userform qui demande à l'utilisateur de rentrer des parametre ( ici ce sera des dates). Je veux utiliser ces dates dans une subroutine MAIN() qui appelle une autre subroutine recup_euribor12m() (qui se sert de ces dates pour aller sur internet). Mon problème est que je n'arrive pas à utilier cette autre subroutine, j'ai un message d'erreur sur la variable date_versement: "nom ambigu détecté". Je ne vois pas pourquoi j'ai cette erreur alors que j'ai utilisé cette variable dans mon MAIN() pour autre chose...
est-ce que quelqu'un connait ce genre d'erreur et pourrait m'aider svp?

voici le code de mon userform :
date_versement = parametres.case_date_versement.Value
date_versement = Format(date_versement, "dd/mm/yyyy")

date_premiere_echeance = parametres.case_date_premiere_echeance.Value
date_date_premiere_echeance = Format(date_premiere_echeance, "dd/mm/yyyy")

date_emission = parametres.case_date_emission.Value
date_emission = Format(date_emission, "dd/mm/yyyy")

'choix de la périodicité
  
   If (choix1 = True) Then
    periodicite = 1
    ElseIf (choix2 = True) Then
    periodicite = 2
    ElseIf choix3 = True Then
    periodicite = 4
    ElseIf choix4 = True Then
    periodicite = 12
   End If
   



puis le code de mon main() :
Option Explicit
Public w, date_emission, date_versement, date_premiere_echeance, date_echeance_avant periodicite As Double

Public amortissement, tauxvar As String

Public tauxeuribor12m As Double
Public lienInternet As SHDocVw.InternetExplorer
Public pageInternet As MSHTML.HTMLDocument
Public leTaux As MSHTML.HTMLSpanElement
Public tauxWeb As String


'le userfom renvoie au MAIN
Sub MAIN()
 
 ThisWorkbook.Application.Visible = True
 
'début du code de la version précédente (modifié)
Dim feuil As Variant
Dim nomonglet As String

nomonglet = feuil.Name

    Dim n, i, j, nbre_echeances, duree_i, nbre_iterations, nbre_ech1, nbre_ech2, nbre_ech3 As Integer
    dim taux as double
    
    Dim date_avant, date_echeance, date_debut, date_fin As Date

nbre_echeances = nombre_echeances(duree_an, duree_mois, periodicite, x1) ' cette fonction marche
date_fin = DateAdd("m", Val(nbre_echeances * 12 / periodicite), date_versement)
 'sur le site, la date de début commence avec un an de décalage, donc on décale aussi
date_debut = DateAdd("m", Val(-12 / periodicite), date_versement)
'MsgBox "la date de début est  " & (date_debut)

 Call RecupEuribor12M.recup_euribor12m


et ma subroutine recup_euribor12m() :
Option Explicit
Public date_emission, date_versement, periodicite, nbre_echeances As Double

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub recup_recup_euribor12m()
'Déclaration des variables
Dim IE As New InternetExplorer
Dim pageInternet As Object
Dim login, motDePasse As Object
Dim InputGoogleBouton As Object
Dim lesEntrees As Object
Dim CasedateCotation As Object
Dim i As Integer
Dim dateCotation As String
Dim selectionTaux As Object
Dim CasedateDebut As Object
Dim CasedateFin As Object
Dim boutonPeriodicite As Object
Dim boutonValider As Object
Dim cadreValider As Object
Dim date_debut, date_fin As Date
Dim date_versement_bis As Date

date_versement_bis = date_versement
'ByVal dateEmission As Date, dateDebut As Date, dateFin As Date) As Double 'rajouter la périodicité en parametre
date_fin = DateAdd("m", Val(nbre_echeances * 12 / periodicite), date_versement_bis)
'sur webdette, la date de début commence avec un an de décalage, donc on décale aussi
date_debut = DateAdd("m", Val(-12 / periodicite), date_versement_bis)
    'MsgBox "la date de début est  " & (date_debut)

'on verifie que la valeur du paramatre est bien une date
    If IsDate(date_emission) = True Then
        
        'c'est une date donc on la converti au format attendu
        dateCotation = Format(CDate(date_emission), "dd/mm/yyyy")
        date_debut = Format(CDate(date_debut), "dd/mm/yyyy")
        date_fin = Format(CDate(date_fin), "dd/mm/yyyy")
    Else 'ce n'est pas une date
        MsgBox "le parametre n'est pas une date  "
        Exit Sub
    End If

 
   'Chargement d'une page web Google
   IE.navigate "https://www.seldon-finance.com/seldon/login.html"
  
   'Affichage de la fenêtre IE
   IE.Visible = True
   
    'On attend le chargement complet de la page
  ' WaitIE IE
Sleep 5000
   'On pointe le membre Document
   Set pageInternet = IE.Document
   
   'AGIR SUR UN BOUTON
'On pointe notre login
Set login = pageInternet.getElementById("IdWebDette")

'On définit le texte que l'on souhaite placer à l'intérieur
login.Value = "chubert"

'On pointe notre mot de passe
Set motDePasse = pageInternet.getElementById("txtPwd_WebDette")

'On définit le texte que l'on souhaite placer à l'intérieur
motDePasse.Value = "baichah2"

'on se connecte a l'espace privé webdette
IE.navigate "https://webdette.seldon-finance.com/WebDette/esp_public/login"
   Sleep 5000
  'on va dans données de marché -> Visu. Taux Fututrs
   IE.navigate " https://webdette.seldon-finance.com/WebDette/esp_privat/visutauxfutur"
    
   Sleep 5000
   
Set pageInternet = IE.Document
    'récupération des objets "input"
    Set lesEntrees = pageInternet.getElementsByTagName("input")
    'on boucle pour retrouver le champ date de la form
    For i = 0 To lesEntrees.Length - 1
        'pour la recherche on utilise l'ID
        If lesEntrees(i).ID = "date_cotation" Then
            'le WaitIE plus haut ne suffit pas à garantir que la page à pris en compte la nouvelle valeur de date
            'on vas donc boucler pour verifier
            Do
                lesEntrees(i).Value = dateCotation
                Application.Wait Now + TimeValue("0:00:01")
                DoEvents
            Loop Until lesEntrees(i).Value = dateCotation
            Exit For
        End If
    Next

   
   'On va sur l'objet qui contient la liste des indices
   Set selectionTaux = pageInternet.all("codeTaux1")
   'On sélectionne l'indice "EURIBOR12M" via sa valeur unique
   selectionTaux.Value = "EURIBOR12M"
   
   'on prend la date de la premiere échéance
   Set CasedateDebut = pageInternet.getElementById("date_deb")
   CasedateDebut.Value = "01/01/2012" 'mettre dateDebut a la place
   
   'on prend la date de la dernière échéance
   Set CasedateFin = pageInternet.getElementById("date_fin")
   CasedateFin.Value = "01/01/2020" ' mettre dateFin a la place
   
   'on choisi la periodicité
   Set lesEntrees = pageInternet.getElementsByTagName("input")
    'on boucle pour retrouver le champ date de la form
    For i = 0 To lesEntrees.Length - 1
        'pour la recherche on utilise l'ID
        If lesEntrees(i).Value = "12" Then
            'le WaitIE plus haut ne suffit pas à garantir que la page à pris en compte la nouvelle valeur de date
            'on vas donc boucler pour verifier
            Do
                Set boutonPeriodicite = lesEntrees(i)
                boutonPeriodicite.setAttribute "checked", True
                Application.Wait Now + TimeValue("0:00:01")
                DoEvents
            Loop Until lesEntrees(i).Value = "12"
            Exit For
        End If
    Next
Sleep 3000

' on appuie sur le bouton valider

pageInternet.forms(0).submit
    
   
    

   'On libère les variables
   Set IE = Nothing
   Set lesEntrees = Nothing
   Set pageInternet = Nothing
   
End Sub


Sub WaitIE(IE As InternetExplorer)

   'On boucle tant que la page n'est pas totalement chargée
   Do Until IE.readyState = READYSTATE_COMPLETE
      DoEvents
   Loop
End Sub


3 réponses

ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
14 août 2012 à 17:28
Bonjour,
1) déjà : on ne peut déclarer publique la même variable en deux endoits différents (c'est par exemple et entre autres le cas de ta variable date_emission) !
2) par ailleurs , sous VB :
Public w, date_emission, date_versement, date_premiere_echeance, date_echeance_avant periodicite As Double

fait que seule date_echeance_avant_périodicité est typé en double (tout le reste sera en variant par défaut ).
!
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
cs_cecile64 Messages postés 15 Date d'inscription vendredi 15 juin 2012 Statut Membre Dernière intervention 17 août 2012 1
17 août 2012 à 12:06
J'ai modifié ma fonction en sub après l'avoir améliorée, mais je rencontre encore un probleme : quand je teste un Call RecupEuribor12M.RECUP_EURIBOR12M(nbre_echeances, dateEmission), avec la sub ci-dessous, ca marche nickel, mais quand je rajoute2 variables dates : Call RecupEuribor12M.RECUP_EURIBOR12M(nbre_echeances, dateEmission, date_echeance, date_fin) j'ai une erreur "Type d'argument ByRef incompatible " pour ma variable date_echeance ( j'en aurai surement une aussi pour date_fin apres...). ce que je ne comprends pas, c'est que j'utilise date_echeance pour d'autres fonctions et ca marche, alors soit je ne comprends pas le passage de variables d'un userform à une sub, soit il y a une erreur de syntaxe que je ne vois pas du tout....
je vous remet mon main, le userform n'a pas changé :
Option Explicit
Public w, date_emission, date_versement, date_premiere_echeance, periodicite As Double

Public amortissement, tauxvar As String

Public lienInternet As SHDocVw.InternetExplorer
Public pageInternet As MSHTML.HTMLDocument
Public leTaux As MSHTML.HTMLSpanElement
Public tauxWeb As String

Private Sub workbook_open()

'pour masquer la feuille excel tant que les parametres ne sont pas saisis
Recalcul.Show
'parametres.Show
ThisWorkbook.Application.Visible = False

'afficher le userform

End Sub

'le userfom renvoie au MAIN
Sub MAIN()
 
 ThisWorkbook.Application.Visible = True
 
'début du code de la version précédente (modifié)
Dim feuil As Variant
Dim nomonglet As String

 'Message box
'base_TEG = InputBox(vbCrLf & vbCrLf & "quelle base pour le TEG?")
'base_TEG = CDbl(Val(base_TEG))


For Each feuil In Worksheets

dim x1 as double

   If feuil.Name = "TEG" Then
    nomonglet = feuil.Name

    Dim n, i, j, nbre_echeances As Integer
    
    Dim date_avant, date_echeance, date_debut, date_fin, dateEmission As Date
    
    
 'nom de la feuille recup correspondante à nomonglet
  Sheets(nomonglet).Select
 
 'on insere les parametres dans les celulles
  Sheets(nomonglet).Cells(6, 4) = montant
  Sheets(nomonglet).Cells(2, 5) = frais
  
  
  'Sheets(nomonglet).Cells(6, 3) = taux / 100
  Sheets(nomonglet).Cells(2, 8) = TEG_banque / 100
  Sheets(nomonglet).Cells(3, 8) = base_interets
  Sheets(nomonglet).Cells(6, 2) = date_versement
  Sheets(nomonglet).Cells(7, 2) = date_premiere_echeance
  
 Sheets(nomonglet).Cells(3, 3) = base_interets
 
 ' initialisation
x1 = DateDiff("m", date_versement, date_premiere_echeance)
    nbre_echeances = nombre_echeances(duree_an, duree_mois, periodicite, x1)

    date_avant = date_versement
    date_echeance = date_premiere_echeance
    date_fin = DateAdd("m", Val(nbre_echeances * 12 / periodicite), date_avant)

    'sur webdette, la date de début commence avec un an de décalage, donc on décale aussi
    date_debut = DateAdd("m", Val(-12 / periodicite), date_avant)

    'MsgBox "la date de début est  " & (date_debut)
    dateEmission = date_emission ' ca ca marche

 'si on est en taux variable, on va chercher le taux sur le site
If w = 5 Then
   Select Case (tauxvar)
    Case "euribor12m":
        Call RecupEuribor12M.RECUP_EURIBOR12M(nbre_echeances, dateEmission, date_echeance, date_fin)
'la suite n'a pas d'importance...


et ma sub qui est appelée :
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Sub RECUP_EURIBOR12M(nbre_echeances As Variant, dateEmission As Date, date_debut As Date, date_fin As Date)
'Déclaration des variables
Dim IE As New InternetExplorer
Dim pageInternet As Object
Dim login, motDePasse As Object
Dim lesEntrees As Object
Dim i, j, k As Integer
Dim selectionTaux As Object
Dim dateCotation, dateDebut, dateFin As Object
Dim boutonPeriodicite As Object
Dim Ligne, cellule As Object
Dim tauxWeb, taux As String
Dim EUR12M As Double
Dim Tableau As Object
Dim dateEmission2, dateDebut2, dateFin2 As String

'on converti les dates en type string
dateEmission2 = Format(CDate(dateEmission), "dd/mm/yyyy")
dateDebut2 = Format(CDate(date_debut), "dd/mm/yyyy")
dateFin2 = Format(CDate(date_fin), "dd/mm/yyyy")

   'Chargement d'une page web Google
   IE.navigate "https://www.seldon-finance.com/seldon/login.html"

   'Affichage de la fenêtre IE
   IE.Visible = True
   
    'On attend le chargement complet de la page
  ' WaitIE IE
    Sleep 5000
   'On pointe le membre Document
   Set pageInternet = IE.Document
   
   'AGIR SUR UN BOUTON
'On pointe notre login
Set login = pageInternet.getElementById("IdWebDette")

'On définit le texte que l'on souhaite placer à l'intérieur
login.Value = "identifiant"

'On pointe notre mot de passe
Set motDePasse = pageInternet.getElementById("txtPwd_WebDette")
'On définit le texte que l'on souhaite placer à l'intérieur
motDePasse.Value = "mdp"

'on se connecte a l'espace privé webdette

   Sleep 10000
   
'IE.navigate "ttps://webdette.seldon-finance.com/WebDette/esp_privat/relationclientconseillerliste"
   
  'on va dans données de marché -> Visu. Taux Fututrs
   IE.navigate " https://webdette.seldon-finance.com/WebDette/esp_privat/visutauxfutur"
   Sleep 5000
   
Set pageInternet = IE.Document
   
   'on rentre la date de cotation
   Set dateCotation = pageInternet.getElementById("date_cotation")
   dateCotation.Value = dateEmission2
   
   'On va sur l'objet qui contient la liste des indices
   Set selectionTaux = pageInternet.all("codeTaux1")
   'On sélectionne l'indice "EURIBOR12M" via sa valeur unique
   selectionTaux.Value = "EURIBOR12M"
   
   'on prend la date de la premiere échéance
   Set dateDebut = pageInternet.getElementById("date_deb")
   dateDebut.Value = dateDebut2
   
   'on prend la date de la dernière échéance
   Set dateFin = pageInternet.getElementById("date_fin")
   dateFin.Value = dateFin2
   
   'on choisi la periodicité
   Set lesEntrees = pageInternet.getElementsByTagName("input")
    'on boucle pour retrouver le champ date de la form
    For i = 0 To lesEntrees.Length - 1
        'pour la recherche on utilise l'ID
        If lesEntrees(i).Value = "12" Then
            'le WaitIE plus haut ne suffit pas à garantir que la page à pris en compte la nouvelle valeur de date
            'on vas donc boucler pour verifier
            Do
                Set boutonPeriodicite = lesEntrees(i)
                boutonPeriodicite.setAttribute "checked", True
                Application.Wait Now + TimeValue("0:00:01")
                DoEvents
            Loop Until lesEntrees(i).Value = "12"
            Exit For
        End If
    Next
Sleep 3000

' on appuie sur le bouton valider

pageInternet.forms(0).submit
    
   Sleep 3000
 ' il y a un changement de page
 Set pageInternet = IE.Document

    'récupération des objets "tr"
    Set Tableau = pageInternet.getElementsByTagName("table")
    For j = 1 To (Tableau.Length - 1)
        Range("a" & j + 1).Value = Tableau(i).className
       If Tableau(j).className = "listeContrats" Then
            
          For k = 1 To nbre_echeances
            'le taux
            Set Ligne = Tableau(j).Rows(k)
            Set cellule = Ligne.Cells(1)
            tauxWeb = cellule.innerText
            taux = Replace(tauxWeb, ",", ".")
            EUR12M = CDbl(Val(taux))
            'MsgBox tauxWeb, Title:="Le taux vaut"
            Sheets("TEG").Cells(k + 6, 3).Value = EUR12M / 100
          Next
        Exit For
        End If
      Next
   
   ' objtIE.Quit
    Set lesEntrees = Nothing


   'On libère les variables
   Set IE = Nothing
   Set pageInternet = Nothing
   
End Sub


Sub WaitIE(IE As InternetExplorer)

   'On boucle tant que la page n'est pas totalement chargée
   Do Until IE.readyState = READYSTATE_COMPLETE
      DoEvents
   Loop
End Sub






la deuxieme sub marche tres bien sans arguments ( quand je rentre directement des valeurs aux variables), dc je pense que ce n'est pas elle le pb...
C'est plutot mon main qui a des soucis...

Merci pour votre aide.
0
xranto Messages postés 90 Date d'inscription mardi 6 octobre 2009 Statut Membre Dernière intervention 31 mars 2014
17 août 2012 à 13:01
Bonjour,

Je pense que t'as pas compris ce que ucfoutu voulait dire.

L'équivalence de :
Dim date_avant, date_echeance, date_debut, date_fin, dateEmission As Date


est :
Dim date_avant As Variant 
Dim date_echeance As Variant
Dim date_debut As Variant
Dim date_fin As Variant
Dim dateEmission As Date


Et donc ce que tu dois faire c'est :
Dim date_avant As Date, date_echeance As Date, date_debut As Date, date_fin As Date, dateEmission As Date


Il faut que tu révises bien ton code. Il y un tat de ce genre de déclaration dedans.
0
Rejoignez-nous