将多个子子文件夹中的所有.TXT文件导入到单独的工作簿中

时间:2014-01-24 23:17:31

标签: vba loops excel-vba import excel

对于VBA我是一个新手,所以非常感谢任何帮助,我有一个宏列出了指定根目录C:Users\Abubakar Adan\JSIM\Ic=340uA\中所有子文件夹和子子文件夹,这些子文件包含101个.txt文件。编号1-101我现在的问题是我现在需要将子文件夹的内容即.TXT文件以真正的时间顺序导入到单个工作簿中,即在运行代码之后,每个包含.TXT文件的子文件夹现在都有一个新的工作簿,它本身将按照真正的时间顺序包含导入的.TXT数据

欢迎任何有关修改我的宏或建议新宏的帮助。老实说,任何帮助都是真的很感激,并提前感谢您花时间阅读本文,再次感谢任何帮助。这是创建的演示文件Link

的链接
     Option Explicit

' * These routines use File System Object.  For the easiest use of File System
'   Objects, it is necessary to create a reference to the Microsoft Scripting
'   Runtime as follows:
'     1) Open the Visual Basic Editor.
'     2) Select Tools, from the tool bar, then References.
'     3) You will get a long list of available references of which a few will be
'        ticked.
'     4) The list is in alphabetic sequence.  Scroll down the list looking for
'        "Microsoft Scripting Runtime".  Tick the box against it and then click OK.
'     5) Select Tools, from the tool bar, then References again.  Check that
'        "Microsoft Scripting Runtime" is one of the ticked references at the top.
'        If it is not, you did not perform step 4 correctly.

Sub CtrlSearch()

  Dim FlSys As FileSystemObject
  Dim FlTextOut As TextStream
  Dim PathCrnt As String
  Dim PathSearchRoot As String

  PathCrnt = ActiveWorkbook.Path

  Set FlSys = CreateObject("Scripting.FileSystemObject")
  Set FlTextOut = FlSys.CreateTextFile(PathCrnt & "\Demo.txt")

  PathSearchRoot = "C:\Users\Abubakar Adan\JSIM\Ic=340uA"

  ' ### Replace "C:\DataArea\Play" with the full name of the folder to search.

  Call SearchSingleFolder(PathSearchRoot, 0, FlTextOut)

  FlTextOut.Close

End Sub
Sub SearchSingleFolder(ByVal PathSearch As String, ByVal Lvl As Long, _
                       ByRef FlTextOut As TextStream)

  ' PathSearch  A path to be searched.
  ' Lvl         The level of this call.  Used to control indenting
  ' FlTextOut   The file object for the text file to which paths and
  '             files are to be output

  ' * When this routine is called by CtrlSearch, PathSearch will be the root of
  '   the folders to be searched and Lvl will be 0.
  ' * When this routine is called by itself, PathSearch will be a sub-folder
  '   or a sub-sub-folder of the root folders to be searched and Lvl will be 1 for
  '   a sub-folder, 2 for a sub-sub-folder and so on.
  ' * This routine outputs PathSearch to the output file following by the names of
  '   the files within it.
  ' * The routine then calls itself for each sub-folder of PathSearch.

  Dim Fldr As Folder
  Dim FldrSubCrnt As Folder
  Dim FlCrnt As File
  Dim FlSys As FileSystemObject
  Dim ws As Worksheet

  Set FlSys = CreateObject("Scripting.FileSystemObject")

  FlTextOut.WriteLine (Space(Lvl * 2) & PathSearch)

  ' ### This routine is called for the root folder and every folder within
  ' ### the root folder.  If any folder level processing is required, it must
  ' ### be added here.  PathSearch is the current folder name.

  Set Fldr = FlSys.GetFolder(PathSearch)

  For Each FlCrnt In Fldr.Files
    FlTextOut.WriteLine (Space(Lvl * 2 + 4) & FlCrnt.Name)

      ' ### This loop will process every file within the root folder and every
      ' ### folder within the root folder.  The full name of the file is:
      ' ###    PathSearch & "\" & FlCrnt.Name
      ' ### If the folders may contain files that are not to be processed, code
      ' ### must be included to exclude such files.  For example, if you only want
      ' ### to process text files you need something like:
If LCase(Right(FlCrnt.Name, 4)) = ".TXT" Then
Set ws = Sheets.Add
With ws.QueryTables.Add(Connection:= _
    "TEXT;" & "PathSearch, & FlCrnt.Name", Destination:=Range("$A$2")) 'The import code does nothing, I was hoping to import every subsubflder to its own workbook
        .Name = FlCrnt.Name
        .FieldNames = True
        .RowNumbers = False
        .FillAdjacentFormulas = False
        .PreserveFormatting = True
        .RefreshOnFileOpen = False
        .RefreshStyle = xlInsertDeleteCells
        .SavePassword = False
        .SaveData = True
        .AdjustColumnWidth = True
        .RefreshPeriod = 0
        .TextFilePromptOnRefresh = False
        .TextFilePlatform = 1251
        .TextFileStartRow = 1
        .TextFileParseType = xlDelimited
        .TextFileTextQualifier = xlTextQualifierDoubleQuote
        .TextFileConsecutiveDelimiter = True
        .TextFileTabDelimiter = True
        .TextFileSemicolonDelimiter = False
        .TextFileCommaDelimiter = False
        .TextFileSpaceDelimiter = True
        .TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, _
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
        .TextFileTrailingMinusNumbers = True
        .Refresh BackgroundQuery:=False
End With
 End If

  Next

  For Each FldrSubCrnt In Fldr.SubFolders
    Call SearchSingleFolder(PathSearch & "\" & FldrSubCrnt.Name, Lvl + 1, FlTextOut)
  Next

End Sub

2 个答案:

答案 0 :(得分:0)

编辑我提供的宏将文件夹和文件名写入文本文件。这表明宏正在搜索根文件夹下的所有文件夹,并可以访问这些文件夹中的所有文件。在原始草案中,我没有说明OP应该在哪里添加他的代码。我已经在宏中添加了注释,标识了应该添加代码的位置。

我不完全理解你的问题。但是,我相信我理解主要问题。

文件夹C:Users\Abubakar Adan\JSIM\包含许多子文件夹和子子文件夹。每个子文件夹和子子文件夹都包含您希望转换为工作簿的文本文件。您不知道如何访问其子文件夹和子子文件夹中的所有文件。

下面的宏演示如何访问任何深度的子文件夹和子子文件夹以及子子文件夹。

这个答案比我希望的更先进。但是,我想不出一种更简单的方法来为您提供我认为您需要的灵活性。这些宏并不长,所以你可以逐个声明地研究它们并研究它们正在做什么。

我正在使用“系统文件对象”,它可以让您完全访问Windows文件系统。互联网上有一些关于“系统文件对象”的好教程,如果我的代码不清楚,我建议你学习。

我在包含包含宏的工作簿的文件夹中创建了一个文本文件“Demo.txt”。在这个文本文件中,我写了每个子文件夹的名称和子文件夹中的每个文件。我不知道你在C:Users\Abubakar Adan\JSIM\中有多少个文件。您可以尝试使用C:Users\Abubakar Adan\上的宏来更好地了解他们的行为。

我使用递归。如今我被认为是一种先进的技术,虽然我在第一次编程课程中就是这样教过的。您可能会知道子程序ABC可以调用子程序DEF可以将子程序GHI调用到任何深度(受内存限制)。你可能不知道子程序ABC可以调用自己。这是递归。

当您在层次结构中工作时,递归非常有用。处理根文件夹C:Users\Abubakar Adan\JSIM\的代码与处理子文件夹和子子文件夹的代码完全相同。在每种情况下,代码都会列出文件夹名称及其中任何文件的名称。然后它会为每个子文件夹调用自己。

尝试使用宏。我相信他们会给你你寻求的骨架。我将文件名输出到“Demo.txt”,您将检查扩展名是否为“TXT”,如果是,则使用现有代码将其转换为工作簿。

我希望这一切都清楚。如有必要,请回答问题。

Option Explicit

' * These routines use File System Object.  For the easiest use of File System
'   Objects, it is necessary to create a reference to the Microsoft Scripting
'   Runtime as follows:
'     1) Open the Visual Basic Editor.
'     2) Select Tools, from the tool bar, then References.
'     3) You will get a long list of available references of which a few will be
'        ticked.
'     4) The list is in alphabetic sequence.  Scroll down the list looking for
'        "Microsoft Scripting Runtime".  Tick the box against it and then click OK.
'     5) Select Tools, from the tool bar, then References again.  Check that
'        "Microsoft Scripting Runtime" is one of the ticked references at the top.
'        If it is not, you did not perform step 4 correctly.

Sub CtrlSearch()

  Dim FlSys As FileSystemObject
  Dim FlTextOut As TextStream
  Dim PathCrnt As String
  Dim PathSearchRoot As String

  PathCrnt = ActiveWorkbook.Path

  Set FlSys = CreateObject("Scripting.FileSystemObject")
  Set FlTextOut = FlSys.CreateTextFile(PathCrnt & "\Demo.txt")

  PathSearchRoot = "C:\DataArea\Play"

  ' ### Replace "C:\DataArea\Play" with the full name of the folder to search.

  Call SearchSingleFolder(PathSearchRoot, 0, FlTextOut)

  FlTextOut.Close

End Sub
Sub SearchSingleFolder(ByVal PathSearch As String, ByVal Lvl As Long, _
                       ByRef FlTextOut As TextStream)

  ' PathSearch  A path to be searched.
  ' Lvl         The level of this call.  Used to control indenting
  ' FlTextOut   The file object for the text file to which paths and
  '             files are to be output

  ' * When this routine is called by CtrlSearch, PathSearch will be the root of
  '   the folders to be searched and Lvl will be 0.
  ' * When this routine is called by itself, PathSearch will be a sub-folder
  '   or a sub-sub-folder of the root folders to be searched and Lvl will be 1 for
  '   a sub-folder, 2 for a sub-sub-folder and so on.
  ' * This routine outputs PathSearch to the output file following by the names of
  '   the files within it.
  ' * The routine then calls itself for each sub-folder of PathSearch.

  Dim Fldr As Folder
  Dim FldrSubCrnt As Folder
  Dim FlCrnt As File
  Dim FlSys As FileSystemObject

  Set FlSys = CreateObject("Scripting.FileSystemObject")

  FlTextOut.WriteLine (Space(Lvl * 2) & PathSearch)

  ' ### This routine is called for the root folder and every folder within
  ' ### the root folder.  If any folder level processing is required, it must
  ' ### be added here.  PathSearch is the current folder name.

  Set Fldr = FlSys.GetFolder(PathSearch)

  For Each FlCrnt In Fldr.Files
    FlTextOut.WriteLine (Space(Lvl * 2 + 4) & FlCrnt.Name)

      ' ### This loop will process every file within the root folder and every
      ' ### folder within the root folder.  The full name of the file is:
      ' ###    PathSearch & "\" & FlCrnt.Name
      ' ### If the folders may contain files that are not to be processed, code
      ' ### must be included to exclude such files.  For example, if you only want
      ' ### to process text files you need something like:
      ' ###    If LCase(Right(FlCrnt.Name,4)) = ".txt" Then
      ' ###      ' Code to process file here
      ' ###    End If

  Next

  For Each FldrSubCrnt In Fldr.SubFolders
    Call SearchSingleFolder(PathSearch & "\" & FldrSubCrnt.Name, Lvl + 1, FlTextOut)
  Next

End Sub

答案 1 :(得分:0)

回答第2版问题

现有代码中的错误

If LCase(Right(FlCrnt.Name, 4)) = ".TXT" Then

在左侧,您使用LCase确保扩展名为小写,但在右侧则使用大写“.TXT”。将LCase更改为UCase或将“.TXT”更改为“.txt”。

"TEXT;" & "PathSearch, & FlCrnt.Name"

您在引号中有路径和文件名,因此它们是文字而不是变量。你省略了“\”;看到七行了。替换为:

"TEXT;" & PathSearch & "\" & FlCrnt.Name

缺少代码

您说要为每个包含感兴趣的文本文件的文件夹创建一个新工作簿。没有代码可以在文件夹的开头将新工作簿添加到工作簿集合,也没有代码将更新的工作簿保存在文件夹的末尾。

如果文件夹包含感兴趣的文本文件,则只需要创建工作簿。从您提供的文件中,我推断出感兴趣的文本文件的名称格式为:

nnn_OUT_Ix_mmm.TXT

其中:

  • nnn以1为单位从1上升到101.
  • mmm从500下降到0然后以10步为单位上升到500.
  • nnn和mmm都没有前导零。

我认为最简单的方法是生成这些文件名。如果文件夹中存在文件“1_OUT_Ix_500.TXT”,则假设所有其他文件都存在。

目前还不清楚是否要将每个文本文件放在自己的工作表中,或者是否要将它们一个接一个地添加到同一个工作表中。如果是第一个,您的现有代码几乎不需要修改,尽管您可能希望更改工作表名称。如果是第二个,则需要为每个文件计算目标单元格,而不是更改每个文件的工作表名称。