Link to home
Start Free TrialLog in
Avatar of sirbounty
sirbountyFlag for United States of America

asked on

build temporary list

I'm just trying to formulate this in my head, so bear with me while I explain it...

I have one app that I currently use to scan a remote share for certain file types and write the results into an excel spreadsheet - each file's path, size and date(s) (creation/last written/last accessed), along with a summary of all file types (results for MDB, ZIP, etc).

I have another app that I'm working on incorporating that same function, but I want to change it just a bit...
For starters, I don't want to create the spreadsheet...yet.
I'd like to generate the same sort of results in, maybe an array of some sort?  or a grid? (I'm fuzzy here) - but still be able to write the output to a spreadsheet if the user determines that's what they want.
In this app, either way, I would be passing that file-type summary data onto an email template for the user to send to the share owner.

Any thoughts to help guide me on this one?
ASKER CERTIFIED SOLUTION
Avatar of Sancler
Sancler

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
Avatar of sirbounty

ASKER

Cool - let me try to work this out based upone the ideas you've presented...I'll let you know.  Thanx!
Here's what I've come up with - though I'm hitting my 'favorite' error again where noted:

    Private Function Scanit(ByVal pFolder As String) As DataSet
        Dim strPath As String = System.AppDomain.CurrentDomain.BaseDirectory
        Dim arrFileTypes() As String, ext As String, x As Int16
        arrFileTypes = Split("ASF,AVI,BMP,EXE,JPG,MDB,PST,ZIP", ",")
        Dim strtDT As DateTime = DateTime.Now
        Dim dtExt As DataTable = New DataTable
        Dim FileName As New DataColumn, FileSize As New DataColumn, CreationDate As New DataColumn
        Dim LastAccessed As New DataColumn, LastWritten As New DataColumn, FileType As New DataColumn
        Dim dr As DataRow = Nothing
        With dtExt.Columns
            .Add(FileName)
            .Add(FileSize)
            .Add(CreationDate)
            .Add(LastAccessed)
            .Add(LastWritten)
            .Add(FileType)
        End With
        Dim d() As String = Nothing
        Try
            d = Directory.GetFiles(pFolder, "*.*", SearchOption.AllDirectories)
        Catch ex As Exception
            MessageBox.Show(Err.Description)
        End Try

        Dim en As Collections.IEnumerator
        Dim fileInfo As FileInfo
        en = d.GetEnumerator
        While en.MoveNext
            x += 1
            For Each ext In arrFileTypes
                If UCase(en.Current.ToString.Substring(Len(en.Current) - 3)) = ext Then
                    Try
                        fileInfo = New FileInfo(en.Current)
                        With dr
                            .Item(0) = Replace(en.Current, pFolder, "")  <=======object reference not set to instance...
                            .Item(1) = fileInfo.Length
                            .Item(2) = fileInfo.CreationTime.Date
                            .Item(3) = fileInfo.LastAccessTime.Date
                            .Item(4) = fileInfo.LastWriteTime.Date
                            .Item(5) = ext
                        End With
                    Catch ex As Exception
                        MessageBox.Show(Err.Description)
                    End Try
                End If
            Next
        End While
        Dim dsScan As New DataSet
        dsScan.Tables.Add(dtExt)
        Return dsScan
Avatar of Sancler
Sancler



        Dim dr As DataRow = Nothing
        '[...]
                        With dr
                            .Item(0) = Replace(en.Current, pFolder, "")  <=======object reference not set to instance...

Do you wonder?

What happened to

   Dim dr As DataRow = FileTable.NewRow
   '[...]
   FileTable.Rows.Add(dr)

from the sample code?

So far as I can see, it should work with that amendment.  

Two thoughts, though.  Depending on precisely how you subsequently need to use the data, you might have later problems having left all columns' datatypes as the default (which is string).  And I wonder why you get your function to return a dataset, into which you put the datatable you have created, rather than just returning the datatable itself.  Datatables don't have to go in Datasets to be usable, and I can see no good reason for putting this in one.

Roger
I say cant beat good old collections. You can add any object (like a Fileinfo class) you like to a collection and ctype it back on the way out.

Much simpler but i suppose it all depends on what you want to do with it *afterwards*...
So, I should just return the table?
I did a little searching afterwards and mimiced 'that' code, as I initially had problems with the .NewRow being 'recognized' (it's working now, however).

lojk - I'm not sure what you mean by using collections - that's a bit outside my current skillset, I'm afraid.
Okay - the table was built - I saw it process at least 1 row, but the returned table's count property is 0.
How do I access the rows to read them?
SOLUTION
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
>>Assuming that its signature has been changed to read
    Private Function Scanit(ByVal pFolder As String) As DataTable << 

it has

>>and the line at the end has been changed to
        Return dtExt<<

it has

>>the calling code should be something like
   Dim FileTable As DataTable = Scanit(<mypath>)<<

Currently it's:
    Dim dtScan As DataTable
        dtScan = Scanit(strShare)


Then I have

        For Each dr As DataRow In dtScan.Rows
            Dim FilePath As String = dr(0)
            Dim FileSize As String = dr(1)
            Dim FileCreation As String = dr(2)
            Dim FileAccess As String = dr(3)
            Dim FileModify As String = dr(4)
            Dim FileExt As String = dr(5)
        Next

but, the 'count' still comes back as 0 (when it's not) and it skips this for loop...
SOLUTION
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
msgbox(dtScan)  already says 'datatable cannot be converted to string'
but even the first is 0, so that would be 'why'...
Now 'why' isn't it getting into the table?  Hmm...
My fault.  I meant

   msgbox(dtScan.Rows.Count)

Roger

My guess is that this line

   FileTable.Rows.Add(dr)

or the equivalent in your terminology, is missing.

Roger
SOLUTION
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
Roger -
where should
dtExt.Rows.Add(dr)
be placed?
I'm getting an error "this row already belongs to this table"
working now...
I adjusted the following:

                    Try
                        fileInfo = New FileInfo(en.Current)
                        Dim dr As DataRow = dtExt.Rows.Add

and it's working now.
OK, if you've sorted it

But what you had was

        Dim en As Collections.IEnumerator
        Dim fileInfo As FileInfo
        en = d.GetEnumerator
        While en.MoveNext
            x += 1
            For Each ext In arrFileTypes
                If UCase(en.Current.ToString.Substring(Len(en.Current) - 3)) = ext Then
                    Try
                        fileInfo = New FileInfo(en.Current)
                        With dr
                            .Item(0) = Replace(en.Current, pFolder, "")  <=======object reference not set to instance...
                            .Item(1) = fileInfo.Length
                            .Item(2) = fileInfo.CreationTime.Date
                            .Item(3) = fileInfo.LastAccessTime.Date
                            .Item(4) = fileInfo.LastWriteTime.Date
                            .Item(5) = ext
                        End With
                    Catch ex As Exception
                        MessageBox.Show(Err.Description)
                    End Try
                End If
            Next
        End While

What I'd given you was

   Dim dr As DataRow = FileTable.NewRow '<<< THIS LINE WAS MISSING
   dr("Path") = <thisPath>
   dr("FileType") = <thisFileType>
   dr("FileSize") = <thisFileSize>
   'etc
   FileTable.Rows.Add(dr) '<<< THIS LINE WAS MISSING

Your code, to be equivalent to mine, should have been

                        Dim dr As DataRow = dtExt.NewRow
                        With dr
                            .Item(0) = Replace(en.Current, pFolder, "")  <=======object reference not set to instance...
                            .Item(1) = fileInfo.Length
                            .Item(2) = fileInfo.CreationTime.Date
                            .Item(3) = fileInfo.LastAccessTime.Date
                            .Item(4) = fileInfo.LastWriteTime.Date
                            .Item(5) = ext
                        End With
                        dtExt.Rows.Add(dr)

Incidentally, (1) I'm not sure how the code you put in your last post would make anything work

                        Dim dr As DataRow = dtExt.Rows.Add

doesn't look like a valid statement to me.  And (2) lojk has a good point.  I offered you a datatable as your temporary array as I know you're getting used to working with them.  But there's all sorts of other mainfestations of Collections which would be just as good - or for many purposes, better.

Still, so long as you're happy ;-)  Thanks for the points.

Roger

The old KISS principle always applies especially in VB (c# forces you by its syntax to be a little more explicit sometimes).

I suppose it depends for what you are writing the code. For my home/personal projects I am a total Purist, prefering long winded and strongly typed code where possible but in commercial development, whatever works quickly and simply is what i tend to end up doing. (Perhaps thats why none of my home projects never get finsihed!).

Thanks for points BTW
I liked the idea lojk - but since I felt the momentum with the datatable, and as Roger pointed out, have been becoming more familiar with them, went more in that direction.
Perhaps not the best route, but so far so good...it's working.

Thanx to you both.
Hey, cool. As long as your code is broken down into manageable sized blocks you can always come back later and refactor it without affecting other code. Only really wanted to give you another option because as im sure you are realising there is ALWAYS more than one way to do these things.

:-)
Yep.
The more I play with this though, the more I'm thinking of redoing it anyway...keep an eye out. :^)