PDA

View Full Version : Classes arrays objects for webservices



burnv84
06-03-2013, 11:53 AM
Hi, Im trying to use some classes that will hold invoice data and I cant seem to get it working. I just want it to save details of an invoice in an array. Heres the code, maybe someone can figure it out.
Also id like for the LineItems to take a random number of product items, not sure how to do that yet.


Sub webservicetest()
Dim NewOrder As New struct_XOrder
Dim LineItems(1 To 2) As Variant
Dim Xline As New struct_LineItem

'NewOrder.LineItems = new LineItem[2]; // initialize to correct number of line items
'LineItem XLine;
'XLine = new LineItem();
'NewOrder.LineItems[0] = XLine

NewOrder.ClientShortName = "DemoClient"
NewOrder.OrderNumber = "12345"

'Dim Xline As New LineItems
Xline = New LineItem
Xline.ItemComment = "item1"
Xline.Qty = 5

'Set Xline = NewOrder.LineItems

Debug.Print NewOrder.ClientShortName
Debug.Print NewOrder.OrderNumber
Debug.Print Xline
End Sub


'''''' This is how it works in c# '''''
NewOrder.LineItems = new LineItem[2]; // initialize to correct number of line items
LineItem XLine;
XLine = new LineItem(); // create a new line item
XLine.ProductSKU = "abcde"; // populate it
XLine.Qty = 3;
XLine.UnitPrice = "19.95";
XLine.ItemComment = "ignore this";
NewOrder.LineItems[0] = XLine; // place it to the array
XLine = new LineItem(); // and so on
XLine.ProductSKU = "aabbc";
XLine.Qty = 2;
XLine.UnitPrice = "4.99";
XLine.ItemComment = "ignore this also";
NewOrder.LineItems[1] = XLine;
'''''''''''''''''''''''''''''''''''''

stanl
06-04-2013, 06:59 AM
Rather than an array, you might consider creating an in-memory recordset with the MSPersist provider. Field names can be typed, any number of records can be added and the .save() method can persist the data as xml.

burnv84
06-04-2013, 09:21 AM
I know even less about mspersist. Iv heard something about collections being better, dont know if it can be applied here.
Here is the other code for struct_XOrder

Public OrderNumber As String
Public ClientShortName As String
'"LineItems" is an array with elements defined as struct_LineItem
'See Complex Types: Arrays in Microsoft Office 2003 Web Services Toolkit Help
'for details on implementing arrays.
Public LineItems As Variant
Public OrderError As String


Heres the struct_LineItem

Public ProductSKU As String
Public Qty As Long
Public UnitPrice As Variant
Public ItemComment As String
Public ItemError As String





Dim NewOrder As struct_XOrder
Dim LineItems(1 To 2) As Variant
Dim Xline(1 To 2) As struct_LineItem
Set NewOrder = New struct_XOrder

Set NewOrder.LineItems() = New struct_LineItem
Set LineItems().Xline() = New struct_LineItem
Xline(1) = New struct_LineItem
Set Xline.ItemComment = "items"
Set Xline.Qty = 10
NewOrder.LineItems() = Xline()


NewOrder.ClientShortName = "DemoClient"
NewOrder.OrderNumber = "12345"

Debug.Print NewOrder.ClientShortName
Debug.Print NewOrder.OrderNumber
'Debug.Print Xline(1).ItemComment
'Debug.Print Xline(1).Qty



I think im stuck on making Xline array an object of array lineitem. I also have to make the array size dynamic at some point. Anyone have any idea? Thanks

burnv84
06-05-2013, 09:02 AM
Bump, any help anyone???

HiTechCoach
06-05-2013, 02:25 PM
Iv heard something about collections being better
Note: Your C# code is already using a collection.

Your VBA code is attempting to use a collection that may no be defined..

Is struct_XOrder defined in a class module?

Are you needing an array so that it can be passed to a web service?

burnv84
06-06-2013, 07:51 AM
Yeah, struct_xorder is in a class module.
Im not sure whether it should use an array or a collection to send the data to a webservice.
The actual webservice is here webservice.p3pl.c0m/wsorder.asmx but iv never used one before so im finding this tricky.

Heres the clsws_WSorder class module

'Dimensioning private class variables.
Private sc_WSOrder As SoapClient30
Private Const c_WSDL_URL As String = "web service link, post count low"
Private Const c_SERVICE As String = "WSOrder"
Private Const c_PORT As String = "WSOrderSoap"
Private Const c_SERVICE_NAMESPACE As String = "link here"
Private Sub Class_Initialize()
'*****************************************************************
'This subroutine will be called each time the class is instantiated.
'Creates sc_ComplexTypes as new SoapClient30, and then
'initializes sc_ComplexTypes.mssoapinit2 with WSDL file found in
'*****.
'*****************************************************************
Dim str_WSML As String
str_WSML = "<servicemapping>"
str_WSML = str_WSML & "<service name='WSOrder'>"
str_WSML = str_WSML & "<using PROGID='MSOSOAP.GenericCustomTypeMapper30' cachable='0' ID='GCTM'/>"
str_WSML = str_WSML & "<types>"
str_WSML = str_WSML & "<type name='LineItem' targetNamespace='***' uses='GCTM' targetClassName='struct_LineItem'/>"
str_WSML = str_WSML & "<type name='XOrder' targetNamespace='*****' uses='GCTM' targetClassName='struct_XOrder'/>"
str_WSML = str_WSML & "<type name='XOrderRet' targetNamespace='*****' uses='GCTM' targetClassName='struct_XOrderRet'/>"
str_WSML = str_WSML & "</types>"
str_WSML = str_WSML & "</service>"
str_WSML = str_WSML & "</servicemapping>"
Set sc_WSOrder = New SoapClient30
sc_WSOrder.MSSoapInit2 c_WSDL_URL, str_WSML, c_SERVICE, c_PORT, c_SERVICE_NAMESPACE
'Use the proxy server defined in Internet Explorer's LAN settings by
'setting ProxyServer to <CURRENT_USER>
sc_WSOrder.ConnectorProperty("ProxyServer") = "<CURRENT_USER>"
'Autodetect proxy settings if Internet Explorer is set to autodetect
'by setting EnableAutoProxy to True
sc_WSOrder.ConnectorProperty("EnableAutoProxy") = True
Set sc_WSOrder.ClientProperty("GCTMObjectFactory") = New clsof_Factory_WSOrder
End Sub
Private Sub Class_Terminate()
'*****************************************************************
'This subroutine will be called each time the class is destructed.
'Sets sc_ComplexTypes to Nothing.
'*****************************************************************
'Error Trap
On Error GoTo Class_TerminateTrap
Set sc_WSOrder = Nothing
Exit Sub
Class_TerminateTrap:
WSOrderErrorHandler ("Class_Terminate")
End Sub
Private Sub WSOrderErrorHandler(str_Function As String)
'*****************************************************************
'This subroutine is the class error handler. It can be called from any class subroutine or function
'when that subroutine or function encounters an error. Then, it will raise the error along with the
'name of the calling subroutine or function.
'*****************************************************************
'SOAP Error
If sc_WSOrder.FaultCode <> "" Then
Err.Raise vbObjectError, str_Function, sc_WSOrder.FaultString
'Non SOAP Error
Else
Err.Raise Err.Number, str_Function, Err.Description
End If
End Sub
Public Function wsm_ProcessOrder(ByVal obj_NewOrder As struct_XOrder) As struct_XOrderRet
'*****************************************************************
'Proxy function created from webservices-wsorder (wont let me print link).
'*****************************************************************
'Error Trap
On Error GoTo wsm_ProcessOrderTrap
Set wsm_ProcessOrder = sc_WSOrder.ProcessOrder(obj_NewOrder)
Exit Function
wsm_ProcessOrderTrap:
WSOrderErrorHandler "wsm_ProcessOrder"
End Function


Heres the class module clsof_Factory_WSOrder

Implements IGCTMObjectFactory
Private Function IGCTMObjectFactory_CreateObject(ByVal par_WSMLNode As MSXML2.IXMLDOMNode) As Object
Dim node As IXMLDOMNode
On Error GoTo IGCTMObjectFactoryTrap
Set node = par_WSMLNode.Attributes.getNamedItem("targetClassName")
Set IGCTMObjectFactory_CreateObject = Nothing
If Not (node Is Nothing) Then
Select Case node.nodeValue
Case "struct_LineItem"
Set IGCTMObjectFactory_CreateObject = New struct_LineItem
Case "struct_XOrder"
Set IGCTMObjectFactory_CreateObject = New struct_XOrder
Case "struct_XOrderRet"
Set IGCTMObjectFactory_CreateObject = New struct_XOrderRet
End Select
End If
Exit Function
IGCTMObjectFactoryTrap:
Err.Raise Err.Number, "clsof_Factory_WSOrder", Err.Description
End Function




Heres the update of what i have now

Sub webservicetest3()
Dim obj_NewOrder As struct_XOrder
Dim LineItems(1 To 2) As struct_LineItem 'Variant?
Dim Xline(1 To 2) As struct_LineItem

Dim myStruct As struct_LineItem
Xline(1) = myStruct

NewOrder.LineItems = Xline()
Xline(1).ProductSKU = "abcde"
Xline(1).UnitPrice = "19.95"
Xline(1).ItemComment = "items"
Xline(1).Qty = 10
NewOrder.LineItems = Xline()

Xline(2).ProductSKU = "daaaa"
Xline(2).UnitPrice = "20.00"
Xline(2).ItemComment = "items2"
Xline(2).Qty = 20
NewOrder.LineItems = Xline()

''''' Just to see if it prints right ''''''
Debug.Print NewOrder.ClientShortName
Debug.Print NewOrder.OrderNumber

Dim I As Integer
For I = 1 To UBound(NewOrder.LineItems)
Debug.Print NewOrder.LineItems(I).ProductSKU
Debug.Print NewOrder.LineItems(I).UnitPrice
Debug.Print NewOrder.LineItems(I).ItemComment
Debug.Print NewOrder.LineItems(I).Qty
Next I
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'// instantiate an order processor (WSOrder)
'WSOrder OrderProcessor = new WSOrder();
'// specify the destination URL
'OrderProcessor.Url = "webservices.p3pl.com/WSORDER.ASMX";
'// specify a timaout time (20 seconds should be more than enough)
'OrderProcessor.Timeout = 20000;
'// using IIS credentials -- you specified the UserID above
'OrderProcessor.UseDefaultCredentials = true;
'
'// instantiate a return item
'XOrderRet XRet = null;

Dim OrderProcessor As clsws_WSOrder
'Set OrderProcessor = New clsws_WSOrder
OrderProcessor.URL = "webservices.p3pl.com/wsorder.asmx"
OrderProcessor.Timeout = 20000
OrderProcessor.UseDefaultCredentials = True


Thanks for all your help. Any suggestions would help.

burnv84
06-12-2013, 09:17 AM
Can anyone correct this piece of code?
Error - Ojbect Variable or With Bloack variable no set. NewOrder.LineItems() = Xline()


Sub webservicetest3()

Dim NewOrder As struct_XOrder
Dim LineItems(1 To 2) As Variant
Dim Xline(1 To 2) As struct_LineItem

' Dim mystruct As struct_LineItem2
' Xline(1) = mystruct

'Set Xline(1) = New struct_LineItem

NewOrder.LineItems() = Xline()
Xline(1).ProductSKU = "abcde"
Xline(1).UnitPrice = "19.95"
Xline(1).ItemComment = "items"
Xline(1).Qty = 10

NewOrder.LineItems() = Xline()
Xline(2).ProductSKU = "daaaa"
Xline(2).UnitPrice = "20.00"
Xline(2).ItemComment = "items2"
Xline(2).Qty = 20

NewOrder.LineItems() = Xline()
Debug.Print NewOrder.ClientShortName
Debug.Print NewOrder.OrderNumber

Dim I As Integer
For I = 1 To UBound(NewOrder.LineItems)
Debug.Print NewOrder.LineItems(I).ProductSKU
Debug.Print NewOrder.LineItems(I).UnitPrice
Debug.Print NewOrder.LineItems(I).ItemComment
Debug.Print NewOrder.LineItems(I).Qty
Next I