enregistrer references VBA definitif

herve62

XLDnaute Barbatruc
Supporter XLD
Bonjour
Je n'ai pas trouvé comment , ou si on peut ? , enregistrer définitivement les références ajoutées de VBA
exemple ; j'ai ajouté Outlook pour l'envoi mail
SI je reprends l'appli dans un nouveau fichier excel : ça plante ..outlook n'est pas coché
Merci
 

david84

XLDnaute Barbatruc
Re : enregistrer references VBA definitif

Bonsoir,

c'est le même principe que celui que j'ai expliqué antérieurement :
- déclarer les variables objet en Object
- instancier l'objet via un CreateObject

Donc dans ton cas (et sans avoir pu tester car c'est une fonction qui demande des arguments pour fonctionner) :
remplacer
Code:
Dim Ouvrage As New Scripting.Dictionary
Dim PosteDirect As New Scripting.Dictionary
par
Code:
Dim Ouvrage As Object
Dim PosteDirect As Object 
 
Set Ouvrage = CreateObject("Scripting.Dictionary")
Set PosteDirect = CreateObject("Scripting.Dictionary")

Et là pas besoin d'activer la référence Microsoft Scripting Runtime.

Le fait de déclarer les objets en early binding (avec obligation de cocher les bibliothèques adéquates) est utile en phase de développement car cela te permet de connaître les propriétés et méthodes de l'objet, de bénéficier de l'auto complétion, etc.
Une fois le code au point, si la portabilité du fichier doit être assurée afin qu'il puisse fonctionner sur d'autres postes qui peuvent être de surcroît équipés de versions différentes d'Excel, la déclaration tardive (late binding) est plus simple : le but pour l'utilisateur ne va pas être d'aller voir le code, il veut simplement que le code fonctionne sans encombre.

C'est pourquoi je ne comprends pas l'intérêt de vouloir à tout prix cocher la référence recherchée via VBA pour assurer la portabilité d'un fichier alors qu'un CreateObject fait le travail...peut-être qu'il y a une réelle plus-value à le faire mais j'attends qu'on me l'explique.

A+
 

Modeste geedee

XLDnaute Barbatruc
Re : enregistrer references VBA definitif

Bonsour®
C'est pourquoi je ne comprends pas l'intérêt de vouloir à tout prix cocher la référence recherchée via VBA pour assurer la portabilité d'un fichier alors qu'un CreateObject fait le travail...peut-être qu'il y a une réelle plus-value à le faire mais j'attends qu'on me l'explique.

A+

peut être là :


ou bien :
Early vs. Late Binding
 

david84

XLDnaute Barbatruc
Re : enregistrer references VBA definitif

Bonjour,

je connais ces arguments et comme je l'ai dit dans la phase de développement je privilégie bien entendu la liaison anticipée mais là on parle bien de la nécessité d'assurer la portabilité d'un fichier susceptible de fonctionner sur différents ordinateurs.

On a donc deux possibilités par programmation :
- soit on veut rester en liaison anticipée et donc il faut via VBA pouvoir ajouter la ou les bibliothèques nécessaires.
Mais pour que cela fonctionne il faut préalablement récupérer soit le guide, soit le chemin complet de la bibliothèque...afin de l'inclure dans le code !
Et en plus il faut prévoir les différents cas de figure en fonction des versions d'Excel susceptibles d'être installées sur les différents ordinateurs, sans compter que lors du passage à une autre version d'Office, il faudra revenir sur le code.
Avouez que ce n'est pas simple !

- soit déclarer les variables objet en liaison tardive via un CreateObject.

Etant donné que l'on a affaire à des utilisateurs qui la plupart du temps ne connaissent pas grand chose voir rien du tout à la programmation (car sinon ils seraient capables eux-même d'aller cocher les bibliothèques manquantes si nécessaire) et le fait que cette procédure ne peut fonctionner qu'après s'être assuré que les guides/chemins soient bien les bons (donc potentiellement différents en fonction des versions), personnellement mon choix a rapidement été fait.

Quant au fait que le code s'exécute plus rapidement via une liaison anticipée, d'accord sur le principe mais jusqu'à présent je n'ai jamais vu une application ramer avec des déclarations faites en liaison tardive et qui se mettrait à fonctionner rapidement uniquement par le fait d'un passage en liaison anticipée.

A+
 

cathodique

XLDnaute Barbatruc
Re : enregistrer references VBA definitif

Bonjour Modeste geedee, David84, Herve62, le Forum,

Je vous remercie beaucoup pour votre aide. J'espère que Herve62 trouve la meilleure solution à son problème.

Merci à toi, c'est un peu grâce à ton fil que je me suis remis au boulot pour aider mon ami.

@Modeste geedee: merci pour le lien (surtout le traduit), j'ai compris les avantages et inconvénients des 2 méthodes.

@David84: c'est exactement comme tu me le préconises que j'ai modifié le code. Hélàs, j'ai l'erreur d’exécution 451:

"La procédure property Let n'est pas définie et La procédure property Get n'a pas renvoyé d'objet".

Voici le fichier sans données confidentielles, personnellement je n'ai pas compris pourquoi j'ai cette erreur.

Un grand merci en espérant que ça servira à d'autres. Surtout à Herve62, initiateur de ce fil.

Bon week-end.
 
Dernière édition:

david84

XLDnaute Barbatruc
Re : enregistrer references VBA definitif

Bonjour,

N'étant pas à la base informaticien et encore moins développeur...
Rassure-toi, moi non plus !
Ton exemple est très intéressant : effectivement cela plante en liaison tardive...essaie comme cela, toujours en liaison tardive, et dis-moi (je t'ai indiqué les modifications dans le code) :
Code:
Option Explicit

Sub Traitement()
Dim Lastlig As Long
Dim Tb, Tablo, Tp
Dim Ind As Byte
 
Application.ScreenUpdating = False
With Worksheets("BD")
    'Dernière ligne remplie de la colonne 1
    Lastlig = .Cells(.Rows.Count, 1).End(xlUp).Row
    'On récupère les données dans une variable tableau Tb
    Tb = .Range("A2:J" & Lastlig)
End With
 
'Ici on supprime les feuilles Beta et Delta (si elles existent)
Tp = Array("Beta", "Delta")
 
Application.DisplayAlerts = False
On Error Resume Next
Worksheets(Tp).Delete
On Error GoTo 0
Application.DisplayAlerts = False
 
'Pour chaque valeur du tableau Tp (Beta ou Delta) on ajoute une feuille qu'on nomme et dans laquelle on transfère les résultats escomptés
'à l'aide de la fonction Dispatch (expliquée ci-après)
For Ind = 0 To 1
    Tablo = Dispatch(Tb, Tp(Ind))
    With Worksheets.Add
        .Name = UCase(Tp(Ind))
        .Range("A1") = Tp(Ind)
        .Range("A7").Resize(UBound(Tablo, 1), UBound(Tablo, 2)) = Tablo
        .Range("A9").Resize(UBound(Tablo, 1) - 2, UBound(Tablo, 2)).Sort Key1:=.Range("A4"), order1:=xlAscending, Header:=xlNo
    End With
Next Ind
End Sub
 

Private Function Dispatch(ByVal Tb, ByVal Typ As String)
Dim Ouvrage As Object
Dim PosteDirect As Object
Dim C As Integer, m As Integer, R As Integer, n As Integer
Dim p As Integer, i As Integer, j As Integer, k As Long
Dim Res(), Tmp, Vemp

Set Ouvrage = CreateObject("Scripting.Dictionary")
Set PosteDirect = CreateObject("Scripting.Dictionary")
 
'p: nombre de valeurs de la feuille BD
p = UBound(Tb, 1)
 
'=====================================
'Ici, à l'aide de 2 dictionnaires, on récupère les valeurs sans doublons et avec comme valeur de la colonne 2 la donnée paramètre Typ (qui sera Delta ou Beta):
'1. Dans le dictionnaire Ouvrage, tous les ouvrages différents de la colonne 3 (Colonne C)
'2. Dans le dictionnaire PosteDirect, tous les les postes concaténé aux direction colonne 4 (D) et colonne 9 (I)
For i = 1 To p
    If Tb(i, 2) = Typ Then
        Ouvrage(Tb(i, 3)) = ""
        PosteDirect(Tb(i, 4) & "|" & Tb(i, 9)) = ""
    End If
Next i
'=====================================
'C: Nombre d'ouvrages trouvés pour Type=typ
C = Ouvrage.Count
'm le nombre de colonnes, chaque ouvrage a 2 colonnes + 5 colonnes pour Poste, redresseur x 2 + direction + observations
m = 5 + 2 * C
'R: Nombre de combinaisons Poste/Direction trouvées pour Type=Typ
R = PosteDirect.Count
'n: nombre de lignes = R + 2 lignes entête
n = 2 + R
 
'On dimensionne notre tableau Resultat nommé Res de N lignes et m colonnes
ReDim Res(1 To n, 1 To m)
 
'on remplit les entêtes fixes (lignes 1 et 2)
Res(1, 1) = "N°Poste Localisation"
Res(1, 2) = "Redresseur"
Res(1, 3) = "Redresseur"
Res(2, 2) = "Tension (V)"
Res(2, 3) = "Courant (A)"


'=========== Modification =========================================
Dim tempOuvrage
Dim tempPosteDirect
tempOuvrage = Ouvrage.Keys
tempPosteDirect = PosteDirect.Keys
'==================================================================


'on remplit les entêtes variables correspondant aux ouvrages (chaque ouvrage et répété 2 fois)
For j = 0 To 2 * C - 1
    k = Int(j / 2)
    Res(1, j + 4) = tempOuvrage(k) 'Res(1, j + 4) = Ouvrage.Keys(k)
    Res(2, 2 * k + 4) = "Potentiel (mV)"
    Res(2, 2 * k + 5) = "Courant (mA)"
Next j


'on remplit les entêtes des 2 dernières colonnes
Res(1, m - 1) = "Direction"
Res(1, m) = "Observations (" & Typ & ")"
 
'Ici, on remplit pour chaqque cellule de notre tableau les données correspondantes
For i = 3 To n
'Dans la variable tableau Vemp on scinde notre combinaison Poste|Direction


    
    Vemp = Split(tempPosteDirect(i - 3), "|") 'Vemp = Split(PosteDirect.Keys(i - 3), "|")
    'La première colonne de Res correspond au poste
    Res(i, 1) = Vemp(0)
    ' et l'avant dernière colonne correspond à la direction
    Res(i, m - 1) = Vemp(1)
    'ici on pracours pour chaque ligne i toutes les colonnes sauf la première et les 2 dernières
    For j = 4 To m - 2 Step 2
        k = Int((j - 4) / 2)
        'la fonction Synthese est expliquée plus bas
        
        Tmp = Synthese(Tb, Typ, Vemp(1), tempOuvrage(k), Res(i, 1)) 'Tmp = Synthese(Tb, Typ, Vemp(1), Ouvrage.Keys(k), Res(i, 1))
        If Res(i, 2) = "" Then Res(i, 2) = Tmp(0)
        If Res(i, 3) = "" Then Res(i, 3) = Tmp(1)
        Res(i, j) = Tmp(2)
        Res(i, j + 1) = Tmp(3)
        Res(i, m) = Res(i, m) & "" & Tmp(5)
    Next j
Next i
 
Set Ouvrage = Nothing
Set PosteDirect = Nothing
Dispatch = Res
End Function
 
'Ici cette fonction fait la synthèse du tableau initial Tb (corespondant à la feuille BD)
'Pour chaque Type, chaque Direction,chaque ouvrage et chaque poste, récupèrer les informations suivantes
'Tension     Courant     Potentiel   Courant_Inj Direction   Observation
 
Private Function Synthese(ByVal Tb, ByVal Typ As String, ByVal Dire As String, ByVal Ouv As String, ByVal Post As String)
Dim Tablo(0 To 5)
Dim i As Integer
Dim t As Byte
 
For i = 1 To UBound(Tb, 1)
    If Tb(i, 2) = Typ And Tb(i, 3) = Ouv And Tb(i, 4) = Post And Tb(i, 9) = Dire Then
        For t = 0 To 5
            Tablo(t) = Replace(Tb(i, 5 + t), Chr(10), " ")
        Next t
        Exit For
    End If
Next i
Synthese = Tablo
End Function

A+
 

cathodique

XLDnaute Barbatruc
Re : enregistrer references VBA definitif

Bonjour,

Je connais une personne qui va être très contente. Mon ami sera ravi que la petite appli refonctionne normalement.

Je te suis très reconnaissant. Tes modifications ont pile poil fait fonctionner le code convenablement.

Je t'avoue que je n'aurais jamais trouvé la solution. J'ai juste compris que tu as déclaré 2 variables tableau (array) auxquels tu as affecté des dictionnaires.

N'étant pas très à l'aise avec les variables tableaux et encore moins avec les dictionnaires. Je n'ai pas vraiment compris pourquoi ça fonctionne bien.

En tous les cas, je te dis un grand Bravo. Tu n'es pas un Barbatruc pour rien.

Bon week-end.
 

david84

XLDnaute Barbatruc
Re : enregistrer references VBA definitif

Content que cela te convienne.
Quand je disais dans le message précédent que ton exemple était intéressant c'est parce que je trouve bizarre le fait que la syntaxe Dictionaire.Keys(i) fonctionne. En effet lorsque je regarde la description de la méthode Keys (d'où l'intérêt d'utiliser une liaison anticipée en phase de développement), je lis bien qu'elle permet d'obtenir un tableau contenant toutes les clés du dictionnaire. Elle n'est d'ailleurs pas décrite comme pouvant être utilisée avec un argument comme c'est le cas dans ton code.
Or c'est vrai que cela fonctionne mais je ne pense pas que cela soit une manière correcte de l'utiliser et peut-être que c'est pour cela qu'elle n'est pas supportée en liaison tardive (je dis bien peut-être !).

A+
 

herve62

XLDnaute Barbatruc
Supporter XLD
Re : enregistrer references VBA definitif

Bonjour à tous .. en ce triste jour !
Un grand merci en espérant que ça servira à d'autres. Surtout à Herve62, initiateur de ce fil.
Tu sais Cathodique , j'y suis pas pour grand chose juste que j'ai la fibre technique et hyper curieux donc aussi j'aime savoir ce que / pourquoi , je fais ça ou ça !
En fait comme j'aide Bcp de monde pas souvent spécialistes , j'ai pas mal de retours
dont celui ci avec Outlook , Pb qui s'avère chez moi aussi , et encore je ne parle pas du CALENDAR avec 2010 dans l'appli en cours pour mon camarade ... il pleure encore !, mais je pense que c'est du même acabit . On va faire un Sype ou Teamviewer que je comprenne pourquoi chez lui ça marche pas ? ( avec 2010) et que moi oui ( avec 2007)
Enfin , content que ce Fil ait intéressé
Bon WE
 

Discussions similaires

Statistiques des forums

Discussions
312 859
Messages
2 092 921
Membres
105 564
dernier inscrit
Mika1979