Vba 根据用户定义的变量路径从关闭的工作簿复制数据
我已经用尽了我的搜索能力来寻找解决方案。以下是我想做的事情的概要:Vba 根据用户定义的变量路径从关闭的工作簿复制数据,vba,excel,excel-2007,xlm,Vba,Excel,Excel 2007,Xlm,我已经用尽了我的搜索能力来寻找解决方案。以下是我想做的事情的概要: 用户打开启用宏的Excel文件 立即提示用户输入或选择所需工作簿的文件路径。他们需要选择两个文件,并且文件名可能不一致 输入文件位置后,第一个文件选择的第一个工作表将复制到启用宏的工作簿的第一个工作表,第二个文件选择的第一个工作表将复制到启用宏的工作簿的第二个工作表 我遇到过一些关于ADO的引用,但我还不太熟悉 编辑:我找到了一个从关闭的文件导入数据的代码。我需要调整范围以返回变量结果 Private Functio
- 用户打开启用宏的Excel文件
- 立即提示用户输入或选择所需工作簿的文件路径。他们需要选择两个文件,并且文件名可能不一致
- 输入文件位置后,第一个文件选择的第一个工作表将复制到启用宏的工作簿的第一个工作表,第二个文件选择的第一个工作表将复制到启用宏的工作簿的第二个工作表
Private Function GetValue(path, file, sheet, ref)
path = "C:\Users\crathbun\Desktop"
file = "test.xlsx"
sheet = "Sheet1"
ref = "A1:R30"
' Retrieves a value from a closed workbook
Dim arg As String
' Make sure the file exists
If Right(path, 1) <> "\" Then path = path & "\"
If Dir(path & file) = "" Then
GetValue = "File Not Found"
Exit Function
End If
' Create the argument
arg = "'" & path & "[" & file & "]" & sheet & "'!" & _
Range(ref).Range("A1").Address(, , xlR1C1)
' Execute an XLM macro
GetValue = ExecuteExcel4Macro(arg)
End Function
Sub TestGetValue()
path = "C:\Users\crathbun\Desktop"
file = "test"
sheet = "Sheet1"
Application.ScreenUpdating = False
For r = 1 To 30
For C = 1 To 18
a = Cells(r, C).Address
Cells(r, C) = GetValue(path, file, sheet, a)
Next C
Next r
Application.ScreenUpdating = True
End Sub
私有函数GetValue(路径、文件、工作表、参考)
path=“C:\Users\crathbun\Desktop”
file=“test.xlsx”
sheet=“Sheet1”
ref=“A1:R30”
'从关闭的工作簿中检索值
作为字符串的Dim arg
'确保该文件存在
如果正确(路径,1)“\”则路径=路径&“\”
如果Dir(路径和文件)=“”,则
GetValue=“未找到文件”
退出功能
如果结束
'创建参数
arg=“”&path&“[”&file&“]”&sheet&“!”&_
范围(参考)。范围(“A1”)。地址(,xlR1C1)
'执行XLM宏
GetValue=ExecuteExcel4Macro(arg)
端函数
子TestGetValue()
path=“C:\Users\crathbun\Desktop”
file=“test”
sheet=“Sheet1”
Application.ScreenUpdating=False
对于r=1到30
对于C=1到18
a=单元(r,C).地址
单元格(r,C)=GetValue(路径、文件、工作表、a)
下一个C
下一个r
Application.ScreenUpdating=True
端接头
现在,我需要一个命令按钮或userform,它将立即提示用户定义文件路径,并从该文件导入数据。下面的函数从关闭的Excel文件读取数据,并以数组形式返回结果。它会丢失格式、公式等。您可能希望在主代码中调用isArrayEmpty函数(位于底部),以测试该函数是否返回了某些内容
Public Function getDataFromClosedExcelFile(parExcelFileName As String, parSheetName As String) As Variant
'see http://www.ozgrid.com/forum/showthread.php?t=19559
'returns an array (1 to nRows, 1 to nCols) which should be tested with isArrayEmpty in the calling function
Dim locConnection As New ADODB.Connection
Dim locRst As New ADODB.Recordset
Dim locConnectionString As String
Dim locQuery As String
Dim locCols As Variant
Dim locResult As Variant
Dim i As Long
Dim j As Long
On Error GoTo error_handler
locConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=" & parExcelFileName & ";" _
& "Extended Properties=""Excel 8.0;HDR=YES"";"
locQuery = "SELECT * FROM [" & parSheetName & "$]"
locConnection.Open ConnectionString:=locConnectionString
locRst.Open Source:=locQuery, ActiveConnection:=locConnection
If locRst.EOF Then 'Empty sheet or only one row
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''' FIX: an empty sheet returns "F1"
'''''' http://support.microsoft.com/kb/318373
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If locRst.Fields.Count = 1 And locRst.Fields(0).Name = "F1" Then Exit Function 'Empty sheet
ReDim locResult(1 To 1, 1 To locRst.Fields.Count) As Variant
For i = 1 To locRst.Fields.Count
locResult(1, i) = locRst.Fields(i - 1).Name
Next i
Else
locCols = locRst.GetRows
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''' FIX: an empty sheet returns "F1"
'''''' http://support.microsoft.com/kb/318373
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If locRst.Fields.Count = 1 And locRst.Fields(0).Name = "F1" And UBound(locCols, 2) = 0 And locCols(0, 0) = "" Then Exit Function 'Empty sheet
ReDim locResult(1 To UBound(locCols, 2) + 2, 1 To UBound(locCols, 1) + 1) As Variant
If locRst.Fields.Count <> UBound(locCols, 1) + 1 Then Exit Function 'Not supposed to happen
For j = 1 To UBound(locResult, 2)
locResult(1, j) = locRst.Fields(j - 1).Name
Next j
For i = 2 To UBound(locResult, 1)
For j = 1 To UBound(locResult, 2)
locResult(i, j) = locCols(j - 1, i - 2)
Next j
Next i
End If
locRst.Close
locConnection.Close
Set locRst = Nothing
Set locConnection = Nothing
getDataFromClosedExcelFile = locResult
Exit Function
error_handler:
'Wrong file name, sheet name, or other errors...
'Errors (#N/A, etc) on the sheet should be replaced by Null but should not raise an error
If locRst.State = ADODB.adStateOpen Then locRst.Close
If locConnection.State = ADODB.adStateOpen Then locConnection.Close
Set locRst = Nothing
Set locConnection = Nothing
End Function
Public Function isArrayEmpty(parArray As Variant) As Boolean
'Returns false if not an array or dynamic array that has not been initialised (ReDim) or has been erased (Erase)
If IsArray(parArray) = False Then isArrayEmpty = True
On Error Resume Next
If UBound(parArray) < LBound(parArray) Then isArrayEmpty = True: Exit Function Else: isArrayEmpty = False
End Function
我不介意在这个过程中打开文件。我只是不希望用户必须单独打开文件。我只需要他们能够选择或导航到所需的文件 下面是一个基本代码。此代码要求用户选择两个文件,然后将相关工作表导入当前工作簿。我有两个选择。你挑吧:) 经过尝试和测试 选项1(直接导入图纸,而不是复制到图纸1和2中) 选项2(将工作表内容导入工作表1和2中)
您已经构建了一些代码了吗?你被困在哪里?@JMax-我添加了目前可用的代码。这并不多,我甚至不确定我是否朝着正确的方向前进。@user955289:你有什么理由不想打开这两个文件吗?使用工作簿从这些文件导入工作表的代码简单明了。open()我不介意在导入过程中是否打开这些文件。我只是不希望用户必须单独打开文件。我只需要他们能够选择或导航到所需的文件。@user955289:几分钟后发布代码……哇!这太完美了。我已经尝试了两种选择,并且很可能会使用第二种选择。非常感谢你!!我登录只是为了感谢你并向你致意,悉达思·劳特。你的这段代码是一件真正的艺术品。我一直在寻找这样的代码很长时间了。很高兴我找到了它。从现在起,我的电子表格将采用完全不同的方法。感谢您分享这一惊人的知识。:)谢谢你的邀请。我想暂时远离ADO,直到我能够进一步研究它。当我更熟悉ADO时,我将保留此作为参考。您还可以使用range对象上的
CopyFromRecordset
方法将记录集转储到工作表中。
Sub test()
Dim data As Variant
data = getDataFromClosedExcelFile("myFile.xls", "Sheet1")
If Not isArrayEmpty(data) Then
'Copies content on active sheet
ActiveSheet.Cells(1,1).Resize(UBound(data,1), UBound(data,2)) = data
End If
End Sub
Option Explicit
Sub Sample()
Dim wb1 As Workbook, wb2 As Workbook
Dim Ret1, Ret2
Set wb1 = ActiveWorkbook
'~~> Get the first File
Ret1 = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*", _
, "Please select first file")
If Ret1 = False Then Exit Sub
'~~> Get the 2nd File
Ret2 = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*", _
, "Please select Second file")
If Ret2 = False Then Exit Sub
Set wb2 = Workbooks.Open(Ret1)
wb2.Sheets(1).Copy Before:=wb1.Sheets(1)
ActiveSheet.Name = "Blah Blah 1"
wb2.Close SaveChanges:=False
Set wb2 = Workbooks.Open(Ret2)
wb2.Sheets(1).Copy After:=wb1.Sheets(1)
ActiveSheet.Name = "Blah Blah 2"
wb2.Close SaveChanges:=False
Set wb2 = Nothing
Set wb1 = Nothing
End Sub
Option Explicit
Sub Sample()
Dim wb1 As Workbook, wb2 As Workbook
Dim Ret1, Ret2
Set wb1 = ActiveWorkbook
'~~> Get the first File
Ret1 = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*", _
, "Please select first file")
If Ret1 = False Then Exit Sub
'~~> Get the 2nd File
Ret2 = Application.GetOpenFilename("Excel Files (*.xls*), *.xls*", _
, "Please select Second file")
If Ret2 = False Then Exit Sub
Set wb2 = Workbooks.Open(Ret1)
wb2.Sheets(1).Cells.Copy wb1.Sheets(1).Cells
wb2.Close SaveChanges:=False
Set wb2 = Workbooks.Open(Ret2)
wb2.Sheets(1).Cells.Copy wb1.Sheets(2).Cells
wb2.Close SaveChanges:=False
Set wb2 = Nothing
Set wb1 = Nothing
End Sub