How can I add an arraylist attribute into a class using classic ASP?
My Example (Not working):
Class AA
Public AA_id
Dim data: set data = CreateObject("System.Collections.ArrayList")
End Class
You need to initialize class members inside a method - function, sub routine of the class constructor. Naturally, the best of these is inside the constructor.
Fully working code demonstrating how to use the .NET ArrayList as part of custom VBScript class:
<%
Class MyCustomClass
Private internalArrayList
Private Sub Class_Initialize()
Set internalArrayList = Server.CreateObject("System.Collections.ArrayList")
End Sub
Private Sub Class_Terminate()
Set internalArrayList = Nothing
End Sub
Public Sub AddItem(oItem)
internalArrayList.Add(oItem)
End Sub
Public Function ToString()
Dim data, x
data = "List contains " & internalArrayList.Count & " item"
If internalArrayList.Count<>1 Then data = data & "s"
For x=0 To internalArrayList.Count-1
data = data & "<br />"
If IsObject(internalArrayList(x)) Then
data = data & "complex object of type " & TypeName(internalArrayList(x))
ElseIf IsArray(internalArrayList(x)) Then
data = data & "array with " & (UBound(internalArrayList(x)) + 1) & " items"
Else
data = data & internalArrayList(x)
End If
Next
ToString = data
End Function
End Class
%>
Usage sample, including adding a complex object:
Class Foo
Public Dummy
End Class
Dim myInstance, myFoo
Set myInstance = New MyCustomClass
myInstance.AddItem("hello")
myInstance.AddItem("world")
myInstance.AddItem(Array(1, 2, 3))
Set myFoo = New Foo
myFoo.Dummy = "just checking"
myInstance.AddItem(myFoo)
Response.Write(myInstance.ToString())
Related
I am creating a tool in VBA to create labels with information about transactions.
I would like the user to use a form to give all the information and the labels will be automatically created.
To do so I have created a transaction class called clsTransaction.
Public PartNum As String
Private Sub Class_Initialize()
MsgBox "initialized!"
End Sub
At the initilalisation of the form a new object is created
Private Sub UserForm_Initialize()
(...)
Dim trans As New clsTransaction
End Sub
Then when a textbox is updated, I want to update the object property
Private Sub txtPartNum_AfterUpdate()
Dim strPartNum As String
strPartNum = txtPartNum.Value
MsgBox (strPartNum)
trans.PartNum = strPartNum
End Sub
I get the following error message
Run-time error '424':
Object required
My understanding is I need to declare the obect. I have tried to add:
dim trans as object
but I get an other error message:
Run time error '91':
object variable or With block variable not set
Could someone help me to update the object through the form?
The problem seems to be in the scope of your declaration. By doing this:
Private Sub UserForm_Initialize()
(...)
Dim trans As New clsTransaction '<-- declaration + assignment
End Sub
you are declaring trans in the scope of UserForm_Initialize(). Hence, when you then try to do something with it into another scope:
Private Sub txtPartNum_AfterUpdate()
(...)
trans.PartNum = strPartNum
End Sub
the object trans doesn't exist anymore because it's out of scope (so it has already been collected by the garbage collector) and you get an "object required error". You need to declare trans at global level, this is the idea:
Dim trans as yourClass '<-- global declaration: the object trans will keep on existing into all scopes
Private Sub UserForm_Initialize()
Set trans = New yourClass '<-- new instance of the object
End Sub
Private Sub txtPartNum_AfterUpdate()
'use the instance here
trans.PartNum = strPartNum
End Sub
I am new in VBA and classes.
I have this procedure in my class:
Public Sub InputData()
Dim blnLoaded As Boolean
Dim path As String
Dim file As String
path = MyForm.TextPath
file = MyForm.TextFile
If LoadData(path, file) = False Then
MsgBox FileErrorString
Else
blnLoaded = LoadData(path, file)
End If
End Sub
and I want to call it using 2 text boxes in my form:
Private Sub CmdLoad_Click()
Call clsData.InputData
End Sub
What I am doing wrong? Thank you in advance!
You need to create a new instance of your class first.
Something like this depending on your implementation of your class:
Private Sub CmdLoad_Click()
Dim myData as New clsData
Call myData.InputData()
End Sub
I am writing my first classes.
One is cCRElist which is essentially a collection of cCRE instances (some specialized events).
I want there to be a sub or function inside cCRElist that will load all the CRE's from the worksheet into one big collection I can work with. I created the function and it worked OK when I called it from a normal code module, but then I tried to move the code into the class. Now I am having trouble calling the function LoadFromWorksheet(myWS as Worksheet).
The error is "object does not support this property or method". I have tried making it a sub, a function, making it public, not public, I have tried turning into a Property Let instead of a sub. Obviously I have a flimsy grasp on what that does. I have tried
Call CREList.LoadFromWorksheet(myWS)
and
CREList.LoadfromWorksheet myWS
Same error every time.
Here is the test code that uses the class and calls the function:
Sub TestClassObj()
Dim CRElist As cCRElist
Set CRElist = New cCRElist
Dim myWS As Worksheet
Set myWS = ThisWorkbook.ActiveSheet
CRElist.LoadFromWorksheet (myWS)
End Sub
Here is a snippet of the class cCRElist:
' **** CLASS cCRElist
Option Explicit
' This is a collection of CRE objects
Private pCRElist As Collection
Private Sub Class_Initialize()
Set pCRElist = New Collection
End Sub
Public Property Get CREs() As Collection
Set CREs = pCRElist
End Property
Public Property Set Add_CRE(aCRE As cCRE)
pCRElist.Add aCRE
End Property
Function LoadFromWorksheet(myWS As Worksheet)
Dim CRE As cCRE
Dim iFirst As Long
Dim iLast As Long
Dim i As Long
Set CRE = New cCRE
iFirst = gHeader_Row + 1
iLast = FindNewRow(myWS) - 1
' update data in CRE then add
For i = iFirst To iLast
If myWS.Cells(i, gCRE_Col) <> "" Then ' This is a CRE row
Set CRE = New cCRE
With CRE
.CRE_ID = myWS.Cells(i, gCRE_Col)
If Not IsDate(myWS.Cells(i, gCRE_ETA_Col)) Then
.ETA = "1/1/1900"
Else
.ETA = Trim(myWS.Cells(i, gCRE_ETA_Col))
End If
<... snipped ...>
End With
pCRElist.Add_CRE CRE
End If
Next
End Sub
' **** END OF CLASS cCRElist
Thanks for your expertise.
Here is what worked based on help I got in the comments. First, I did the "break in class module". In the test code, I changed the function call from:
CRElist.LoadFromWorksheet(myWS)
to
CRElist.LoadFromWorksheet myWS
Inside the class, i had to change
Set pCRElist.Add_CRE CRE
to
pCRElist.Add CRE
Then I was able to get rid of extraneous CLASS functions Add_CRE and Count.
Thanks for everyone's input. I couldn't figure out how to mark comments as accepted answers so I did this. Let me know if I need to do something differently.
Now it works!
I made a class in VBScript and used it in asp classic to instatiate an object:
This is my class:
<%
Class RBAC
Public dateTimeValue
Public userIdValue
Public fileIdValue
Public actionValue
Public Property Get DateTime()
'Gets the propery value
DateTime = dateTimeValue
End Property
Public Property Set DateTime(value)
'Sets the property value
dateTimeValue = value
End Property
Public Property Get UserId()
'Gets the propery value
UserId = userIdValue
End Property
Public Property Set UserId(value)
'Sets the property value
userIdValue = value
End Property
Public Property Get FileId()
'Gets the propery value
FileId = fileIdValue
End Property
Public Property Set FileId(value)
'Sets the property value
fileIdValue = value
End Property
Public Property Get Action()
'Gets the propery value
Action = actionValue
End Property
Public Property Set Action(value)
'Sets the property value
actionValue = value
End Property
Public Sub Insert()
sqlMethods = "INSERT INTO RBAC ([DateTime],[UserId],[FileId],[Action]) VALUES ("+dateTimeValue+","+userIdValue+","+fileIdValue+","+actionValue+",)"
Conn.Execute(sqlMethods)
End Sub
End Class
%>
And here I instantiate an object and set it's properties:
Dim RbacObject
Set RbacObject = New RBAC
Set RbacObject.DateTime = Now
Set RbacObject.UserId = Cstr(Session("cgsid"))
sqlFileId = "SELECT int_fileid FROM tbl_SecFiles where str_filename = '"&split(Request.ServerVariables("SCRIPT_NAME"),"/cgs/")(1)&"'"
Set RS = Conn.Execute(sqlFileId)
Set RbacObject.FileId = RS("int_fileid")
Set RbacObject.Action = "<"&stringMethods&"><old>"&enabled_profiles_old&"</old><new>"&enabled_profiles_old&siteid&",</new></"&stringMethods&">"
RbacObject.Insert
The problem is that only FileId gets a value rest of the fields are empty, even if I set them an value. What am I doing wrong?
Set is used for assigning objects to variables. So
Set RbacObject = New RBAC
is correct, but all other statements like
Set RbacObject.DateTime = Now
are not. Use
RbacObject.DateTime = Now
instead.
Set RbacObject.FileId = RS("int_fileid")
is a borderline case: fileIdValue will contain a Field object, but evaluate to its .Value when used in a 'non-object context' (like IO or computations).
You shouldn't run dubious code with/under On Error Resume Next.
Demo:
copy con 10.vbs
Class C
Public V
End Class
Set O = New C
Set O.V = "don't do this at home."
^Z
cscript 10.vbs
... 10.vbs(5, 1) Microsoft VBScript runtime error: Object required: 'O.V'
Demo II (to prove that 'it works' if you don't use Set for assignment of non-objects, and indicate that there must be other error hidden by the evil OERN if it 'still doesn't work'):
Class C
Public V
End Class
Set O = New C
On Error Resume Next
Set O.V = "don't do this at home."
WScript.Echo Err.Description
On Error GoTo 0
WScript.Echo "Set O.V => '" & O.V & "'"
O.V = "don't do this at home."
WScript.Echo "O.V => '" & O.V & "'"
output:
cscript 10.vbs
Object required
Set O.V => ''
O.V => 'don't do this at home.'
In addition to what Ekkehard.Horner said you need to define the setters for properties that don't take objects as
Public Property Let name(value)
not as
Public Property Set name(value)
Given that we have a script
Option Explicit
Class CClass
Private m_date
Private Sub Class_Initialize()
m_date = CDate("1970-01-01 00:00:00")
End Sub
Public Function Foo()
Dim d : d = Date()
WScript.Echo "d is " & FormatDateTime(d, vbGeneralDate)
End Function
Public Property Get Date()
Date = m_date
End Property
Public Property Let Date(p_date)
m_date = CDate(p_date)
End Property
End Class
Dim obj : Set obj = NEW CClass
Call obj.Foo()
How can class function CClass.Foo() call built-in VBScript function Date() without the property CClass.Date interfering?
My current solution is to introduce a dummy Date_() function which can be called instead. But that just seems wrong. I'm thinking there should be some way to specify that we want to call something outside the class scope.
I am almost positive that there is no way to do what you're asking in VBScript.
But even if you could figure out a way to do this, you really shouldn't. You need to choose names for your own functions that don't conflict with the names of built-in functions. Anything else is completely unmaintainable for a dynamic scripting language like VBScript.
Pick a different name for your Date property. Preferably something more descriptive: what kind of date does that property return? What does the date refer to? How is it likely to be used? Whatever you do, don't rename it to Date_—that's not any better.
You can call it from inside the class like:
Dim d : d = me.Date()
Me in VBScript is the same as you use This in Javascript for example
Too late to the party, but there is a solution using eval function.
see eval function docs for details
Class CClass
Private m_date
Private Sub Class_Initialize()
m_date = CDate("1970-01-01 00:00:00")
End Sub
Public Function Foo()
Dim d : d = eval("Date()")
WScript.Echo "d is " & FormatDateTime(d, vbGeneralDate)
End Function
Public Property Get Date()
Date = m_date
End Property
Public Property Let Date(p_date)
m_date = CDate(p_date)
End Property
End Class
Dim obj : Set obj = NEW CClass
Call obj.Foo()