Link to home
Start Free TrialLog in
Avatar of gcargile
gcargile

asked on

(VB.NET) Make a class/form global - Newbie:) Help....

I'm stupid when it comes to sharing classes (well just general sharing between forms classes etc).  I created a class to Export results of a datagrid to Excel and I need to use it in my main form and use part of my main form which I was able to share sorta.

Quick Info:
AA is my main form
GlobalForm is how I shared it somehow - which works in another class I have
dgResults is my datagrid located  on my AA form
row is declared in a separate class:  Public Class ACheck     (Dim row as DataRow)

In my main form I call ....
Private Shared EE As New ExportExcel()

EE.Export_To_Excel(row)   Not sure how to pass "row" from ACheck

My Class:
Public Class ExportExcel
   Sub Export_To_Excel(ByVal dr as DataRow)
        Dim oExcel As New Excel.Application()
        Dim oBooks As Excel.Workbooks
        Dim oBook As Excel.Workbook
        Dim oSheets As Excel.Sheets
        Dim oSheet As Excel.Worksheet
        Dim oCells As Excel.Range
        oExcel.Application.SheetsInNewWorkbook = 1

        oExcel.Visible = True

        ' Get a new workbook
        oBooks = oExcel.Workbooks
        oBook = oBooks.Add
        oSheets = oBook.Worksheets
        oSheet = oSheets(1)
        oSheet.Name = "Results"
        oCells = oSheet.Cells

        oCells(1, 1) = "Testing"      But of  couse I need this to export each field
        'oBook.Close() Close the workbook

        Dim rcnt As Integer
        Dim clcnt As Integer
        rcnt = 1
        For Each row In AA.GlobalForm.dgResults.Items                   ... So, I tried here.  The AA.GlobalForm.dgResults.Items isn't valid
            For clcnt = 0 To row.Cells.Count - 1
                clval = row.Cells(0).Text.ToString
                oSheet.Cells(rcnt, clcnt).value = clval
            Next
            rcnt = rcnt + 1
        Next

        ' Save the sheet to Sites directory.
        oSheet.SaveAs("CID.xls")

        'Quit
        'oExcel.Quit() Close Excel

        oExcel = Nothing
        oBooks = Nothing
        oBook = Nothing
        oSheets = Nothing
        oSheet = Nothing
        oCells = Nothing

THANKS!!! For all your help!!!!
Avatar of morphinex
morphinex

Here's a quick and dirty suggestion on how you can pass in the reference of the main form into your class object.  This is probably not considered object oriented programming, but just a simple solution to do what needs to be done.  

In Public Class ExportExcel, add in a "new" constructor that you can pass in the reference of where the caller is at...

>>>>>>>
Public Class ExportExcel
    Public Sub New(ByVal caller As Object)
        MyBase.New()
        theCaller = caller
    End Sub

    private theCaller as Object

   Sub Export_To_Excel(ByVal dr as DataRow)
       Dim oExcel As New Excel.Application()
       Dim oBooks As Excel.Workbooks
       .
       .
       .
<<<<<<<

Then, when it's time to call on the form for the datagrid stuff...

>>>>>>>


       For Each row In CType(theCaller, theFormName).GlobalForm.dgResults.Items                   ... So, I tried here.  The AA.GlobalForm.dgResults.Items isn't valid
           For clcnt = 0 To row.Cells.Count - 1
               clval = row.Cells(0).Text.ToString
               oSheet.Cells(rcnt, clcnt).value = clval
           Next
           rcnt = rcnt + 1
       Next

<<<<<<<<

theFormName is what your form's class object name is... you should see a huge list of what type you want to cast "theCaller" in.. just pick the class that AA is.  That should reveal the public variable GlobalForm within the AA, and then the dgResults from that...  

Hope this helps!

Avatar of gcargile

ASKER

I did this in my main form (AA) and I can access AA.GlobalForm.....   ex: AA.GlobalForm.rtbAnsi.Text  (just not AA.GlobalForm.dgResults.Items)  It has Item, but not Items ?  I know this part works.  I don't really understand the code above.

Is there not a command in each Class I can type in just to share it?

#Region "Global Form"
    Private Shared m_GlobalForm As AA
    Public Shared Property GlobalForm() As AA
        Get
            If m_GlobalForm Is Nothing OrElse m_GlobalForm.IsDisposed Then
                m_GlobalForm = New AA()
            End If
            Return m_GlobalForm
        End Get
        Set(ByVal Value As AA)
            m_GlobalForm = Value
        End Set
    End Property

#End Region
Refer to http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vbls7/html/vblrfvbspec4_5.asp for different access types.  When you create a "Private Shared", its domain is limited, so you can't really "just share" the program as you desire.  It all depends on where you put stuff exactly.  

My code above is to pass in the reference of the class to another class, so you could refer to it.  When you instantiate a new class object, with Private Shared EE As New ExportExcel(), you could pass in the reference to the current object via

Private Shared EE As New ExportExcel(Me)

By having that, you get unlimited access to whatever you want from the form.  Try out the code and you'd see!
Humm...  Still a little confusing... but also let me explain what form/class has what in it - because I can't quite use your code above.

AA(form) - has GlobalForm declared... need to call ExportExcel here.
ACheck (class)- does not have a form, just code only, it adds everything to the DataGrid
ExportExcel(class) - no form, just export code

AA needs to call ExportExcel
ExportExcel needs to call ACheck for the DataGrid info  (ds as Dataset, tbl as DataTable, row as DataRow...)


So, when I'm in ExportExcel:
        For Each CType(CallAcheck, DontKnowFormNameUnlessAA) In AA.GlobalForm.dgResults.Items
            For clcnt = 0 To row.Cells.Count - 1
                clval = row.Cells(0).Text.ToString
                oSheet.Cells(rcnt, clcnt).value = clval
            Next
            rcnt = rcnt + 1
        Next


Note:  I placed your code in both ACheck and ExportExcel naming the call's CallACheck and CallEE and from CallACheck to .Items (above) errors.  
I call AA.GlobalForm.everything... fine from ACheck, maybe "Items" is not valid.

I really appreciate your help... I'm going to increase the points if I can!  THANKS!
Hiya,

The question wasn't on the datagrid, so I didn't really look at the code you had for the dgResults.

If I'm understanding you correctly, you are instantiating two different "AA" forms.  The one is the "main" form, the other is the "globalForm"  The "main" form is instantiated when the program starts, and as soon as the "main" form starts, it'd instantiate the "globalform."   The mainForm will contain the "Globalform."  And this "globalform" is a publically shared object that all your other classes are able to access.  Correct me if I'm wrong... I just woke up  =)

Anyway, if this is the case, try this...  

Get rid of the GlobalForm variable.  You don't need it in I think.  And try this...

>>>>>>>>>>>>>>>>>>

In my main form I call ....
'The old one
'Private Shared EE As New ExportExcel()
'You are passing in the reference of "AA" into the class "ExportExcel"  So that the class "ExportExcel" would be able to use
'The methods and variables within "AA."  Me is a reference to the caller itself.

Private Shared EE As New ExportExcel(Me)

'If we are going to pass in the entire datagrid, no need to pass in a single row
'EE.Export_To_Excel(row)   Not sure how to pass "row" from ACheck
EE.Export_To_Excel()

My Class:
Public Class ExportExcel
      Public Sub New(ByVal caller As AA)
            MyBase.New()
            'When the class ExportExcel is first instantiated, it'd store the reference of the caller into a private variable
            'ExportExcel would be able to use this reference throughout.
            theCaller = caller
      End Sub

      private theCaller as AA

        'We don't even need to pass in the dataRow if we are going to use the entire datagrid.  So let's get rid of that
      'Sub Export_To_Excel(ByVal dr as DataRow)
      Sub Export_To_Excel()
            Dim oExcel As New Excel.Application()
            Dim oBooks As Excel.Workbooks
            Dim oBook As Excel.Workbook
            Dim oSheets As Excel.Sheets
            Dim oSheet As Excel.Worksheet
            Dim oCells As Excel.Range
            oExcel.Application.SheetsInNewWorkbook = 1

            oExcel.Visible = True

            ' Get a new workbook
            oBooks = oExcel.Workbooks
            oBook = oBooks.Add
            oSheets = oBook.Worksheets
            oSheet = oSheets(1)
            oSheet.Name = "Results"
            oCells = oSheet.Cells

            oCells(1, 1) = "Testing"      But of  couse I need this to export each field
            'oBook.Close() Close the workbook

            Dim rcnt As Integer
            Dim clcnt As Integer
            rcnt = 0

            'This depends on what you assigned as datasource to the datagrid
            'Normally, people use DataSet, so this is what I'd assume here
            'You have to initialize the datatype of the variable row first though
            'It is gonna have the datatype of DataRow
            Dim drDataRow as DataRow

            'Also, you can't just count the # of cells to represent the number of columns,
            'you' have to use the DataTable to see how many columns there are

            Dim dcDataColumn as DataColumn

            'Since you are using the DataTable extensively, we'd assign a variable for it

            Dim dtDataTable as DataTable = CType(AA.dgResults.DataSource, DataSet).Tables(0)

            For Each drDataRow In dtDataTable.Rows
                  For each dcDataColumn in dtDataTable.Columns
                        'Variable "clval" is not instantiated, will give ya an error unless this is a global var
                        'But, we don't really need it anyway.
                        'clval = row.Cells(0).Text.ToString

                        'oSheet.Cells(rcnt, clcnt).value = clval

                        'rcnt is the Row Counter, dcDataColumn.Ordinal returns what number the
                        'the column belongs in.

                        'drDataRow is the current dataRow, and it has a method where if you pass
                        'In the DataColumn that you are looking at, it'd return the cell you want.

                        oSheet.Cells(rcnt, dcDataColumn.Ordinal).value = drDataRow(dcDataColumn).ToString
                  Next
                  rcnt = rcnt + 1
            Next
                  
            ' Save the sheet to Sites directory.
            oSheet.SaveAs("CID.xls")

            'Quit
            'oExcel.Quit() Close Excel

            oExcel = Nothing
            oBooks = Nothing
            oBook = Nothing
            oSheets = Nothing
            oSheet = Nothing
            oCells = Nothing
      End sub

<<<<<<<<<<<<<<<<<

There is no Items property in dgResults.  I didn't catch that before, sorry =(  There is an item property, that would return the specific cel according to row and column values.

ie..

'strCell will have the value inside Row 5, Column 2 within the datagrid
dim strCell as String = dgResults(5)(2)

Visit http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwindowsformsdatagridclasstopic.asp for more information on DataGrids

I tried your code and got an error on :
oSheet.Cells(rcnt, dcDataColumn.Ordinal).value = drDataRow(dcDataColumn).ToString

An unhandled exception of type
'System.Runtime.InteropServices.COMException' occurred in mscorlib.dll

Additional information: Exception from HRESULT: 0x800A03EC.
ASKER CERTIFIED SOLUTION
Avatar of mondayblueboy
mondayblueboy

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

Almost forgot, don't forget to add reference to Microsoft Excel Object Library.

Cheers
It's been there.  The spreadsheet opens and writes the "Testing" in it and the error pops up.
Heh, I tried my best but I hate any error messages with "HRESULT: 0x800A03EC" ~ our own app is still plagued with it!

mondayblueboy, give it your all

Best of luck =)

Thanks morphinex :o)

>> I tried your code and got an error on :
>> oSheet.Cells(rcnt, dcDataColumn.Ordinal).value = drDataRow(dcDataColumn).ToString
gcargile,
You can't use the code above, I have tested it and I got the same error either from morphinex's code or your original code. That's why I modified, and of course tested, it . And I managed to export the datagrid rows perfectly. Maybe you confuse how to use it, let me explain.

From your last comment I tried to understand, it seems you don't really need to pass the datagrid object. Because the datagrid has its data source from AACheck. So you call the export_to_excel from AA(form) something like:

       Dim sDestinationFile = "C:\Temp\Test.xls"
       Dim ee As New ExportExcel()
       ee.Export_To_Excel(CType(GlobalForm.dgResults.DataSource, System.Data.DataTable), sDestinationFile)

If you think I'm wrong please clarify.
Thanks.
You guys are awesome....  I cut and pasted your exact code mondayblueboy and got the following error.

An unhandled exception of type 'System.InvalidCastException' occurred in AANet.exe

Additional information: Specified cast is not valid.

This is in my AA(form)
    Private Sub mnuExpToExcel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuExpToExcel.Click
        Dim sDestinationFile = "C:\Temp\Test.xls"
        EE.Export_To_Excel(CType(dgResults.DataSource, System.Data.DataTable), sDestinationFile)    ' On this line
    End Sub

I pasted your code above to ExportExcel (class).
Sorry for late response, I couldn't reach this website for few hours.
At which line the code giving you the exception?

I didn't reach your last comment, sorry. try this instead (but if you are not using DataSet for data binding please let me know).


   Private Sub mnuExpToExcel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles mnuExpToExcel.Click

       Dim dsData As System.Data.DataSet = CType(dgResults.DataSource, System.Data.DataSet)
       Dim sDestinationFile = "C:\Temp\Test.xls"
       EE.Export_To_Excel(dsData.Tables(0), sDestinationFile)

   End Sub
I couldn't connect to ExpertsExchange.com either on/off for hours....

But I did find that piece on the web somewhere.  This is what I used:
EE.Export_To_Excel(CType(dgResults.DataSource, DataSet).Table(0), sDestinationFile)

Which may do the exact thing you did above:
It said I must have already been connected to the DataSet or something like that.

THANKS FOR ALL YOUR HELP!!!!