Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 393
  • Last Modified:

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.WriteAttributeString("Customer", sCustomerName)
        writer.WriteElementString("OrderTotal", CStr(dOrderTotal))
        writer.WriteElementString("Discount", CStr(dDiscountAmount))
        writer.WriteElementString("InvoiceTotal", 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
0
bamoon
Asked:
bamoon
  • 13
  • 7
  • 4
2 Solutions
 
thenrichCommented:
try this: instead of 'Invoice.OpenInvoice' Import the class that has OpenInvoice and then just call OpenInvoice from the Form
0
 
thenrichCommented:
Your trying to Access it through The Instance of Invoice and you don't need too.
0
 
bamoonAuthor Commented:
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
0
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
thenrichCommented:
You need to Dimension 'writer'. That function is not shared and therefore does not have writer in it's scope from the shared functions.
0
 
bamoonAuthor Commented:
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.
0
 
Javert93Commented:
Revert all of your code to what you started with and simply mark the WriteInvoice() and CloseInvoice() functions as Shared.
0
 
thenrichCommented:
Javert93 ,
He'd still need to Dim a writer varibale for the Public Sub WriteInvoice(ByVal writer As XmlTextWriter) sub
0
 
bamoonAuthor Commented:
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.

0
 
thenrichCommented:
you need to put a writer.close in the  Public Sub WriteInvoice(ByVal writer As XmlTextWriter)
0
 
bamoonAuthor Commented:
I tried that still the same error.
0
 
thenrichCommented:
it's very unclear to me what you are trying to even do...
It doesn't make any sense to me.
0
 
thenrichCommented:
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?
0
 
thenrichCommented:
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.WriteAttributeString("Customer", "sCustomerName")
            writer.WriteElementString("OrderTotal", CStr("dOrderTotal"))
            writer.WriteElementString("Discount", CStr("dDiscountAmount"))
            writer.WriteElementString("InvoiceTotal", 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
0
 
thenrichCommented:
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.WriteInvoice(I1.OpenInvoices))
0
 
bamoonAuthor Commented:
still getting the execption file being used.
0
 
thenrichCommented:
I can't help then, I tested the code I posted and it works fine.

0
 
thenrichCommented:
You either have the file physically open or there is someother pieace of code you are not showing.
0
 
Javert93Commented:
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.
0
 
bamoonAuthor Commented:
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.WriteAttributeString("Customer", "sCustomerName")
            writer.WriteElementString("OrderTotal", CStr("dOrderTotal"))
            writer.WriteElementString("Discount", CStr("dDiscountAmount"))
            writer.WriteElementString("InvoiceTotal", 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(ItemEntry.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(txtUnitPrice.Text), CInt(txtQuantity.Text))
        lblOrderTotal.Text = FormatNumber(Invoice.OrderTotal)
        lblDiscountAmount.Text = FormatNumber(Invoice.DiscountAmount)
        lblInvoiceTotal.Text = FormatNumber(Invoice.InvoiceTotal)

        txtUnitPrice.Text = ""
        txtQuantity.Text = ""
        txtUnitPrice.Focus()
        btnNewInvoice.Enabled = True
        InvoiceTotal(iIndex) = CDec(Me.lblInvoiceTotal.Text)
        iIndex += 1
        InvoiceArray.Add(Invoice.InvoiceTotal)


    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.OrderTotal) & _
                    ControlChars.CrLf & _
                "Discount Amount: " & _
                    FormatCurrency(Invoice.DiscountAmount) & _
                    ControlChars.CrLf & _
                "Invoice Total: " & _
                    FormatCurrency(Invoice.InvoiceTotal), , _
                "Invoice for Customer " & Invoice.CustomerName)
        Invoice.WriteInvoice(writer)
        Invoice.OrderTotal = 0
        Invoice = New Invoice()
        lblOrderTotal.Text = ""
        lblDiscountAmount.Text = ""
        lblInvoiceTotal.Text = ""
        txtCustomerName.Text = ""
        txtUnitPrice.Text = ""
        txtQuantity.Text = ""
        cmbItem.SelectedItem.Selected = False
        txtCustomerName.Focus()
        btnNewInvoice.Enabled = False
        qInvoice.Enqueue(Invoice.CustomerName & " " & FormatCurrency(Invoice.InvoiceTotal))

    End Sub

    Sub btnExit_Click(ByVal sender As Object, ByVal e As System.EventArgs)
       
        Invoice.CloseInvoices(writer)

    End Sub

    Public Sub cmbItem_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
       
        txtUnitPrice.Text = SortedItemList.Item(CInt(cmbItem.SelectedItem.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
0
 
Javert93Commented:
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.
0
 
thenrichCommented:
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.
0
 
bamoonAuthor Commented:
How do I give IUSER_ <Maching Name> permission?  The file that is created is not read only.
0
 
thenrichCommented:
Why does this seem to be the never ending question?
0
 
Javert93Commented:
To set, view, change, or remove file and folder permissions (assuming you are using Windows XP):

    1) Open Windows Explorer, and then locate the file or folder for which you want to set permissions.
    2) Right-click the file or folder, click Properties, and then click the Security tab.
    3) Click Add. In the "select users" dialog box, type the name of the group or user you want to set permissions for and then click OK (in your case, IUSR_<Machine Name>).
    4) Select the "Internet User (IUSR_<Machine Name>)" account from the list.
    5) Check the "Modify", "Read", and "Write" check boxes (all others should be unchecked).
    6) Click OK.

This is the procedure for Windows XP, but you can look in the Windows Help File for the exact procedure if you are using Windows 2000. After you set the folder permissions, you need to go into Internet Services Administrator and check the "Write" check box in the property page for the target folder (DO NOT check execute). That should allow you to write your file.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

  • 13
  • 7
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now