Excel 将图像和数据从多个源工作簿复制到单个工作簿的有效方法
我有以下代码将图像从一个工作簿复制到另一个工作簿。代码打开源工作簿/工作表,复制图像,然后关闭工作簿。此过程重复多次。有没有更有效的方法?也许绕过剪贴板 我只需要为每个源工作簿/工作表复制1个图像(名为“图片4”)和2-3个单元格值。我有7-8个源工作簿Excel 将图像和数据从多个源工作簿复制到单个工作簿的有效方法,excel,vba,Excel,Vba,我有以下代码将图像从一个工作簿复制到另一个工作簿。代码打开源工作簿/工作表,复制图像,然后关闭工作簿。此过程重复多次。有没有更有效的方法?也许绕过剪贴板 我只需要为每个源工作簿/工作表复制1个图像(名为“图片4”)和2-3个单元格值。我有7-8个源工作簿 Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS1.xlsx", True, True) Set srcWS = srcWB.Sheets("s
Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS1.xlsx", True, True)
Set srcWS = srcWB.Sheets("sheetwithimage")
srcWS.Pictures(4).Copy
dstWS.Range("B7").PasteSpecial
Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS2.xlsx", True, True)
Set srcWS = srcWB.Sheets("sheetwithimage")
srcWS.Pictures(4).Copy
dstWS.Range("G8").PasteSpecial
创建报告
- 我假设目标工作簿和包含此代码的工作簿是相同的
- 调整常量部分中的值
- 仅运行
过程。它正在调用函数createReport
getFilePathsInFolder
- 由于
将没有扩展名此工作簿
,因此语句“xlsx”
是多余的,但我将离开它,因为有一天,当代码可能造成一些损坏时,您可能会将文件扩展名更改为如果StrComp(filepath(fp)、dstFilePath、vbTextCompare)0那么
“xls*”
- 它将在指定的文件夹中查找并将所有
文件写入数组。它将循环遍历数组并打开每个工作簿,将其索引指定的图片复制到目标工作簿的指定位置,然后将其粘贴并写入指定的单元格值,然后关闭每个源工作簿.xlsx
Option Explicit
Sub createReport()
Const ProcName As String = "createReport"
On Error GoTo clearError
' Source
Const Extension As String = "xlsx"
Const srcName As String = "sheetwithimage"
Const srcList As String = "A1,A2,A3" ' add more
Const picIndex As Long = 1
' Destination
Const dstName As String = "Sheet1"
Const dstList As String = "B1,B2,B3" ' add more
Const picAddress As String = "B7"
Const colOffset As Long = 5
' Write file paths from Source Folder Path to File Paths array.
Dim wbDst As Workbook: Set wbDst = ThisWorkbook
Dim srcFolderPath As String: srcFolderPath = wbDst.Path
Dim FilePaths As Variant
FilePaths = getFilePathsInFolder(srcFolderPath, Extension)
Dim srcCells() As String: srcCells = Split(srcList, ",")
Dim dstCells() As String: dstCells = Split(dstList, ",")
' Use a variable for lower and upper if inside another loop.
' Split ensures that lower is 0, so no need for lower variable.
Dim CellsUB As Long: CellsUB = UBound(srcCells) ' or 'Ubound(dstCells)'
Dim dst As Worksheet: Set dst = wbDst.Worksheets(dstName)
Dim dstFilePath As String: dstFilePath = wbDst.FullName
' Declare new variables occurring in the following loop.
Dim wbSrc As Workbook
Dim src As Worksheet
Dim srcCount As Long
Dim fp As Long
Dim n As Long
Application.ScreenUpdating = False
' We don't care if 'FilePaths' is zero, one or five-based, since we
' cannot use fp because of 'ThisWorkbook'; hence 'srcCount'.
For fp = LBound(FilePaths) To UBound(FilePaths)
' We have to skip 'ThisWorkbook'. Using 'StrComp' with 'vbTextCompare'
' is a great way for comparing strings case-insensitively i.e. 'A=a'.
' '0' means it is a match.
If StrComp(FilePaths(fp), dstFilePath, vbTextCompare) <> 0 Then
Set wbSrc = Workbooks.Open(FilePaths(fp), True, True)
Set src = wbSrc.Worksheets(srcName)
src.Pictures(picIndex).Copy
dst.Range(picAddress).Offset(, srcCount * colOffset).PasteSpecial
For n = 0 To CellsUB ' 'Split'
dst.Range(dstCells(n)).Offset(, srcCount * colOffset).Value _
= src.Range(srcCells(n)).Value
Next n
wbSrc.Close SaveChanges:=False
srcCount = srcCount + 1
End If
Next fp
' Save and/or inform user.
If srcCount > 0 Then
dst.Range("A1").Select
wbDst.Save
Application.ScreenUpdating = True
If srcCount = 1 Then
MsgBox "Data from 1 workbook transferred.", vbInformation, "Success"
Else
MsgBox "Data from " & srcCount & " workbooks transferred.", _
vbInformation, "Success"
End If
Else
MsgBox "No matching workbooks found in folder '" & srcFolderPath _
& "'!", vbCritical, "Fail"
End If
ProcExit:
Exit Sub
clearError:
Debug.Print "'" & ProcName & "': Unexpected Error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Sub
Function getFilePathsInFolder( _
FolderPath As String, _
Optional ByVal ExtensionPattern As String = "", _
Optional ByVal FirstIndex As Long = 0) _
As Variant
Const ProcName As String = "listFilePathsInFolder"
On Error GoTo clearError
With CreateObject("Scripting.FileSystemObject")
Dim fsoFolder As Object
Set fsoFolder = .GetFolder(FolderPath)
Dim FilesCount As Long
FilesCount = fsoFolder.Files.Count
If FilesCount > 0 Then
Dim n As Long
n = FirstIndex - 1
Dim OneD As Variant
ReDim OneD(FirstIndex To FilesCount + n)
Dim fsoFile As Object
If ExtensionPattern = "" Then
For Each fsoFile In fsoFolder.Files
n = n + 1
OneD(n) = fsoFile.Path
Next fsoFile
getFilePathsInFolder = OneD
Else
For Each fsoFile In fsoFolder.Files
If LCase(.GetExtensionName(fsoFile)) _
Like LCase(ExtensionPattern) Then
n = n + 1
OneD(n) = fsoFile.Path
End If
Next fsoFile
If n > FirstIndex - 1 Then
ReDim Preserve OneD(FirstIndex To n)
getFilePathsInFolder = OneD
Else
Debug.Print "'" & ProcName & "': " _
& "No '" & ExtensionPattern & "'-files found."
End If
End If
Else
Debug.Print "'" & ProcName & "': " _
& "No files found."
End If
End With
ProcExit:
Exit Function
clearError:
Debug.Print "'" & ProcName & "': Unexpected error!" & vbLf _
& " " & "Run-time error '" & Err.Number & "':" & vbLf _
& " " & Err.Description
Resume ProcExit
End Function
选项显式
子报表()
Const ProcName As String=“createReport”
关于错误转到clearError
"来源:
常量扩展名为String=“xlsx”
Const srcName As String=“sheetwithimage”
Const srcList As String=“A1、A2、A3”'添加更多
常量picIndex的长度=1
“目的地
常量dstName为String=“Sheet1”
Const dstList As String=“B1、B2、B3”'添加更多
Const picAddress As String=“B7”
长度=5时的常数列偏移
'将文件路径从源文件夹路径写入文件路径数组。
将wbDst设置为工作簿:设置wbDst=ThisWorkbook
将srcFolderPath设置为字符串:srcFolderPath=wbDst.Path
变暗文件路径作为变量
filepath=getFilePathsInFolder(srcFolderPath,扩展名)
Dim srccell()作为字符串:srccell=Split(srcList,“”)
Dim dstCells()作为字符串:dstCells=Split(dstList,“”)
'如果在另一个循环内,则为lower和upper使用一个变量。
'拆分确保lower为0,因此不需要lower变量。
将CellsUB设置为长:CellsUB=UBound(SRCCell)或UBound(DSTCell)
将dst设置为工作表:设置dst=wbDst.Worksheets(dstName)
Dim dstFilePath作为字符串:dstFilePath=wbDst.FullName
'声明发生在以下循环中的新变量。
将wbSrc设置为工作簿
Dim src As工作表
我认为只要
尽可能长
长
Application.ScreenUpdating=False
我们不在乎“文件路径”是零、一还是五,因为我们
'无法使用fp,因为'ThisWorkbook';因此“srcCount”。
对于fp=LBound(文件路径)到UBound(文件路径)
“我们必须跳过“此工作簿”。将“StrComp”与“vbTextCompare”一起使用
'是比较字符串大小写不敏感的好方法,即'a=a'。
“”0表示它是匹配项。
如果StrComp(filepath(fp)、dstFilePath、vbTextCompare)为0,则
设置wbSrc=Workbooks.Open(文件路径(fp)、True、True)
Set src=wbSrc.Worksheets(srcName)
src.图片(picIndex).复制
dst.Range(picAddress).Offset(,srcCount*colOffset).PasteSpecial
对于n=0的CellsUB“拆分”
dst.Range(dstcell(n)).Offset(,srcCount*colOffset).Value_
=src.Range(srccell(n)).Value
下一个
wbSrc.Close SaveChanges:=False
srcCount=srcCount+1
如果结束
下一个fp
'保存和/或通知用户。
如果srcCount>0,则
dst.范围(“A1”)。选择
wbDst.Save
Application.ScreenUpdating=True
如果srcCount=1,则
MsgBox“已传输1个工作簿中的数据”,vbInformation,“成功”
其他的
MsgBox“数据来自”&srcCount和“已传输工作簿”_
VBA信息,“成功”
如果结束
其他的
MsgBox“在文件夹“”中找不到匹配的工作簿(&srcFolderPath)_
&“!”,vbCritical,“失败”
如果结束
程序出口:
出口接头
clearError:
Debug.Print“”&ProcName&“:意外错误!”&vbLf_
&“&”运行时错误“&”错误编号&“:”&vbLf_
&“”错误描述(&R)
恢复程序退出
端接头
函数getFilePathsInFolder(_
FolderPath作为字符串_
可选的ByVal扩展模式为String=“”_
可选的ByVal FirstIndex(长度=0)_
作为变体
Const ProcName As String=“listFilePathsInFolder”
关于错误转到clearError
使用CreateObject(“Scripting.FileSystemObject”)
作为对象的模糊文件夹
设置fsoFolder=.GetFolder(FolderPath)
我认为时间很长
filescont=fsoFolder.Files.Count
如果FileCount>0,则
长
n=第一索引-1
作为变体
重新定义(第一个索引到filescout+n)
作为对象的Dim fsoFile
如果ExtensionPattern=“”,则
对于fsoFolder.Files中的每个fsoFile
n=n+1
OneD(n)=f文件路径
下一个文件
getFilePathsInFolder=OneD
其他的
对于fsoFolder.Files中的每个fsoFile
如果是LCase(.GetExtensionName(fsoFile))_
就像LCase(ExtensionPattern)那样
n=n+1
OneD(n)=f文件路径
Option Explicit
Sub copy_images_original()
Dim dstWS As Worksheet
Set dstWS = ThisWorkbook.Sheets(1)
Dim srcWB As Workbook
Dim srcWS As Worksheet
Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS1.xlsx", True, True)
Set srcWS = srcWB.Sheets("sheetwithimage")
srcWS.Pictures(4).Copy
dstWS.Range("B7").PasteSpecial
srcWB.Close
Set srcWB = Workbooks.Open(ThisWorkbook.Path & "\testWS2.xlsx", True, True)
Set srcWS = srcWB.Sheets("sheetwithimage")
srcWS.Pictures(4).Copy
dstWS.Range("G8").PasteSpecial
srcWB.Close
End Sub
Sub CalculateRunTime_Seconds()
'PURPOSE: Determine how many seconds it took for code to completely run
'SOURCE: www.TheSpreadsheetGuru.com/the-code-vault
Dim StartTime As Double
Dim SecondsElapsed As Double
'Remember time when macro starts
StartTime = Timer
'*****************************
Call turn_app_off
Call copy_images_original
Call turn_app_on
'*****************************
'Determine how many seconds code took to run
SecondsElapsed = Round(Timer - StartTime, 2)
'Notify user in seconds
MsgBox "This code ran successfully in " & SecondsElapsed & " seconds", vbInformation
End Sub
Sub turn_app_off()
With Application
.ScreenUpdating = False
.EnableEvents = False
.DisplayAlerts = False
End With
End Sub
Sub turn_app_on()
With Application
.ScreenUpdating = True
.EnableEvents = True
.DisplayAlerts = True
End With
End Sub