Link to home
Start Free TrialLog in
Avatar of beechhorn
beechhorn

asked on

Returning classes in ASP

I have several classes which I import in every page using includes:

<!--#INCLUDE VIRTUAL="includes/ShopWithinAShop/Size.inc"-->
<!--#INCLUDE VIRTUAL="includes/ShopWithinAShop/SizeGroup.inc"-->

The problem is when I call the Sub:

    Private Sub SizeUpd()
      Dim SizeIdentity
      Dim SizeRecordset
      SizeIdentity = 0
      Set SizeRecordset = Server.CreateObject("ADODB.Recordset")
      Call SizeRecordset.Open("SELECT [SizeGroupSize].[Size] " & _
                              "FROM [SizeGroupSize] " & _
                              "WHERE [SizeGroupSize].[SizeGroup] = " & CStr(Me.Identification) & " " & _
                              ";", Connection, adOpenForwardOnly, adLockReadOnly)
      Do While Not SizeRecordset.EOF
        SizeIdentity = SizeIdentity + 1
        Call SizeRecordset.MoveNext
      Loop
      Call SizeRecordset.Close
      Erase Sizes
      ReDim Sizes(SizeIdentity)
      SizeIdentity = 0
      Call SizeRecordset.Open("SELECT [SizeGroupSize].[Size] " & _
                              "FROM [SizeGroupSize] " & _
                              "WHERE [SizeGroupSize].[SizeGroup] = " & CStr(Me.Identification) & " " & _
                              ";", Connection, adOpenForwardOnly, adLockReadOnly)
      Do While Not SizeRecordset.EOF
        SizeIdentity = SizeIdentity + 1
        Set Sizes(SizeIdentity) = New Size
        Set Sizes(SizeIdentity).Database = Connection
        Sizes(SizeIdentity).Identification = SizeRecordset.Fields("Size").Value
        Call SizeRecordset.MoveNext
      Loop
      Call SizeRecordset.Close
      Set SizeRecordset = Nothing
    End Sub

It says:

 <font face="Arial" size=2>
<p>Microsoft VBScript runtime </font> <font face="Arial" size=2>error '800a01fa'</font>
<p>
<font face="Arial" size=2>Class not defined: 'Size'</font>
<p>
<font face="Arial" size=2>/includes/ShopWithinAShop/SizeGroup.inc</font><font face="Arial" size=2>, line 137</font>

Despite the Size Class being added first...

Any ideas on how to fix this?

It seems I must declare the size class inside the sizegroup class how do I do this?
Avatar of alorentz
alorentz
Flag of United States of America image

Is the class in <% %> tags in the includes?
Avatar of beechhorn
beechhorn

ASKER

Yup here are the two classes:

SIZE.INC

--------------------------------------

<%
  Class Size
    Private Connection
    Private Recordset

    Public Property Set Database(ByRef ActiveConnection)
      Set Connection = ActiveConnection
    End Property

    Public Property Get Database()
      If IsObject(Connection) Then
        Set Database = Connection
      Else
        Database = Connection
      End If
    End Property

    Public Property Get Identification()
      If Recordset.State Then
        If Not Recordset.EOF Then
          Identification = Recordset.Fields("Identification").Value
        End If
      End If
    End Property

    Public Property Let Identification(ByVal newIdentification)
      If Recordset.State Then
        Call Recordset.CancelUpdate
        Call Recordset.Close
      End If
      If Connection.State Then
        Call Recordset.Open("SELECT [Size].[Identification], " & _
                            "       [Size].[Name] " & _
                            "FROM [Size] " & _
                            "WHERE [Size].[Identification] = " & CStr(newIdentification) & " " & _
                            ";", Connection, adOpenStatic, adLockOptimistic)
        If Recordset.EOF Then
          If Recordset.State Then
            If Not Recordset.BOF And Not Recordset.EOF Then
              Call Recordset.CancelUpdate
            End If
            Call Recordset.Close
          End If
          If Connection.State Then
            Call Recordset.Open("SELECT [Size].[Identification], " & _
                                "       [Size].[Name] " & _
                                "FROM [Size] " & _
                                ";", Connection, adOpenDynamic, adLockOptimistic)
            Call Recordset.AddNew
            Call Recordset.Update
            newIdentification = Recordset.Fields("Identification").Value
            Call Recordset.Close
            Call Recordset.Open("SELECT [Size].[Identification], " & _
                                "       [Size].[Name] " & _
                                "FROM [Size] " & _
                                "WHERE [Size].[Identification] = " & CStr(newIdentification) & " " & _
                                ";", Connection, adOpenStatic, adLockOptimistic)
          End If
        End If
      End If
    End Property

    Public Property Get Name()
      If Recordset.State Then
        If Not Recordset.EOF Then
          If Recordset.Fields("Name").ActualSize = 0 Then
            Name = ""
          Else
            Name = Recordset.Fields("Name").Value
          End If
        End If
      End If
    End Property

    Public Property Let Name(ByVal newName)
      If Recordset.State Then
        If Not Recordset.EOF Then
          Recordset.Fields("Name").Value = newName
          Call Recordset.Update
        End If
      End If
    End Property

    Private Sub Class_Initialize()
      Set Connection = Server.CreateObject("ADODB.Connection")
      Set Recordset = Server.CreateObject("ADODB.Recordset")
    End Sub

    Private Sub Class_Terminate()
      If Recordset.State Then
        If Not Recordset.BOF And Not Recordset.EOF Then
          Call Recordset.CancelUpdate
        End If
        Call Recordset.Close
      End If
      Set Recordset = Nothing
    End Sub
  End Class
%>

--------------------------------

SIZEGROUP.INC

-------------------------------

<%
  Class SizeGroup
    Private Connection
    Private Recordset
    Private Sizes()

    Public Property Set Database(ByRef ActiveConnection)
      Set Connection = ActiveConnection
    End Property

    Public Property Get Database()
      If IsObject(Connection) Then
        Set Database = Connection
      Else
        Database = Connection
      End If
    End Property

    Public Property Get Identification()
      If Recordset.State Then
        If Not Recordset.EOF Then
          Identification = Recordset.Fields("Identification").Value
        End If
      End If
    End Property

    Public Property Let Identification(ByVal newIdentification)
      If Recordset.State Then
        Call Recordset.CancelUpdate
        Call Recordset.Close
      End If
      If Connection.State Then
        Call Recordset.Open("SELECT [SizeGroup].[Identification], " & _
                            "       [SizeGroup].[Name] " & _
                            "FROM [SizeGroup] " & _
                            "WHERE [SizeGroup].[Identification] = " & CStr(newIdentification) & " " & _
                            ";", Connection, adOpenStatic, adLockOptimistic)
        If Recordset.EOF Then
          If Recordset.State Then
            If Not Recordset.BOF And Not Recordset.EOF Then
              Call Recordset.CancelUpdate
            End If
            Call Recordset.Close
          End If
          If Connection.State Then
            Call Recordset.Open("SELECT [SizeGroup].[Identification], " & _
                                "       [SizeGroup].[Name] " & _
                                "FROM [SizeGroup] " & _
                                ";", Connection, adOpenDynamic, adLockOptimistic)
            Call Recordset.AddNew
            Call Recordset.Update
            newIdentification = Recordset.Fields("Identification").Value
            Call Recordset.Close
            Call Recordset.Open("SELECT [SizeGroup].[Identification], " & _
                                "       [SizeGroup].[Name] " & _
                                "FROM [SizeGroup] " & _
                                "WHERE [SizeGroup].[Identification] = " & CStr(newIdentification) & " " & _
                                ";", Connection, adOpenStatic, adLockOptimistic)
          End If
        End If
      End If
    End Property

    Public Property Get Name()
      If Recordset.State Then
        If Not Recordset.EOF Then
          If Recordset.Fields("Name").ActualSize = 0 Then
            Name = ""
          Else
            Name = Recordset.Fields("Name").Value
          End If
        End If
      End If
    End Property

    Public Property Let Name(ByVal newName)
      If Recordset.State Then
        If Not Recordset.EOF Then
          Recordset.Fields("Name").Value = newName
          Call Recordset.Update
        End If
      End If
    End Property

    Public Property Get Size(ByVal Identification)
      Call SizeUpd
      If Identification < LBound(Sizes) Or Identification > UBound(Sizes) Then
        Set Size = New Size
      Else
        Set Size = Sizes(Identification)
      End If
      Erase Sizes
    End Property

    Public Sub SizeAdd(ByRef newSize)
      If Connection.State Then
        Call Connection.Execute("INSERT INTO [SizeGroupSize] ([SizeGroup], " & _
                                "                             [Size]) " & _
                                "VALUES (" & CStr(Me.Identification) & ", " & _
                                         CStr(newSize.Identification) & ") " & _
                                ";")
      End If
    End Sub

    Public Sub SizeDel(ByRef newSize)
      If Connection.State Then
        Call Connection.Execute("DELETE FROM [SizeGroupSize] " & _
                                "WHERE [SizeGroupSize].[SizeGroup] = " & CStr(Me.Identification) & " " & _
                                "AND [SizeGroupSize].[Size] = " & CStr(newSize.Identification) & " " & _
                                ";")
      End If
    End Sub

    Private Sub SizeUpd()
      Dim SizeIdentity
      Dim SizeRecordset
      SizeIdentity = 0
      Set SizeRecordset = Server.CreateObject("ADODB.Recordset")
      Call SizeRecordset.Open("SELECT [SizeGroupSize].[Size] " & _
                              "FROM [SizeGroupSize] " & _
                              "WHERE [SizeGroupSize].[SizeGroup] = " & CStr(Me.Identification) & " " & _
                              ";", Connection, adOpenForwardOnly, adLockReadOnly)
      Do While Not SizeRecordset.EOF
        SizeIdentity = SizeIdentity + 1
        Call SizeRecordset.MoveNext
      Loop
      Call SizeRecordset.Close
      Erase Sizes
      ReDim Sizes(SizeIdentity)
      SizeIdentity = 0
      Call SizeRecordset.Open("SELECT [SizeGroupSize].[Size] " & _
                              "FROM [SizeGroupSize] " & _
                              "WHERE [SizeGroupSize].[SizeGroup] = " & CStr(Me.Identification) & " " & _
                              ";", Connection, adOpenForwardOnly, adLockReadOnly)
      Do While Not SizeRecordset.EOF
        SizeIdentity = SizeIdentity + 1
        Set Sizes(SizeIdentity) = New Size
        Set Sizes(SizeIdentity).Database = Connection
        Sizes(SizeIdentity).Identification = SizeRecordset.Fields("Size").Value
        Call SizeRecordset.MoveNext
      Loop
      Call SizeRecordset.Close
      Set SizeRecordset = Nothing
    End Sub

    Private Sub Class_Initialize()
      Set Connection = Server.CreateObject("ADODB.Connection")
      Set Recordset = Server.CreateObject("ADODB.Recordset")
    End Sub

    Private Sub Class_Terminate()
      If Recordset.State Then
        If Not Recordset.BOF And Not Recordset.EOF Then
          Call Recordset.CancelUpdate
        End If
        Call Recordset.Close
      End If
      Set Recordset = Nothing
    End Sub
  End Class
%>

-----------------------------------

I'd get a warning that sizegroup is not defined and my actual code on the returned html otherwise.
Not sure...should try something smaller though to test:
<%
Class Size
      Function Testing(val)
               Response.write "This class works, and passes " & val
      end function
end class
%>

<%
set p = new Size
r = p.Testing(100)
 %>
Classes on there own work fine - like your example works fine.

I have classes that called on their own work and work really well.

For instance I have a product class that I am using (same structure) I just write

Dim CurrentProduct
Set CurrentProduct = New Product
Set CurrentProduct.Database = ActiveConnection
CurrentProduct.Identification = 133

Then I am calling things like

<%=CurrentProduct.Name%>

That works fine.

Same thing for the SizeGroup I can return the name, etc.

I have tried returning arrays using the same functions (.Size(Long), .SizeAdd(Size), .SizeDel(Size) that works fine.

MY PROBLEM IS

That my classes will not return my classes or even allow variables to be set to my classes from within my classes.

For simplicity say I called my classes a and b.

On a page with imports of the two class includes - I can set a variable to be class a and a variable to be class b.

Fine no problems.

However if I try to return an instance of class b from class a - I get an error pointing to the class a include saying "Class not defined: 'b'".

Despite calls on the page to class b working - its just my classes are not aware of each other.

The main page can talk to them all though.
I'll raise the points for this question to 2,500 if someone can tell me how.

See if that gets some more responses.
For anyone with a Visual Basic background - these classes work fine in VB6.

They can return my classes from within classes.

All I did to convert them to ASP is:

1) remove the AS Type declarations

2) put them in includes with <% %> around them

3) change New ADODB.ANYTHING to Server.CreateObject("ADODB.ANYTHING")

4) change the redim array(1 to something) calls to just redim array(something)

It is frustating that ASP messes it up.
Unfortunately 2,500 points is against EE policiy, so that won't do any good.

So, your problem is creating an instance of class a within class b, but you can create an instance of them independently in code?
>>For anyone with a Visual Basic background - these classes work fine in VB6.

Thought they looked like VB and not ASP.  May still be fine, but I do all mine in ASP.  Might consider making them DLL's.
??  that sub (sizeupd) doesn't actually class size.  what's line 137?
Line 137 is

Set Sizes(SizeIdentity) = New Size

It chokes because it isn't aware of its surroundings custom classes.

I'll post another question about how I can create a dll that can be accepted and usable on a web server I have no control over - so no comments on that matter here please. I want an ASP solution.
So, your problem is creating an instance of class a within class b, but you can create an instance of them independently in code?

Yup!!!

Thought they looked like VB and not ASP.  May still be fine, but I do all mine in ASP.  Might consider making them DLL's.

Don't know why that would make a difference to this issue - must keep this relavant.
...works in ASP for me.

copy the classes into the file and see if it works...
>> ...works in ASP for me.
>>copy the classes into the file and see if it works...

Huh?!? Please explain a little more.

The page that is calling the class does this:

<%
  Dim CurrentSizeGroup
  Set CurrentSizeGroup = New SizeGroup
  If Request.QueryString("Identification") > 0 Then
    Set CurrentSizeGroup.Database = Session("ActiveConnection")
    CurrentSizeGroup.Identification = CLng(Request.QueryString("Identification"))
  End If
%>
              <td>Name:</td>
              <td colspan="3"><input id="Name"
                                     name="Name"
                                     style="width: 300px;"
                                     type="text"
                                     value="<%=CurrentSizeGroup.Name%>"></td>
            </tr>
            <tr>
              <td>Sizes<br>on<br>separate<br>lines:</td>
              <td colspan="3"><textarea id="Sizes"
                                        name="Sizes"
                                        style="height: 150px;
                                               width: 300px;"><%
  Dim CurrentSizeGroupSize
  Dim CurrentSize
  Set CurrentSize = New Size
  CurrentSizeGroupSize = 1
  Do While Not CurrentSizeGroup.Size(CurrentSizeGroupSize).Identification = 0
%><%=CurrentSizeGroup.Size(CurrentSizeGroupSize).Name%>
<%
    CurrentSizeGroupSize = CurrentSizeGroupSize + 1
  Loop
%></textarea></td>

Now the text box says the sizegroup name ok but the textarea box says:

" <font face="Arial" size=2>
<p>Microsoft VBScript runtime </font> <font face="Arial" size=2>error '800a01fa'</font>
<p>
<font face="Arial" size=2>Class not defined: 'Size'</font>
<p>
<font face="Arial" size=2>/includes/ShopWithinAShop/SizeGroup.inc</font><font face="Arial" size=2>, line 137</font>"
How can I up the points on this and whats the limit? I REALLY need an answer quickly...
500 is the highest.  Experts are pretty timely here, so if they know they would respond.
I just believe I am the first person to want to use a custom ASP class within a custom ASP class.

Microsoft OO programming at its most ironic...
I just can't believe even.
Well it looks like I'll have to close this question as no-one has the answer the way I want to do it.

A comprimise as suggested by alorentz seems the only option.

If someone can tell me how to reference a dll file entirely from ASP I'll award 250 points to them and 250 points to alorentz (for coming up with the suggestion).
Avatar of CooPzZ
that actually sounds like to me that one of your varibles is taking up a reserved key word to me. therefore the class can't compile therefore not defined..

I'd trying renaming your varibles like Recordset and things to oRecordset

cheers
I would recon that it would be how you have call that method through this..

    Public Property Get Size(ByVal Identification)
      Call SizeUpd
      If Identification < LBound(Sizes) Or Identification > UBound(Sizes) Then
        Set Size = New Size
      Else
        Set Size = Sizes(Identification)
      End If
      Erase Sizes
    End Property

Set Size in a property called Size  sounds like trouble to me.  and I just did a test and i would believe thats your problem
It's not though! I can call it anything and I get the same result. I use hungarian notation and different naming schemes. I changed some names over for simplicity to get this thing working. The problem is no-one can tell me how to get a user defined class to use a user defined class in ASP. It doesn't matter what they are called!
I take it no-one knows how to get this working then.

So far no-one whos actually got homemade classes within homemade classes working has posted (or left an answer that makes sense from their description) - I thought this would of been easy points for someone...

I am offering 500 points if someone can give me a 100% ASP solution or 250 points to whoever can tell me how to use my .dll file from within a asp page - due to it being a suggestion by Alorentz and I'd have to split the points.

Is there a command like include("aspects.dll")?
The DLL works fine even with the spurious naming conventions.

[url]http://www.aspects.biz/includes/aspects.dll[/url]

It's just if I write the classes in ASP...
SOLUTION
Avatar of alorentz
alorentz
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I can't register the dll on the server it's out of my control...

:(

I know that is possible to include a dll on a per page basis (looking through some old source code for it now).

Then it'll work as if it was registered - if I find it first I will close this question and award all points to alorentz if anyone wants all 500 then I need a way for a usermade class to use another usermade class internally or for half points find the code to dynamically use a dll before me.
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
You know, I've been thinking that the naming of the class is wrong the whole time.  Guess I should have spoke up!
That oh so nearly works for all my classes.

It is close enough.

Due to it being slightly off (I have it working now) I will do an equal split between you and alorentz.

Thank you both.
>>I have it working now

What did you do then?
Just to explain why it was slightly off - some words such as image, etc do not suffer that issue (probably because I am overstepping some preused name spaces). Also some required double renaming.

IMO you both deserve at least 500 points.

I cannot explain sufficiently how important getting this info was.
>>What did you do then?

Well using Coopzz code:

    class topSize
          Public Property Get Size
               dim oSize: set oSize = new Size1
               Size = oSize.theSize
          end Property
          Public sub Update
               dim oSize: set oSize = new Size1
               oSize.Update
          End sub
     end class

I had to do the equivalent of

    class topSize
          Public Property Get Size
               dim oSize: set oSize = new Size1
                dim oTheSize: set oTheSize = oSize.theSize
               Set Size = oTheSize
          end Property
          Public sub Update
               dim oSize: set oSize = new Size1
               oSize.Update
          End sub
     end class

I guess I was overstepping some more name spaces...
Good luck!
>>IMO you both deserve at least 500 points.

Note, for future reference, the grade you give does effect the points received.
BTW I only had to change things on some classes

They all have v.similar properties/functions/subs hence simple naming

So not changing anything worked on some
Coopzz way worked on others
My new way worked on the rest

Very random and microsoft esque - going for a pint now project finished!!! :D
Happy to help.. gotta watch out for that asp.. can trap you for hours if your not careful #{