vba 如何将数据附加到现有工作簿的工作表而不创建新工作簿
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9437016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to append data to existing workbook's sheet and don't create a new workbook
提问by Tom
I am trying to work out what I need to change in the following VBA code to append the data at the bottom of data that already exists in a workbook named "Main" and a worksheet named "summary":
我正在尝试找出需要在以下 VBA 代码中更改的内容,以将数据附加到名为“ Main”的工作簿和名为“ summary”的工作表中已存在的数据底部:
Sub MergeAllWorkbooks()
Dim MyPath As String, FilesInPath As String
Dim MyFiles() As String
Dim SourceRcount As Long, FNum As Long
Dim mybook As Workbook, BaseWks As Worksheet
Dim sourceRange As Range, destrange As Range
Dim rnum As Long, CalcMode As Long
' Change this to the path\folder location of your files.
MyPath = "C:\test\"
' Add a slash at the end of the path if needed.
If Right(MyPath, 1) <> "\" Then
MyPath = MyPath & "\"
End If
' If there are no Excel files in the folder, exit.
FilesInPath = Dir(MyPath & "*.xl*")
If FilesInPath = "" Then
MsgBox "No files found"
Exit Sub
End If
' Fill the myFiles array with the list of Excel files
' in the search folder.
FNum = 0
Do While FilesInPath <> ""
FNum = FNum + 1
ReDim Preserve MyFiles(1 To FNum)
MyFiles(FNum) = FilesInPath
FilesInPath = Dir()
Loop
FNum = FNum - 1
' Set various application properties.
With Application
CalcMode = .Calculation
.Calculation = xlCalculationManual
.ScreenUpdating = False
.EnableEvents = False
End With
' Add a new workbook with one sheet.
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
' Loop through all files in the myFiles array.
If FNum > 0 Then
For FNum = LBound(MyFiles) To UBound(MyFiles)
Set mybook = Nothing
On Error Resume Next
Set mybook = Workbooks.Open(MyPath & MyFiles(FNum))
On Error GoTo 0
If Not mybook Is Nothing Then
On Error Resume Next
' Change this range to fit your own needs.
With mybook.Worksheets(1)
Set sourceRange = .Range("A2:T" & CStr(mybook.Worksheets(1).Range("A2").CurrentRegion.Rows.Count))
End With
If Err.Number > 0 Then
Err.Clear
Set sourceRange = Nothing
Else
' If source range uses all columns then
' skip this file.
If sourceRange.Columns.Count >= BaseWks.Columns.Count Then
Set sourceRange = Nothing
End If
End If
On Error GoTo 0
If Not sourceRange Is Nothing Then
SourceRcount = sourceRange.Rows.Count
If rnum + SourceRcount >= BaseWks.Rows.Count Then
MsgBox "There are not enough rows in the target worksheet."
BaseWks.Columns.AutoFit
mybook.Close savechanges:=False
GoTo ExitTheSub
Else
' Copy the file name in column A.
With sourceRange
BaseWks.Cells(rnum, "A"). _
Resize(.Rows.Count).Value = MyFiles(FNum)
End With
' Set the destination range.
Set destrange = BaseWks.Range("B" & rnum)
' Copy the values from the source range
' to the destination range.
With sourceRange
Set destrange = destrange. _
Resize(.Rows.Count, .Columns.Count)
End With
destrange.Value = sourceRange.Value
rnum = rnum + SourceRcount
End If
End If
mybook.Close savechanges:=False
End If
Next FNum
BaseWks.Columns.AutoFit
End If
ExitTheSub:
' Restore the application properties.
With Application
.ScreenUpdating = True
.EnableEvents = True
.Calculation = CalcMode
End With
End Sub
Thank you
谢谢
回答by Tony Dallimore
I do not like this code. There is lots I object to but I am most unhappy about the use of error handling:
我不喜欢这个代码。我反对的有很多,但我对错误处理的使用最不满意:
The error handling functionality is there to allow your routine to fail gracefully when something goes wrong. It is not there to allow you to ignore errors and carry on as though they did not happen.
The error handling failed to handle a problem with one of my workbooks. I have not investigated but I suspect the problem is either the length of a single cell or the total length of the data being transferred by
destrange.Value = sourceRange.Value
.
错误处理功能允许您的例程在出现问题时正常失败。它不是让您忽略错误并继续进行,就好像它们没有发生一样。
错误处理未能处理我的一本工作簿的问题。我没有调查过,但我怀疑问题出在单个单元格的长度或由
destrange.Value = sourceRange.Value
.
However, you ask how to make a single change so I will limit myself to that.
但是,您询问如何进行单个更改,因此我将仅限于此。
I suggest the easiest approach would be to create workbook "Main" with worksheet "Summary" and to include your macro in it.
我建议最简单的方法是使用工作表“摘要”创建工作簿“主要”,并在其中包含您的宏。
Add new statements under the Dim
statements:
在语句下添加新Dim
语句:
Dim rnum As Long, CalcMode As Long
'### Start of new code
If Workbooks.Count > 1 Then
' It is easy to get into a muddle if there are multiple workbooks
' open at the start of a macro like this. Avoid the problem until
' you understand it.
Call MsgBox("Please close all other workbooks", vbOKOnly)
Exit Sub
End If
Set BaseWks = ActiveWorkBook.Worksheets("Summary")
With BaseWks
rnum = .Cells(Rows.Count, "A").End(xlUp).Row + 1
End With
'### End of new code
' Change this to the path\folder location of your files.
The first block of the above code ensures there are no other workbooks open.
上述代码的第一块确保没有其他工作簿打开。
The second block (1) sets BaseWks
to worksheet "Summary" and (2) sets rnum
to the first unused row in "Summary". End(xlUp)
is the VBA equivalent of clicking Ctrl
+Up
. So I have gone to the bottom of column A, gone up until I hit a row with a value and then down 1 row.
第二个块 (1) 设置BaseWks
为工作表“摘要”,(2) 设置rnum
为“摘要”中第一个未使用的行。 End(xlUp)
是相当于单击Ctrl
+的 VBA Up
。所以我已经到了 A 列的底部,一直上升到我碰到一个有值的行,然后下降了 1 行。
Replace the loop that locates the filenames with:
将查找文件名的循环替换为:
Do While FilesInPath <> ""
If FilesInPath <> ActiveWorkbook.Name Then
FNum = FNum + 1
ReDim Preserve MyFiles(1 To FNum)
MyFiles(FNum) = FilesInPath
End If
FilesInPath = Dir()
Loop
I assume that workbook "Main" will be in the same folder as the other workbooks. This change ensures that "Main" is not used as a source.
我假设工作簿“Main”将与其他工作簿位于同一文件夹中。此更改可确保“Main”不用作源。
Discard these statements:
丢弃这些陈述:
Set BaseWks = Workbooks.Add(xlWBATWorksheet).Worksheets(1)
rnum = 1
because I have already set BaseWks
and rnum
to the values I require.
因为我已经设置BaseWks
并rnum
为值我需要。
If you want to save the updated workbook "Main" automatically, add the following statement above ExitTheSub:
:
如果要自动保存更新的工作簿“Main”,请在上面添加以下语句ExitTheSub:
:
ActiveWorkbook.Save