首页 文章

VBA - 将工作表复制到另一个工作簿

提问于
浏览
0

我想将表单(sheet2)从某些工作簿(单元格列“B”中的路径)复制到另一个工作簿(模板) .

我尝试了以下一个但Excel返回以下错误“运行时错误'1004':应用程序定义或对象定义错误” .

Private Sub SplitFile_Click()
  Dim C As Integer
  Dim x As Variant
  Dim Z As Workbook

  For C = 0 To 10

  Set x = ThisWorkbook.Sheets("SelectedFiles").Range("B" & C)
  Worlbooks.Open("x").Sheets(Sheet2).Range("A1:U1000").Copy
  Set Z = Workbooks.Open("D:\PTP\MASTERDATA\SPACCHETTAMENTO FILE\TEMPLATE.Template.xlsx")


  Z.Sheets("SPLIT TAB").Range("A1:U1000").PasteSpecial
  Workbooks("Z").SaveAs Filename:="PROVA.xlsx"
  Next C
End Sub

你能帮助我吗?

谢谢,伊万

2 回答

  • 0

    您不需要在Workbook之间复制和粘贴数据,因为它运行得更慢 . 这里有一些示例代码,希望它可以帮到你..!

    Option Explicit
    
        Public Sub SplitFile_Click()
          Dim C As Integer
          Dim x As Range
          Dim Z As Workbook
    
          For C = 1 To 10
              Set x = ThisWorkbook.Sheets("SelectedFiles").Range("B" & C)
              Set Z = Workbooks.Open("D:\Template.xlsx")
    
              Z.Sheets("SPLIT TAB").Range("A1") = x 'this code is faster that copy & paste
              Z.SaveAs "PROVA" & C & ".xlsx" 'workbook should have a unique filename
    
              Z.Close 'close workbook
          Next C
        End Sub
    
  • 0

    VBA正在爆炸这条线:

    Set x = ThisWorkbook.Sheets("SelectedFiles").Range("B" & C)
    

    由于 C 的值为0,并且0不是有效的行号,因此 B0 不是有效的范围地址 . 所以你可以从 C = 1 开始,这将解决这个错误 .

    我强烈建议在引用行号时使用 Long 整数(32位)而不是 Integer (16位)(无论您需要哪些行) . Integer 的最大值为32,767,工作表可以包含更多行 .

    x 声明为 Variant . 这意味着它可以成为你所做的任何事情 .

    如果你这样做:

    x = ThisWorkbook.Sheets("SelectedFiles").Range("B" & C)
    

    然后 x 将包含 Range 调用引用的单元格的值 .

    但是你这样做了:

    Set x = ThisWorkbook.Sheets("SelectedFiles").Range("B" & C)
    

    这指示VBA x 应该包含一个对象引用,因此不是为它分配单元格的值,而是获取单元格本身 .

    然后你这样做:

    Worlbooks.Open("x").Sheets(Sheet2).Range("A1:U1000").Copy
    

    如果这个编译,那只是因为没有指定 Option Explicit . Worlbooks 不是't exist anywhere, it'是一个拼写错误 - 但由于未指定 Option Explicit ,VBA允许您在不声明变量的情况下使用变量,因此很乐意编译 Worlbooks 并将其分辨率推迟到运行时...此时会弹出另一个错误 .

    这会解决它:

    Workbooks.Open("x").Sheets(Sheet2).Range("A1:U1000").Copy
    

    除了......它在循环内部:在该循环的每次迭代中,您尝试打开名为 "x" 的工作簿(很可能不存在) . 如果 "x" 表示 ThisWorkbook.Sheets("SelectedFiles").Range("B" & C) 中包含的文件名,那么 x 应该声明为 String 变量,你可以像这样引用它:

    Dim source As Workbook
    Set source = Workbooks.Open(x)
    

    你会在循环之外做到这一点,所以你已经打开了't try to open the same workbook every time the loop makes an iteration: IIRC opening a workbook that'将会引发另一个运行时错误 .

    如果每次迭代都应该使用不同的工作簿/文件,那么每次迭代也应关闭该工作簿,否则最终会打开12个工作簿,其中11个不再需要 .

    因此,您要保留对要使用的工作簿对象的引用:

    For C = 1 To 11
        x = ThisWorkbook.Sheets("SelectedFiles").Range("B" & C).Value
        Set source = Worlbooks.Open(x)
        source.Sheets(Sheet2).Range("A1:U1000").Copy
        '...
        source.Close
    Next
    

    与您的目的地书籍相同:

    Set Z = Workbooks.Open("D:\PTP\MASTERDATA\SPACCHETTAMENTO FILE\TEMPLATE.Template.xlsx")
    

    您打开相同的文件11次,而不是关闭它一次 . 然后您将源书籍粘贴到目标书中......

    Z.Sheets("SPLIT TAB").Range("A1:U1000").PasteSpecial
    

    ...每次都覆盖上一次迭代的工作,并保存11次 .


    因此,该代码中存在许多严重问题 . 概括:

    • 在每个模块的顶部指定 Option Explicit .

    • 尽可能使用显式特定类型声明所有变量 .

    • 自己清理干净 .

    学习使用调试器 . F9设置断点,停止执行;从那时起,您可以使用F8一次运行一个指令代码,并且可以使用立即窗格(Ctrl G)在当前执行上下文中输出任何内容 . 使用locals工具窗口可视化当前作用域可以访问的所有内容 .

相关问题