bamoon
asked on
Calling a shared method for XMLtextWriter
I have the following code in a class name Invoice. I am trying to call each of the below procedures from my form class by using Invoice.OpenInvoice()... getting an error "Access of a shared member through an instance". How do I call these shared methods from my form?
Shared Sub OpenInvoices()
'writes XML declaration..start tag called from load event of form
Dim writer As New XmlTextWriter(Path, Nothing)
writer.Formatting = Formatting.Indented
writer.WriteStartDocument( )
writer.WriteStartElement(" Invoices")
writer.Close()
End Sub
'writes invoice elements for each invoice click event
Public Sub WriteInvoice(ByVal writer As XmlTextWriter)
writer.WriteStartElement(" Invoice")
writer.WriteAttributeStrin g("Custome r", sCustomerName)
writer.WriteElementString( "OrderTota l", CStr(dOrderTotal))
writer.WriteElementString( "Discount" , CStr(dDiscountAmount))
writer.WriteElementString( "InvoiceTo tal", CStr(dInvoiceTotal))
writer.WriteEndElement()
End Sub
'writes end tag and closes
Shared Sub CloseInvoices()
Dim writer As New XmlTextWriter(Path, Nothing)
writer.WriteEndElement()
writer.Close()
End Sub
Shared Sub OpenInvoices()
'writes XML declaration..start tag called from load event of form
Dim writer As New XmlTextWriter(Path, Nothing)
writer.Formatting = Formatting.Indented
writer.WriteStartDocument(
writer.WriteStartElement("
writer.Close()
End Sub
'writes invoice elements for each invoice click event
Public Sub WriteInvoice(ByVal writer As XmlTextWriter)
writer.WriteStartElement("
writer.WriteAttributeStrin
writer.WriteElementString(
writer.WriteElementString(
writer.WriteElementString(
writer.WriteEndElement()
End Sub
'writes end tag and closes
Shared Sub CloseInvoices()
Dim writer As New XmlTextWriter(Path, Nothing)
writer.WriteEndElement()
writer.Close()
End Sub
try this: instead of 'Invoice.OpenInvoice' Import the class that has OpenInvoice and then just call OpenInvoice from the Form
Your trying to Access it through The Instance of Invoice and you don't need too.
ASKER
Ok that seemed to clear up that error now I have the error "Object reference not set to an instance of an object" on the line writer.WriteStartElement(" Invoice") under WriteInvoice
You need to Dimension 'writer'. That function is not shared and therefore does not have writer in it's scope from the shared functions.
ASKER
For some reason the program does not seem to be writing my top start element, error message when opening file .."XML document must have a top level element. Error processing resource 'file:..." I had dimensioned writer in the form class then changed the code to dimension in the Invoice class. But now this seems now to be a problem in OpenInvoices.
Revert all of your code to what you started with and simply mark the WriteInvoice() and CloseInvoice() functions as Shared.
Javert93 ,
He'd still need to Dim a writer varibale for the Public Sub WriteInvoice(ByVal writer As XmlTextWriter) sub
He'd still need to Dim a writer varibale for the Public Sub WriteInvoice(ByVal writer As XmlTextWriter) sub
ASKER
I changed it back and made all methods shared. now on open I get the error message System.IO.IOException: The process can not access the file because it is being used by another process. I have a module level variable Path in the invoice class and dim Path in the form class.
you need to put a writer.close in the Public Sub WriteInvoice(ByVal writer As XmlTextWriter)
ASKER
I tried that still the same error.
it's very unclear to me what you are trying to even do...
It doesn't make any sense to me.
It doesn't make any sense to me.
Make everything un-shared intantiate the class and call it by.
Invoice.CloseInvoices
Invoice.WriteInvoice
or
Invoice.OpenInvoices
Why do you even have those subs marked as shared?
Invoice.CloseInvoices
Invoice.WriteInvoice
or
Invoice.OpenInvoices
Why do you even have those subs marked as shared?
Once you have a pointer to the writer why not just keep it around:
Imports System.Xml
Public Class Invoice
Public Function OpenInvoices() As XmlTextWriter
Try
'writes XML declaration..start tag called from load event of form
Dim writer As New XmlTextWriter("Path", Nothing)
writer.Formatting = Formatting.Indented
writer.WriteStartDocument( )
writer.WriteStartElement(" Invoices")
writer.Close()
Return writer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
'writes invoice elements for each invoice click event
Public Function WriteInvoice(ByVal writer As XmlTextWriter) As XmlTextWriter
Try
writer.WriteStartElement(" Invoice")
writer.WriteAttributeStrin g("Custome r", "sCustomerName")
writer.WriteElementString( "OrderTota l", CStr("dOrderTotal"))
writer.WriteElementString( "Discount" , CStr("dDiscountAmount"))
writer.WriteElementString( "InvoiceTo tal", CStr("dInvoiceTotal"))
writer.WriteEndElement()
Return writer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
'writes end tag and closes
Public Function CloseInvoices(ByVal writer As XmlTextWriter) As Boolean
Try
writer.WriteEndElement()
writer.Close()
Return True
Catch ex As Exception
MsgBox(ex.Message)
Return False
End Try
End Function
End Class
Imports System.Xml
Public Class Invoice
Public Function OpenInvoices() As XmlTextWriter
Try
'writes XML declaration..start tag called from load event of form
Dim writer As New XmlTextWriter("Path", Nothing)
writer.Formatting = Formatting.Indented
writer.WriteStartDocument(
writer.WriteStartElement("
writer.Close()
Return writer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
'writes invoice elements for each invoice click event
Public Function WriteInvoice(ByVal writer As XmlTextWriter) As XmlTextWriter
Try
writer.WriteStartElement("
writer.WriteAttributeStrin
writer.WriteElementString(
writer.WriteElementString(
writer.WriteElementString(
writer.WriteEndElement()
Return writer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
'writes end tag and closes
Public Function CloseInvoices(ByVal writer As XmlTextWriter) As Boolean
Try
writer.WriteEndElement()
writer.Close()
Return True
Catch ex As Exception
MsgBox(ex.Message)
Return False
End Try
End Function
End Class
Works perfectly - take the:
writer.Close()
out of the OpenInvoice function and here is what I put in the form to test it:
''' Form test code
Dim I1 As New Invoice
I1.CloseInvoices(I1.WriteI nvoice(I1. OpenInvoic es))
writer.Close()
out of the OpenInvoice function and here is what I put in the form to test it:
''' Form test code
Dim I1 As New Invoice
I1.CloseInvoices(I1.WriteI
ASKER
still getting the execption file being used.
I can't help then, I tested the code I posted and it works fine.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
One of two things will cause the IO exception: either the file is open by another process (or the same process), or you do not have permission to access the file. Try downloading process explorer from http://www.sysinternals.com for the former issue, and check the security permissions on both the file and the directory for the latter issue.
ASKER
Here is all of it..the file is on my personal computer so I know it's not being used, and I do have permission to access.
'Invoice Class
Imports Microsoft.VisualBasic
Imports System.Xml
Module mItotal
Public dInvoiceTotal As Decimal
Public sCustomerName As String
Public dOrderTotal As Decimal
Public dDiscountAmount As Decimal
End Module
Public Class Invoice
Public InvInfo As InvoiceInfo
Public Property CustomerName() As String
Get
Return sCustomerName
End Get
Set(ByVal value As String)
sCustomerName = value
End Set
End Property
Public Property OrderTotal() As Decimal
Get
Return dOrderTotal
End Get
Set(ByVal value As Decimal)
dOrderTotal = value
End Set
End Property
Public ReadOnly Property DiscountAmount() As Decimal
Get
Return dDiscountAmount
End Get
End Property
Public ReadOnly Property InvoiceTotal() As Decimal
Get
Return dInvoiceTotal
End Get
End Property
Public Sub AddItem(ByVal UnitPrice As Decimal, _
ByVal Quantity As Integer)
dOrderTotal = dOrderTotal + (UnitPrice * Quantity)
dDiscountAmount = Discount(dOrderTotal)
dInvoiceTotal = dOrderTotal - dDiscountAmount
End Sub
Private Function Discount(ByVal OrderTotal As Decimal) As Decimal
Dim dDiscountPct As Decimal
Select Case OrderTotal
Case Is >= 500
dDiscountPct = 0.3
Case Is >= 200
dDiscountPct = 0.2
Case Is >= 100
dDiscountPct = 0.1
Case Else
dDiscountPct = 0
End Select
Return Math.Round(OrderTotal * dDiscountPct, 2)
End Function
Structure InvoiceInfo
Dim Cust As String
Dim OTotal As Decimal
Dim ITotal As Decimal
Dim DAmt As Decimal
End Structure
Public Function OpenInvoices(ByVal Path As String) As XmlTextWriter
Try
'writes XML declaration..start tag called from load event of form
Dim writer As New XmlTextWriter(Path, Nothing)
writer.Formatting = Formatting.Indented
writer.WriteStartDocument( )
writer.WriteStartElement(" Invoices")
'writer.Close()
Return writer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
'writes invoice elements for each invoice click event
Public Function WriteInvoice(ByVal writer As XmlTextWriter) As XmlTextWriter
Try
writer.WriteStartElement(" Invoice")
writer.WriteAttributeStrin g("Custome r", "sCustomerName")
writer.WriteElementString( "OrderTota l", CStr("dOrderTotal"))
writer.WriteElementString( "Discount" , CStr("dDiscountAmount"))
writer.WriteElementString( "InvoiceTo tal", CStr("dInvoiceTotal"))
writer.WriteEndElement()
Return writer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
'writes end tag and closes
Public Function CloseInvoices(ByVal writer As XmlTextWriter) As Boolean
Try
writer.WriteEndElement()
writer.Close()
Return True
Catch ex As Exception
MsgBox(ex.Message)
Return False
End Try
End Function
End Class
'Form Class
Option Explicit On
Imports System.Xml
Module mQ
Public qInvoice As New Queue
Public SortedItemList As New SortedList(5)
End Module
Partial Class Invoice_aspx
Dim Invoice As Invoice
Dim Path As String = "..\Invoices.xml"
Dim writer As New XmlTextWriter(Path, Nothing)
Public Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Invoice = New Invoice()
txtCustomerName.Focus()
btnNewInvoice.Enabled = False
Dim ItemEntry As DictionaryEntry
If SortedItemList.Count = 0 Then
SortedItemList.Add(1000, 19.95)
SortedItemList.Add(2000, 9.95)
SortedItemList.Add(3000, 29.95)
SortedItemList.Add(4000, 69.95)
SortedItemList.Add(5000, 129.95)
For Each ItemEntry In SortedItemList
cmbItem.Items.Add(ItemEntr y.Key)
Next
End If
Invoice.OpenInvoices(Path)
End Sub
Private Sub btnadditem_click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAddItem.Click
Invoice.AddItem(CDec(txtUn itPrice.Te xt), CInt(txtQuantity.Text))
lblOrderTotal.Text = FormatNumber(Invoice.Order Total)
lblDiscountAmount.Text = FormatNumber(Invoice.Disco untAmount)
lblInvoiceTotal.Text = FormatNumber(Invoice.Invoi ceTotal)
txtUnitPrice.Text = ""
txtQuantity.Text = ""
txtUnitPrice.Focus()
btnNewInvoice.Enabled = True
InvoiceTotal(iIndex) = CDec(Me.lblInvoiceTotal.Te xt)
iIndex += 1
InvoiceArray.Add(Invoice.I nvoiceTota l)
End Sub
Private Sub btnNewInvoice_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnNewInvoice.Click
Invoice.CustomerName = txtCustomerName.Text
MsgBox("Order Total: " & _
FormatCurrency(Invoice.Ord erTotal) & _
ControlChars.CrLf & _
"Discount Amount: " & _
FormatCurrency(Invoice.Dis countAmoun t) & _
ControlChars.CrLf & _
"Invoice Total: " & _
FormatCurrency(Invoice.Inv oiceTotal) , , _
"Invoice for Customer " & Invoice.CustomerName)
Invoice.WriteInvoice(write r)
Invoice.OrderTotal = 0
Invoice = New Invoice()
lblOrderTotal.Text = ""
lblDiscountAmount.Text = ""
lblInvoiceTotal.Text = ""
txtCustomerName.Text = ""
txtUnitPrice.Text = ""
txtQuantity.Text = ""
cmbItem.SelectedItem.Selec ted = False
txtCustomerName.Focus()
btnNewInvoice.Enabled = False
qInvoice.Enqueue(Invoice.C ustomerNam e & " " & FormatCurrency(Invoice.Inv oiceTotal) )
End Sub
Sub btnExit_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Invoice.CloseInvoices(writ er)
End Sub
Public Sub cmbItem_SelectedIndexChang ed(ByVal sender As Object, ByVal e As System.EventArgs)
txtUnitPrice.Text = SortedItemList.Item(CInt(c mbItem.Sel ectedItem. Value))
End Sub
End Class
Module mInvoice
Public InvoiceTotal(4) As Decimal
Public iIndex As Integer
Public dInvoiceTotal As Decimal
Public InvoiceArray As New ArrayList(4)
End Module
'Invoice Class
Imports Microsoft.VisualBasic
Imports System.Xml
Module mItotal
Public dInvoiceTotal As Decimal
Public sCustomerName As String
Public dOrderTotal As Decimal
Public dDiscountAmount As Decimal
End Module
Public Class Invoice
Public InvInfo As InvoiceInfo
Public Property CustomerName() As String
Get
Return sCustomerName
End Get
Set(ByVal value As String)
sCustomerName = value
End Set
End Property
Public Property OrderTotal() As Decimal
Get
Return dOrderTotal
End Get
Set(ByVal value As Decimal)
dOrderTotal = value
End Set
End Property
Public ReadOnly Property DiscountAmount() As Decimal
Get
Return dDiscountAmount
End Get
End Property
Public ReadOnly Property InvoiceTotal() As Decimal
Get
Return dInvoiceTotal
End Get
End Property
Public Sub AddItem(ByVal UnitPrice As Decimal, _
ByVal Quantity As Integer)
dOrderTotal = dOrderTotal + (UnitPrice * Quantity)
dDiscountAmount = Discount(dOrderTotal)
dInvoiceTotal = dOrderTotal - dDiscountAmount
End Sub
Private Function Discount(ByVal OrderTotal As Decimal) As Decimal
Dim dDiscountPct As Decimal
Select Case OrderTotal
Case Is >= 500
dDiscountPct = 0.3
Case Is >= 200
dDiscountPct = 0.2
Case Is >= 100
dDiscountPct = 0.1
Case Else
dDiscountPct = 0
End Select
Return Math.Round(OrderTotal * dDiscountPct, 2)
End Function
Structure InvoiceInfo
Dim Cust As String
Dim OTotal As Decimal
Dim ITotal As Decimal
Dim DAmt As Decimal
End Structure
Public Function OpenInvoices(ByVal Path As String) As XmlTextWriter
Try
'writes XML declaration..start tag called from load event of form
Dim writer As New XmlTextWriter(Path, Nothing)
writer.Formatting = Formatting.Indented
writer.WriteStartDocument(
writer.WriteStartElement("
'writer.Close()
Return writer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
'writes invoice elements for each invoice click event
Public Function WriteInvoice(ByVal writer As XmlTextWriter) As XmlTextWriter
Try
writer.WriteStartElement("
writer.WriteAttributeStrin
writer.WriteElementString(
writer.WriteElementString(
writer.WriteElementString(
writer.WriteEndElement()
Return writer
Catch ex As Exception
MsgBox(ex.Message)
Return Nothing
End Try
End Function
'writes end tag and closes
Public Function CloseInvoices(ByVal writer As XmlTextWriter) As Boolean
Try
writer.WriteEndElement()
writer.Close()
Return True
Catch ex As Exception
MsgBox(ex.Message)
Return False
End Try
End Function
End Class
'Form Class
Option Explicit On
Imports System.Xml
Module mQ
Public qInvoice As New Queue
Public SortedItemList As New SortedList(5)
End Module
Partial Class Invoice_aspx
Dim Invoice As Invoice
Dim Path As String = "..\Invoices.xml"
Dim writer As New XmlTextWriter(Path, Nothing)
Public Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Invoice = New Invoice()
txtCustomerName.Focus()
btnNewInvoice.Enabled = False
Dim ItemEntry As DictionaryEntry
If SortedItemList.Count = 0 Then
SortedItemList.Add(1000, 19.95)
SortedItemList.Add(2000, 9.95)
SortedItemList.Add(3000, 29.95)
SortedItemList.Add(4000, 69.95)
SortedItemList.Add(5000, 129.95)
For Each ItemEntry In SortedItemList
cmbItem.Items.Add(ItemEntr
Next
End If
Invoice.OpenInvoices(Path)
End Sub
Private Sub btnadditem_click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnAddItem.Click
Invoice.AddItem(CDec(txtUn
lblOrderTotal.Text = FormatNumber(Invoice.Order
lblDiscountAmount.Text = FormatNumber(Invoice.Disco
lblInvoiceTotal.Text = FormatNumber(Invoice.Invoi
txtUnitPrice.Text = ""
txtQuantity.Text = ""
txtUnitPrice.Focus()
btnNewInvoice.Enabled = True
InvoiceTotal(iIndex) = CDec(Me.lblInvoiceTotal.Te
iIndex += 1
InvoiceArray.Add(Invoice.I
End Sub
Private Sub btnNewInvoice_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnNewInvoice.Click
Invoice.CustomerName = txtCustomerName.Text
MsgBox("Order Total: " & _
FormatCurrency(Invoice.Ord
ControlChars.CrLf & _
"Discount Amount: " & _
FormatCurrency(Invoice.Dis
ControlChars.CrLf & _
"Invoice Total: " & _
FormatCurrency(Invoice.Inv
"Invoice for Customer " & Invoice.CustomerName)
Invoice.WriteInvoice(write
Invoice.OrderTotal = 0
Invoice = New Invoice()
lblOrderTotal.Text = ""
lblDiscountAmount.Text = ""
lblInvoiceTotal.Text = ""
txtCustomerName.Text = ""
txtUnitPrice.Text = ""
txtQuantity.Text = ""
cmbItem.SelectedItem.Selec
txtCustomerName.Focus()
btnNewInvoice.Enabled = False
qInvoice.Enqueue(Invoice.C
End Sub
Sub btnExit_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Invoice.CloseInvoices(writ
End Sub
Public Sub cmbItem_SelectedIndexChang
txtUnitPrice.Text = SortedItemList.Item(CInt(c
End Sub
End Class
Module mInvoice
Public InvoiceTotal(4) As Decimal
Public iIndex As Integer
Public dInvoiceTotal As Decimal
Public InvoiceArray As New ArrayList(4)
End Module
This is an ASP.NET application? The most likely problem is that IUSER_<Machine Name> does not have access to the file. You need to explicitly give this account write permissions on the folder and file before you can access it. Under a default installation, anonymous reuqests to a Web Application run under the IUSER_<Machine Name> account, which does not have permission to write to the file system (note that you need to replace <Machine Name> with the name of your computer). Also, watch out for the execute permission (especially if the file is accessible from IIS), because that could allow a remote user to write an executable to the directory and execute it.
Yea - he's right. Depending on which OS your using if you right mouse click on the directory you should find a tab to allow you to set ASP.NET permissions.
ASKER
How do I give IUSER_ <Maching Name> permission? The file that is created is not read only.
Why does this seem to be the never ending question?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.