2010-03-27 7 views
4

Je travaille sur un complément Excel orienté objet pour extraire des informations de la base de données de notre système ERP. Voici un exemple d'un appel de fonction:Fonction renvoyant une classe contenant une fonction renvoyant une classe

itemDescription = Macola.Item("12345").Description

Macola est une instance d'une classe qui prend en charge l'accès aux bases de données. Item() est une fonction de la classe Macola qui renvoie une instance d'une classe ItemMaster. Description() est une fonction de la classe ItemMaster. Tout cela fonctionne correctement.

Les articles peuvent être être stockés dans plus d'un endroit, donc mon étape suivante consiste à faire:

quantityOnHand = Macola.Item("12345").Location("A1").QuantityOnHand

Emplacement() est une fonction de la classe ItemMaster qui renvoie une instance de la ItemLocation classe (enfin, en théorie de toute façon). QuantityOnHand() est une fonction de la classe ItemLocation. Mais pour une raison quelconque, la classe ItemLocation n'est même pas en cours d'initialisation.

Public Function Location(inventoryLocation As String) As ItemLocation 
    Set Location = New ItemLocation 
    Location.Item = item_no 
    Location.Code = inventoryLocation 
End Function 

Dans l'exemple ci-dessus, la variable item_no est une variable membre de la classe ItemMaster.

Bizarrement, je peux instancier avec succès la classe ItemLocation en dehors de la classe ItemMaster dans un module non-classe.

Dim test As New ItemLocation 
test.Item = "12345" 
test.Code = "A1" 
quantityOnHand = test.QuantityOnHand 

Y a-t-il un moyen de faire ce travail comme je le souhaite? J'essaie de garder l'API aussi simple que possible. Alors qu'il suffit d'une ligne de code pour récupérer une valeur.

+1

Je sais que c'est un exemple de code destiné à montrer un problème, donc vous pouvez déjà être au courant, mais ceux qui ne le sont pas devraient Google la "loi de Demeter" ... – jtolle

+0

Comment savez-vous que ".. pour une raison quelconque, la classe ItemLocation n'est même pas en cours d'initialisation. " ?? – RBarryYoung

+0

@jtolle - Je n'ai rien caché ici. Je ai googlé "Loi de Demeter", mais je ne sais pas ce que vous considérez problématique de mon code? @RBarryYoung - J'ai du code dans la classe Class_Intialize de la classe ItemLocation pour imprimer un message de débogage. Aucun message = aucun init. – Scott

Répondre

1

Chaque fois que votre fonction fait référence à Location, elle crée une nouvelle ItemLocation (car elle rappelle la fonction, de manière récursive), à ​​ce qu'il semble. Peut-être que vous avez besoin d'isoler le ItemMaster intérieur de la fonction, comme celui-ci

Public Property Get Location(inventoryLocation As String) As ItemLocation 

    Dim clsReturn As ItemLocation 

    Set clsReturn = New ItemLocation 

    clsReturn.Item = "item_no" 
    clsReturn.Code = inventoryLocation 

    Set Location = clsReturn 

End Property 

Je ne sais pas pourquoi vous utilisez une fonction au lieu d'une propriété, mais si vous avez une bonne raison, je suis sûr que vous pouvez adapter ce. Je ne pouvais pas non plus comprendre d'où venait item_no, donc j'ai fait une chaîne.

+0

Je pense que votre solution est presque exactement comme la mienne.J'ai reconnu le même problème, mais apparemment cela n'a pas aidé: -/ –

+0

Je pense que vous voulez dire "crée un nouvel ItemLocation", pas "ItemMaster" ... – jtolle

+0

Right Ben. Je jure que j'ai lu toutes les autres réponses avant de poster, mais de toute évidence je ne l'ai pas fait. Correct jtolle. –

1

Vous pouvez essayer de séparer la déclaration et l'instanciation des objets dans votre code VBA. Je voudrais également créer une variable d'objet locale à la fonction et la renvoyer à la fin. Essayez ceci:

Public Function Location(inventoryLocation As String) As ItemLocation 
    Dim il As ItemLocation  'Declare the local object ' 
    Set il = New ItemLocation  'Instantiate the object on a separate line ' 
    il.Item = item_no 
    il.Code = inventoryLocation 
    Set Location = il    'Return the local object at the end ' 
End Function 

Je ne sais pas si cela est ce qui a causé le problème, mais je me souviens avoir lu que VB6/VBA a un problème avec la déclaration et instanciation d'un objet sur la même ligne de code. Je sépare toujours mon Dim de mon Set en VBA en deux lignes.

+0

Merci pour la suggestion. Cela n'a fait aucune différence, cependant. – Scott

1

Je ne peux pas sembler reproduire ceci, mais laissez-moi signaler ce que j'ai fait et peut-être cela vous aidera à trouver votre problème.

Voici le code pour Class1:

Public Function f() As Class2 
    Set f = New Class2 
    f.p = 42 
End Function 

et est ici le code pour Classe2:

Private p_ 

Public Property Let p(value) 
    p_ = value 
End Property 

Public Property Get p() 
    p = p_ 
End Property 

Private Sub Class_Initialize() 
    Debug.Print "Class 2 init" 
End Sub 

Private Sub Class_Terminate() 
    Debug.Print "Class 2 term" 
End Sub 

Si je vais à la fenêtre immédiate et entrez:

set c1=new Class1 

puis

?c1.f().p 

Je reviens:

Class 2 init 
42 
Class 2 term 

Ainsi, une instance de la classe 2 est créé, il est bien « p » s'écrit et lu, mais VBA il tue après cette ligne exécute, car aucune variable a une référence à cette exemple.

Comme je l'ai dit, cela ne correspond pas à votre problème tel que décrit. Il me manque probablement quelque chose dans les détails, mais j'espère que cela aidera.

EDIT:

Pour clarifier les choses, je veux dire pour mon simple exemple d'appeler. C1.f() p 'pour correspondre à votre

quantityOnHand = Macola.Item("12345").Location("A1").QuantityOnHand 

mais mon exemple simple fonctionne très bien. Donc, vous avez maintenant trois réponses qui correspondent à "besoin de plus d'infos", mais c'est un petit puzzle intéressant.

Si une instance de 'ItemLocation' n'est pas créée du tout, cela signifie-t-il que vous ne voyez pas d'appel à la méthode 'Location' de la classe 'ItemMaster'? Alors peut-être que le problème est en amont du code "Location" posté.

Questions connexes