【问题标题】:VBA copying all the Excel files in a folder to a single file causes runtime errorVBA将文件夹中的所有Excel文件复制到单个文件会导致运行时错误
【发布时间】:2016-09-21 06:46:41
【问题描述】:

我正在尝试使用 VBA 打开一个目录(在本例中为 c:\temp)中的所有 excel 文件,并将所有文件数据表放在一个大文件中。每个新工作表都以文件名加上原始文档上工作表的名称命名。我的代码复制了第一个文件的第一个工作表,甚至正确命名它,但是当我尝试设置名称时,第二个工作表上出现运行时错误 1004:应用程序定义或对象定义错误。任何人都对如何修复有任何建议。

Sub MergeAllWorkbooks()
Dim FolderPath As String
Dim FileName As String

' Create a new workbook
Set FileWorkbook = Workbooks.Add(xlWBATWorksheet)

' folder path to the files you want to use.
FolderPath = "C:\Temp\"

' Call Dir the first time, pointing it to all Excel files in the folder path.
FileName = Dir(FolderPath & "*.xl*")

' Loop until Dir returns an empty string.
Do While FileName <> ""

    ' Open a workbook in the folder
    Set WorkBk = Workbooks.Open(FolderPath & FileName)

    Dim currentSheet As Worksheet
    Dim sheetIndex As Integer
    sheetIndex = 1

    Windows(WorkBk.Name).Activate

    For Each currentSheet In WorkBk.Worksheets
        currentSheet.Select
        currentSheet.Copy Before:=Workbooks(FileWorkbook.Name).Sheets(sheetIndex)
        FileWorkbook.Sheets(sheetIndex).Name = FileName & "-" & currentSheet.Name
        sheetIndex = sheetIndex + 1
    Next currentSheet

    ' Close the source workbook without saving changes.
    WorkBk.Close savechanges:=False

    ' Use Dir to get the next file name.
    FileName = Dir()
Loop

结束子

【问题讨论】:

  • 您能否调试错误并检查填充工作表名称的值,即确保它没有任何这些 \ / * [ ] : ?字符或不超过 31 个字符。否则,将手表添加到该行的每个部分,以查看哪个出错了。希望这会有所帮助。
  • 肯定需要先创建工作表才能命名,工作簿不包含无限工作表。
  • @NickA 我会考虑复制工作表来创建它。也许与sheetIndex 有关?在这里逐步检查并检查我认为的值是了解发生了什么的最佳策略。
  • 我曾经在工作表名称长度和字符方面遇到过类似问题,我的解决方案是最初删除特殊字符,然后将名称减少到最大 31,然后循环测试名称和如果存在更改新工作表名称(在我的情况下我缩短了它)。

标签: excel vba


【解决方案1】:

替换

FileWorkbook.Sheets(sheetIndex).Name = FileName & "-" & currentSheet.Name

with(为了便于阅读,我把它分开了)

sWSName = FileName & "-" & currentSheet.Name
sWSName = NameTest(sWSName)
sWSName = TestDup(sWSName)
FileWorkbook.Sheets(sheetIndex).Name = sWSName

您需要定义 sWSName。

以下是我之前使用的修改后的函数。

Function NameTest(sName As String) As String
  NameTest = sName
  aSpecChars = Array("\", "/", "*", "[", "]", ":", "?")
  For Each c In aSpecChars
    NameTest = Replace(NameTest, c, "")
  Next c

  If Len(sName) > 31 Then NameTest = Left(sName, 31)

End Function

Function TestDup(sWSName As String) As String
  TestDup = sWSName
  For Each ws In Worksheets
    Debug.Print ws.Name
    If sWSName = ws.Name Then TestDup = TestDup(Left(sWSName, Len(sWSName) - 1))
  Next ws
End Function

如果发布此代码(或在此范围内)不合时宜,请告诉我,因为我仍在接受所需的努力程度与合理的响应。

【讨论】:

  • 效果很好!非常感谢您的帮助
猜你喜欢
  • 2016-06-14
  • 2015-01-20
  • 1970-01-01
  • 2019-02-15
  • 2021-04-09
  • 1970-01-01
  • 2022-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多