5

我每月收到 100 多个 Excel 电子表格,我从中选取固定范围并粘贴到其他电子表格中以制作报告。

我正在尝试编写一个 VBA 脚本来迭代我的 Excel 文件并将范围复制到一个电子表格中,但我无法做到这一点。

是否有捷径可寻?

4

7 回答 7

6

下面是一些 VBA 代码,演示了遍历目录中的一堆 Excel 文件并打开每个文件:

Dim sourcePath As String
Dim curFile As String
Dim curWB As Excel.Workbook
Dim destWB As Excel.Workbook

Set destWB = ActiveWorkbook
sourcePath = "C:\files"

curFile = Dir(sourcePath & "\*.xls")
While curFile <> ""
    Set curWB = Workbooks.Open(sourcePath & "\" & curFile)

    curWB.Close
    curFile = Dir()
Wend 

希望这将是您处理现有宏代码的一个足够好的起点。

于 2009-07-25T01:51:45.357 回答
3

我在几年前写过这篇文章,但也许​​它会对你有所帮助。我为最新版本的 Excel (xlsx) 添加了扩展。似乎工作。

Sub MergeExcelDocs()
    Dim lastRow As Integer
    Dim docPath As String
    Dim baseCell As Excel.range
    Dim sysObj As Variant, folderObj As Variant, fileObj As Variant
    Application.ScreenUpdating = False
    docPath = Application.GetOpenFilename(FileFilter:="Text Files (*.txt),*.txt,Excel Files (*.xls),*.xls,Excel 2007 Files (*.xlsx),*.xlsx", FilterIndex:=2, Title:="Choose any file")
    Workbooks.Add
    Set baseCell = range("A1")
    Set sysObj = CreateObject("scripting.filesystemobject")
    Set fileObj = sysObj.getFile(docPath)
    Set folderObj = fileObj.ParentFolder
    For Each fileObj In folderObj.Files
        Workbooks.Open Filename:=fileObj.path
        range(range("A1"), ActiveCell.SpecialCells(xlLastCell)).Copy
        lastRow = baseCell.SpecialCells(xlLastCell).row
        baseCell.Offset(lastRow, 0).PasteSpecial (xlPasteValues)
        baseCell.Copy
        ActiveWindow.Close SaveChanges:=False
    Next
End Sub

编辑:

我应该提到它是如何工作的。当您启动宏时,它会弹出一个打开文件对话框。双击列表中的第一个文件(或任何文件)。它将创建一个新工作簿,然后遍历文件夹中的所有文件。对于每个文件,它会复制第一个工作表中的所有内容并将其粘贴到新工作簿的末尾。这就是它的全部内容。

于 2009-07-25T05:06:29.277 回答
2

另一种解决方案是让您的汇总电子表格按文件名访问其他电子表格并获取数据本身。

为此,您需要同时打开所有电子表格,以便它可以更新链接,但这仍然可能比一次打开和复制/粘贴一个更快,即使使用宏也是如此。每个电子表格都需要有一个唯一的文件名。

如果在您收到电子表格之前不知道它们的名称,或者它们会定期更改,请在汇总表中创建一个列来存储工作表的文件名,然后使用字符串操作构建您需要的地址并获取数据使用间接()。

从一个特定文件中获取一个数据单元格的示例:

=INDIRECT("'[C:\path\workbook.xls]MyWorksheet'!$A$2")

冲洗并为您想要获取的每个电子表格的每个单元格重复上述操作。

您应该很聪明地知道如何将字符串传递给 INDIRECT()。将其构建为公式,这样您就可以对需要检索的每个单元格使用相同的公式。

例子:

= INDIRECT("'[" & $A2 & "]MyWorksheet'!$" & ADDRESS(3, COL()))

上面的公式将转到文件名在 $A2 中的电子表格(注意“2”之前缺少 $,因此您可以将相同的公式粘贴到其他文件的其他行),并获取 MyWorksheet 表上单元格的值在第三行和当前列上(因此,如果它在您的汇总中的 B2 中,它将从另一个文件中获取 B3)。

调整 ADDRESS 函数以向所需的行和列添加偏移量。

上述解决方案的优点是可以在需要填充的行和列之间复制和粘贴相同的公式,Excel 会根据需要调整 $A2 和 COL()。非常可维护。

遇到类似情况后进行编辑,我无法一次加载所有电子表格(超过 200 个)。我想我最终写了 VBA,所以它实际上并没有打开和读取 Excel 文件。相反,我让它遍历文件名,打开到每个文件名的 ODBC 连接,并使用 ADO 从指定的命名范围(在 ODBC 中显示为“表”——工作表也显示为“表”)读取我需要的值“但有关于允许名称的规则)。这比打开和关闭 Excel 文件要快得多,并且还具有不会使 Excel 崩溃的额外优势。

于 2009-07-24T22:37:06.237 回答
1

你试过了吗

Tools->Macro->Record New Macro 

创建maco来做同样的事情

于 2009-07-24T22:19:09.453 回答
1

罗德里戈,

我猜您的意思是 100 多个工作簿,您需要单独打开并复制并粘贴到一个工作簿中?听起来很有趣 :)

如果您可以将它们全部放在一个目录中,那么打开每个文件相当容易,请先进行搜索。(@Mark Biek 为您发布了一个很好的例子)

打开文件后,我会将数据复制到 ADO 记录集中,然后将其附加到该记录集中。我已经发布了一些代码,用于在一个工作簿中合并多个工作表非常相似。

这不完全是您所需要的,但它应该有所帮助。如果没有,请发布您的进度,我将在一周内再看一次。

于 2009-07-25T01:27:25.107 回答
0

这可以通过在 Access 中使用 TransferSpreadsheet 来实现。请参阅此链接:

http://datapigtechnologies.com/blog/index.php/using-access-to-combine-multiple-excel-files-method-2/comment-page-1/#comment-1741

此解决方案不需要任何 VBA。

于 2009-08-03T20:30:11.173 回答
0

过去,我使用 VBA 创建外部引用(链接)。

我在这里发布了它(参见示例 2):

需要 Excel VBA 的最佳简短示例

它类似于使用 INDIRECT,但不需要打开 excel 工作簿。

唯一的缺点是旧电脑或旧版本的 excel,不确定是哪个,会使这个过程变慢。我相信这是因为每次添加新的外部引用时,所有其他外部引用都会更新。为了让它更快,我将计算设置为手动,添加外部引用,并将计算设置为自动以更新它们。

之后,如果您只需要这些值,您可以使用断开链接或复制和粘贴特殊值。

于 2009-10-05T04:22:19.377 回答