Nearly there i think - Where am i going wrong with the class

mahmed1

Well-known Member
Joined
Mar 28, 2009
Messages
2,302
Office Version
  1. 365
  2. 2016
Platform
  1. Windows
Hi

I am trying to set up a class that has a Team name, Player Name and Players (Collection to add players) but i am getting an error saying variable not set. Please advise if im on the right track and give some pointers to where i can improve

Thank You

P.s how would i encorporate into the NEW class multiple names from the sheet1 Range A2:A10 where it hold the player names

Do i need to create an instance for each player name in the loop or can i leave it as 1 instance?

i.e

Code:
For i = 2 to 10

Set AddPlayer = New PlayersTeam.Player.Name = Sheets("Sheet1").Range("A" & i).value
Players.Add Player, Team.Player.Name
Set Players = Nothing
Next i

I have set up these 3 classes.

Team clas has 2 properties - Name and Player (class) to access Player Class

Normal Module

Code:
Sub test()
Dim Team As Team
Dim Player As Player
Dim Players As Players

Set Team = New Team
Set Player = New Player
Set Players= New Players

Team.Player.Name = "Joe Bloggs"
Players.Add Player, Team.Player.Name

End Sub

Team Class module

Code:
Private pName As String
Private pPlayer As Player
Public Property Let Name(value As String)
pName = value
End Property
Public Property Get Name() As String
Name = pName
End Property
Public Property Let Player(value As Player)
Set pPlayer = value
End Property
Public Property Get Player() As Player
Set Player = pPlayer
End Property

Player Class module

Code:
Private pName As String
Public Property Let Name(value As String)
pName = value
End Property
Public Property Get Name() As String
Name = pName
End Property

Players Class Module (Collection)

Code:
Private pAddPlayers As Collection

Private Sub Class_Initialize()
Set pAddPlayers = New Collection
End Sub

Sub Add(Item As Player, Key As String)
    pAddPlayers.Add Item, Key
End Sub

Public Property Get Count() As Long
Count = pAddPlayers.Count
End Property

Public Property Get Item(NameORnumber As Variant) As Player
Set Item = pAddPlayers.Item(NameORnumber)
End Property
 
And with this line of code, could it not have been written like this as i cant see the t.name = teamname doing anything

from

Private p_Teams As Dictionary




Public Function AddTeam(teamName As String) As Team
Dim t As Team

Set t = New Team

t.Name = teamName
p_Teams.Add teamName, t

Set AddTeam = t

End Function

to

Private p_Teams As Dictionary


Public Function AddTeam(teamName As String) As Team


p_Teams.Add teamName, Team

Set AddTeam = Team

End Function


Just trying to understand why that line of code is there
 
Upvote 0

Excel Facts

Can a formula spear through sheets?
Use =SUM(January:December!E7) to sum E7 on all of the sheets from January through December
Hi Kyle

Having studied the code I have a few questions and hopefully you can clarify

1) Private p_Teams As Dictionary

Public Function AddTeam(teamName As String) As Team

'Why are we Set t as New Team as the team is passed as this seems to give the same result
p_Teams.Add teamName, Team
Code:
    Dim t As Team
    Set t = New Team
    
    t.Name = teamName
    p_Teams.Add teamName, t

Code:
' What does this line of code do and whats the AddTeam set to, is this required    
    Set AddTeam = t
End Function

2) Again with this code also could i have done like this
Public Function AddPlayer(PlayerName As String) As Player
p_Players.Add PlayerName, Player
End Function

and there seems to be no Set AddPlayer = p like the example above and curious to why its not added in the code below

Code:
Public Function AddPlayer(PlayerName As String) As Player

    Dim p As Player
    Set p = New Player
    p.Name = PlayerName
    p_Players.Add PlayerName, p
    
End Function
 
Upvote 0
1. But the team isn't passed, only a string is passed the team name. You therefore need to create an instance of Team, you can then assign its properties.

The:
Rich (BB code):
Set AddTeam = t

Is the point I made earlier, it returns the Team that has just been created to the calling function, without it, the code would look like this:
Rich (BB code):
    oLeague.AddTeam "Boys Team"
    With oLeague.GetTeamByName("Boys Team")
        .AddPlayer "Kyle"
        .AddPlayer "James"
        .AddPlayer "Bob"
        .AddPlayer "Pete"
    End With

So we have to create the Team, then get a reference to it separately, returning it as part of the function allows us to skip this step:
Rich (BB code):
    With oLeague.AddTeam("Boys Team")
        .AddPlayer "Kyle"
        .AddPlayer "James"
        .AddPlayer "Bob"
        .AddPlayer "Pete"
    End With

2. No, you couldn't - where are you getting the player from in this? Player does not exist in this context, therefore needs creating:
Rich (BB code):
Public Function AddPlayer(PlayerName As String) As Player 
    p_Players.Add PlayerName, Player 
End Function

You could indeed return the Player created as in the first example, I omitted it for brevity, but you could include it in the same way as I did for teams
 
Upvote 0
Firstly thank you so so so much

Am i thinking right in saying

1) with the function returning as TEAMt, this allows the access to the properties of the Team class however you still have to create an instance of the Team class or you wont be able to access the properties of the Team class?

I say this because in the standard module if i had Set t = new Team then i could reference the team properties but are you saying because in the teams class although it has as TEAM, no instance has been created in that class therefore properties could not be accessed of the TEAM class.

2) by having set Addteam = t this is saying that
with this oleague.additem("boys team").addplayer = "kyle"
the additem will store boys team however if i excluded this then it loses it therefore i would have to get the team name again?

t.name = teamname <<<is this needed
 
Upvote 0
Technically you can't access any properties of a class, you access properties of an object. A class is simply a blueprint that defines an object - that object simply does not exist until you create it. That's what we are actually doing here, we are creating an object of the type Team:
Code:
Dim t as Team 'Declare a Variable of Type Team
Set t = New Team 'Create an object of type Team and assign it to the t variable

'We can now interact with the Team Object
t.Name = "Kyle's Team"

By returning the Team object in the AddTeam function, we pass this object back to the calling code so that it can access its properties.
Code:
Dim League as Teams
Dim oTeam as Team

Set League = New Teams
Set oTeam = League.AddTeam("Boys Team")
oTeam.AddPlayer "Kyle"

Sorry, I don't understand this:
I say this because in the standard module if i had Set t = new Team then i could reference the team properties but are you saying because in the teams class although it has as TEAM, no instance has been created in that class therefore properties could not be accessed of the TEAM class.

2. I'm saying that without:
Code:
Addteam = t
You can't do
Code:
oleague.additem("boys team").addplayer "kyle"

The above only works because the function returns a Team Object with the Method AddPlayer, if it didn't return anything, you would need to get a reference to the Team object after creating it - in this case through the GetTeamByName() function - which does return a Team object.
 
Upvote 0
Hi Kyle

is this analogy right?

public property get item(value as variant) as Team
Set item = addteam.item(value)
end property

The set Item ....holds a reference to the Team class
 
Upvote 0
I understand now how you could pass an object to the calling function to hold an object so you can reference the properties?
So if we are creating the object like
set t = new team
then why do we need AS TEAM at the end of function? Is this needed so that the standard module can access the properties of team class also?
 
Last edited by a moderator:
Upvote 0
is this analogy right?

public property get item(value as variant) as Team
Set item = addteam.item(value)
end property

I don't know - it depends on what "addteam" is in that context. It seems an odd thing to do, presumably that code would add a new Team each time you Get an item - that doesn't sound like the correct behaviour?

I understand now how you could pass an object to the calling function to hold an object so you can reference the properties?
So if we are creating the object like
set t = new team
then why do we need AS TEAM at the end of function? Is this needed so that the standard module can access the properties of team class also?

No, it is not required, this is just a normal function, so if omitted the function would return a variant type. This isn't desirable, you should always be explicit with your declarations and it would also mean that you lose intellisense
 
Upvote 0
Awesome Kyle

i was more curious to which part actually allows me to get reference to the Team object properties in a standard module

Was it

Set AddTeam = t or at the end of the function having AS TEAM

standard module Additem.(property)

i thought it was the As TEAM that allowed the access but i guess its the SET AddItem that is allowing the access and the AS TEAM allows you to have the intellisence?

would that be correct?
 
Upvote 0
For the most part yes. the As Team strongly types the function return, which allows intellisense to work. Setting the function return is what actually returns the object.
 
Upvote 0

Forum statistics

Threads
1,216,086
Messages
6,128,736
Members
449,466
Latest member
Peter Juhnke

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top