excel - How can I open multiple files to copy data into a master workbook in new tab?
问题描述
I have a master Excel file that needs to inherit data from .csv files.
When I run the VBA, it will pop up the file explorer, let me select multiple files and loop over them and create new sheets.
When I try to copy the data into the sheet that it created, it gives me a type mismatch error.
Sub OpenLMSFiles()
Dim fd As FileDialog
Dim FileChosen As Integer
Dim FileName As String
Dim tempWB As Workbook
Dim i As Integer
Set fd = Application.FileDialog(msoFileDialogFilePicker)
fd.InitialFileName = "Libraries\Documents"
fd.InitialView = msoFileDialogViewList
fd.AllowMultiSelect = True
FileChosen = fd.Show
If FileChosen = -1 Then
For i = 1 To fd.SelectedItems.Count
Set tempWB = Workbooks.Open(fd.SelectedItems(i))
Call ReadDataFromSourceFile(tempWB)
Next i
End If
End Sub
Private Sub ReadDataFromSourceFile(src As Workbook)
Application.ScreenUpdating = False
ThisWorkbook.Sheets.Add
Workbooks(src).Worksheets(src.ActiveSheet).Range("A1:Z500").Copy _
Workbooks(ThisWorkbook).Worksheets(ThisWorkbook.ActiveSheet).Range("A1:Z500")
End Sub
解决方案
The cause of the error is the way you are referencing workbooks and worksheets, which are collections that take index arguments (integer or string). For example you can reference a workbook as Workbooks(1)
(bad idea) or Workbooks("FileName.xlsx")
(better). Similarly use Sheets(1)
or Sheets("SheetName")
.
src
is a Workbook
-> simply use src.Sheets()
. Because csv files have only 1 worksheet it is safe to use src.Worksheets(1)
(Sheets
and Worksheets
are equivalent).
Anyway, here is a working code. I rearranged the code as I think ReadDataFromSourceFile
should encapsulate opening and closing the csv file as well as reading data from it (only an opinion)
Sub ImportLMSFiles()
Dim fd As FileDialog
Dim FileChosen As Long
Dim FileName As String
Dim i As Long
Set fd = Application.FileDialog(msoFileDialogFilePicker)
fd.InitialFileName = "Libraries\Documents"
fd.InitialView = msoFileDialogViewList
fd.AllowMultiSelect = True
FileChosen = fd.Show
If FileChosen = -1 Then
For i = 1 To fd.SelectedItems.Count
Call ReadDataFromSourceFile(fd.SelectedItems(i))
Next i
End If
End Sub
Private Sub ReadDataFromSourceFile(sSrcFilename As String)
' Validate the name
If Right(sSrcFilename, 4) <> ".csv" Then Exit Sub
Application.ScreenUpdating = False
Dim shtDest As Worksheet: Set shtDest = ThisWorkbook.Sheets.Add
Dim wbSrc As Workbook: Set wbSrc = Workbooks.Open(sSrcFilename)
' csv files have only 1 sheet
' UsedRange is exactly what it sounds like
With wbSrc.Sheets(1)
.UsedRange.Copy shtDest.Range(.UsedRange.Address)
' if you want to rename the new sheet
' Bug: another sheet might have the same name -> u need check for that
' Here I'm just ducking it: name not changed
On Error Resume Next
shtDest.Name = .Name
On Error GoTo 0
End With
wbSrc.Close SaveChanges:=False
Application.ScreenUpdating = True
End Sub
推荐阅读
- python - 我想将函数 .head() 用于 groupby 对象
- javascript - 在 ruby-on-rails 中更新数据库后如何向 div 添加 id 或类?
- c++ - 为什么带有模板参数的 C++ 函数在 clang++ 7 上没有警告“控制到达非 void 函数的末尾”?
- python - pypi cproto(chrome调试客户端)在退出时挂起
- python - 从图像中复制黑色像素并粘贴到具有偏移的同一图像中
- server-side - 流服务器端聊天消息 POST
- excel - 无法正确关闭 Excel 应用程序
- node.js - npm run devs 在全新安装时失败
- android - Android 实时数据室。使用哪种方法
- linux - Linux 中汇编程序可用的内存