使用VB.NET进行递归excel操作

时间:2015-07-27 15:27:24

标签: vb.net excel visual-studio visual-studio-2015

我正在使用Visual Studio 2015和VB.net,我有2个文件夹 1. C:\ phd \ unclean 2. C:\ phd \ clean

在不干净的文件夹中。我有各种子文件夹和子文件夹包含各种文件。我想在所有不干净的子文件夹和子文件夹中获取所有.csv文件,处理它们以清理它们,然后将它们输出到C:\ clean BUT中,并使用与unclean中相同的子文件夹结构。

到目前为止,这是我的代码......

    Imports Excel = Microsoft.Office.Interop.Excel
Imports System.IO
Class MainWindow
    Dim xl As Excel.Application = New Excel.ApplicationClass()
    Dim wb, wbTraj, wbForce As Excel.Workbook
    Dim ws, wsData, wsLeg As Excel.Worksheet
    Dim misValue As Object = System.Reflection.Missing.Value
    Dim iCol As Integer
    Dim iRow As Integer
    Dim trajEndRow, analogEndRow, analogDataRow, forceLegRowStart, forceLegRowEnd, forceDataRow, lastDataRow As Integer
    Dim cell, trajDataRangeSrc, trajDataRangeDest, trajLegSrc, trajLegDest, analogDataRange, forceDataRangeSrc, forceDataRangeDest, forceLegSrc, forceLegDest As Excel.Range
    Dim strName As String
    Dim blank As String
    Dim iIndex As Integer
    Dim strPath As String
    Dim strFile As String

    Private Sub button_Click(sender As Object, e As RoutedEventArgs) Handles button.Click
        If cleanRadioButton.IsChecked = True Then
            Dim list As List(Of String) = GetFilesRecursive("C:\phd\unclean")

            ' Loop through and display each path.
            For Each path In list
                clean(path)
            Next

        Else inputRadioButton.IsChecked = True
            ' do something else
        End If
        releaseObject(ws)
        releaseObject(wsData)
        releaseObject(wsLeg)
        releaseObject(wb)
        releaseObject(wbForce)
        releaseObject(wbTraj)
        releaseObject(xl)
    End Sub

Public Shared Function GetFilesRecursive(ByVal initial As String) As List(Of String)
        ' This list stores the results.
        Dim result As New List(Of String)

        ' This stack stores the directories to process.
        Dim stack As New Stack(Of String)

        ' Add the initial directory
        stack.Push(initial)

        ' Continue processing for each stacked directory
        Do While (stack.Count > 0)
            ' Get top directory string
            Dim dir As String = stack.Pop
            Try
                ' Add all immediate file paths
                result.AddRange(Directory.GetFiles(dir, "*.csv"))

                ' Loop through all subdirectories and add them to the stack.
                Dim directoryName As String
                For Each directoryName In Directory.GetDirectories(dir)
                    stack.Push(directoryName)
                Next

            Catch ex As Exception
            End Try
        Loop

        ' Return the list
        Return result
    End Function

Private Sub clean(path)
        strPath = path
        strFile = Dir(strPath & "*.csv")
        Do While strFile <> ""
            wb = xl.Workbooks.Open(Filename:=strPath & strFile)

            'Loop through the sheets.
            For iIndex = 1 To xl.ActiveWorkbook.Worksheets.Count
                ws = xl.ActiveWorkbook.Worksheets(iIndex)

                'Loop through the columns.
                For iCol = 1 To ws.UsedRange.Columns.Count
                    'Check row 10 of this column for the char of *
                    If InStr(ws.Cells(10, iCol).Value, "*") > 0 Then
                        'We have found a column with the char of *
                        xl.DisplayAlerts = False
                        ws.Columns(iCol).EntireColumn.Delete
                        ws.Columns(iCol).EntireColumn.Delete
                        ws.Columns(iCol).EntireColumn.Delete
                        iCol = iCol - 3
                    End If
                Next iCol

            Next iIndex
            wb.SaveAs(Filename:="C:\phd\clean\" & wb.Name, FileFormat:=51)
            wb.Close(SaveChanges:=False)
            strFile = Dir()
        Loop
        MessageBox.Show("The csv files have now been cleaned.  Congrats.")
    End Sub

然而,我无法让它工作,我迷失了自己。任何人都可以帮助我浏览一个结构,找到任何.csv文件,清理它然后在干净的文件夹下输出相同的文件结构并继续搜索下一个.csv文件??

令人难以置信......

THX

1 个答案:

答案 0 :(得分:2)

如果要克隆文件夹结构,单独保存目录名称似乎不够。您还需要知道每个文件夹中有哪些CSV。为此,我会保存一个List(Of FileInfo),其中包含CSV文件名和原始文件夹。收集它们:

Private myCSVList As List(Of FileInfo)

Private Sub Button_Click(sender As Object, 
      e As EventArgs) Handles Button29.Click
    myCSVList = New List(Of FileInfo)

    FindCSVs("C:\Temp")
    ' print some:
    For n As Int32 = 0 To myCSVList.Count - 1 Step 2
        Console.WriteLine(myCSVList(n).FullName)
    Next
End Sub

Private Sub FindCSVs(path As String)
    Dim di As New DirectoryInfo(path)
    ' add the csvs in THIS folder
    myCSVList.AddRange(di.EnumerateFiles("*.csv").ToArray)

    ' look for csvs in sub folders
    For Each d As DirectoryInfo In di.EnumerateDirectories
        FindCSVs(d.FullName)
    Next
End Sub

输出:

  

C:\ TEMP \ capitals.csv
  C:\ TEMP \ mycsv.csv
  C:\ TEMP \ townsinfo.csv
  C:\ TEMP \ A \ AA \ capitals.csv
  C:\ TEMP \ A \ AA \ AAA \ AAAA \ capitals.csv
  C:\ Temp \ B \ BB \ capitals.csv

现在您拥有所有CSV的ToDo列表,处理它们并将它们写回新文件夹。您应该可以在存储的路径上使用String.ReplaceC:\phd\unclean更改为C:\phd\clean。我将驱动器部分包括在内以便改变第一个外观&#34;清洁&#34;出现在路径的其他地方。

如果你需要为初始列表做一些更广泛的事情,根据日期或名称等排除一些,我可能会使用另一个Sub

...
' add the csvs in this folder
myCSVList.AddRange(LoadFiles(di))

Private Function LoadFiles(di As DirectoryInfo) As FileInfo()
    Dim thisFolder = di.EnumerateFiles("*.csv").ToList
    ' ...do stuff to remove unqualified ones
    ' ...
    Return thisFolder.ToArray

End Function