从有关的工作簿中取值有多种方法,现将网上收集的整理向大家共享。
方法 1、使用公式 方法 2、使用 GetObject 函数 、 方法 3、隐藏 Application 对象 方法 4、使用 ExecuteExcel4Macro 方法
方法 5、使用 SQL 连接 1、使用公式 、 如果需要引用的数据不是太多,可以使用公式取得引用工作簿中的工作表数据,如下面的代码所示。
Sub CopyData_1() Dim Temp As String
Temp = "'" & ThisWorkbook.Path & "¥[数据表.xls]Sheet1'!"
With Sheet1.Range("A1:F22")
.FormulaR1C1 = "=" & Temp & "RC"
.Value = .Value
End With
End Sub 代码解析: CopyData_1 过程在工作表中写入公式引用“数据表”中同一位置单元格中的数据。 第 3 行代码将引用工作簿的路径赋给变量 Temp。 第 5 行代码在作表中写入公式引用数据。 第 6 行代码将公式转换为数值。 2、使用 GetObject 函数 、
使用 GetObject 函数来获取对指定的 Excel 工作表的引用,如下面的代码所示。 Sub CopyData_2() Dim Wb As Workbook
Dim Temp As String
Application.ScreenUpdating = False
Temp = ThisWorkbook.Path & "¥数据表.xls"
Set Wb = GetObject(Temp)
With Wb.Sheets(1).Range("A1").CurrentRegion
Range("A1").Resize(.Rows.Count, .Columns.Count) = .Value Wb.Close False
End With
Set Wb = Nothing
Application.ScreenUpdating = True
End Sub 代码解析: CopyData_2 过程使用 GetObject 函数来获取“数据表”工作簿中的数据。 第 4 行代码关关屏幕更新加快运行速度。 第 5 行代码将引用工作簿的路径赋给变量 Temp。 第 6 行代码使用 Set 语句将 GetObject 函数返回的对象赋给对象变量 Wb。 GetObject 函数返回文件中的 ActiveX 对象的引用,语法如下:
GetObject([pathname] [, class])
参数 pathname 是可选的,包含待检索对象的文件的全路径和名称。如果省略,则 class 参数是必需的。
参数 class 是可选的,代表该对象的类的字符串。 Class 参数的格式为 appname.objecttype,语法的各个部分如表格 1 所示。
部分 描述
appname 必需的,提供该对象的应用程序名称。 objecttype 必需的,待创建对象的类型或类。
表格 1 Class 参数语法的各个部分 第 7 行到第 10 行代码,当 GetObject 函数指定的对象被激活之后,就可以在代码中使用对象变量 Wb 来访问这个对象的属性 和方法。 其中第 7、8 行代码将“数据表”工作簿中的第 1 张工作表已使用区域的数据赋给本工作表的单元格,第 9 行代码关关“数据表”工 作簿,使用 GetObject 函数返回对象的引用时,虽然在窗口中看不到对象的实例,但实际上是打开的,所以需用 Close 语句将 其关关。 第 12 行代码开启屏幕更新。
3、隐藏 Application 对象 通过隐藏 Application 对象来模拟不打开工作簿取数,如下面的代码所示。
Sub CopyData_3() Dim myApp As New Application
Dim Sh As Worksheet Dim Temp As String T
emp = ThisWorkbook.Path & "¥数据表.xls"
myApp.Visible = False
Set Sh = myApp.Workbooks.Open(Temp).Sheets(1)
With Sh.Range("A1").CurrentRegion
Range("A1").Resize(.Rows.Count, .Columns.Count) = .Value
End With
myApp.Quit
Set Sh = Nothing
Set myApp = Nothing
End Sub 代码解析: CopyData_3 过程隐藏 Application 对象来模拟不打开工作簿取数。 第 2 行代码使用 New 关键字隐式地创建一个 Application 对象。 第 6 行代码将新创建的 Application 对象的 Visible 属性设置为 False,使之隐藏。 第 7 行代码使用 Open 方法打开“数据表”工作簿(关于 Open 方法请参阅技巧 42 ,因为工作簿是使用新创建的、隐藏的 Application 对象打开的,所以在窗口中是不可视的。 第 8 行到第 10 行代码将“数据表”工作簿中的第 1 张工作表已使用区域的数据赋给本工作表的单元格。 第 11 行代码使用 Quit 方法退出新打开的 Excel 程序。 4、使用 ExecuteExcel4Macro 方法 使用 ExecuteExcel4Macro 方法可以做到不打开工作簿的情况下获取其他工作薄中指定工作表的数据,如下面的代码所示。
Sub CopyData_4() Dim RCount As Long
Dim CCount As Long
Dim Temp As String
Dim Temp1 As String
Dim Temp2 As String
Dim Temp3 As String
Dim R As Long
Dim C As Long Dim arr() As Variant
Temp = "'" & ThisWorkbook.Path & "¥[数据表.xls]Sheet1'!"
Temp1 = Temp & Rows(1).Address(, , xlR1C1)
Temp1 = "Counta(" & Temp1 & ")"
CCount = Application.ExecuteExcel4Macro(Temp1)
Temp2 = Temp & Columns("A").Address(, , xlR1C1)
Temp2 = "Counta(" & Temp2 & ")"
RCount = Application.ExecuteExcel4Macro(Temp2)
ReDim arr(1 To RCount, 1 To CCount)
For R = 1 To RCount
For C = 1 To CCount
Temp3 = Temp & Cells(R, C).Address(, , xlR1C1)
arr(R, C) = Application.ExecuteExcel4Macro(Temp3)
Next
Next Range("A1").Resize(RCount, CCount).Value = arr
End Sub 代码解析: CopyData_4 过程使用 ExecuteExcel4Macro 方法获取“数据表”工作薄中指定工作表的数据。 第 14、16 行代码使用 ExecuteExcel4Macro 方法执行 Counta 函数取得“数据表”工作薄中指定工作表的行数和列数合计。 ExecuteExcel4Macro 方法执行一个 Microsoft Excel 4.0 宏函数,然后返回此函数的结果,语法如下: expression.ExecuteExcel4Macro(String) 参数 expression 是可选的,返回一个 Application 对象。 参数 String 是必需的,一个不带等号的 Microsoft Excel 4.0 宏语言函数,所有引用必须是像 R1C1 这样的字符串。 因为 Microsoft Excel 4.0 宏不在当前工作簿或工作表的环境中求值,所有的引用都是外部引用,所以无需打开引用工作簿但是 需要明确指定工作簿名称。 第 18 行代码使用 ReDim 语句为动态数组 arr 重新分配存储空间。 第 19 行到第 24 行代码循环取值,将“数据表”工作薄中指定工作表的数据赋给动态数组 arr。 第 25 行代码将动态数组 arr 的值赋给工作表的单元格。 5、使用 SQL 连接使用 SQL 建立与工作簿的连接,查询数据记录后复制到当前工作表中,如下面的代码所示。
Sub CopyData_5() Dim Sql As String
Dim j As Integer
Dim R As Integer
Dim Cnn As ADODB.Connection
Dim rs As ADODB.Recordset
With Sheet5
.Cells.Clear
Set Cnn = New ADODB.Connection
With Cnn
.Provider = "microsoft.jet.oledb.4.0"
.ConnectionString = "Extended Properties=Excel 8.0;" _ & "Data Source=" & ThisWorkbook.Path & "¥数据表"
.Open
End With
Set rs = New ADODB.Recordset
Sql = "select * from [Sheet1$]"
rs.Open Sql, Cnn, adOpenKeyset, adLockOptimistic
For j = 0 To rs.Fields.Count - 1
.Cells(1, j + 1) = rs.Fields(j).Name
Next
R = .Range("A65536").End(xlUp).Row
.Range("A" & R + 1).CopyFromRecordset rs
End With
rs.Close
Cnn.Close
Set rs = Nothing
Set Cnn = Nothing
End Sub 代码解析: CopyData_5 过程使建立与“数据表”工作簿的连接,查询数据记录后复制到当前工作表中。 第 8 行代码删除当前工作表的所有数据。 第 9 行到第 15 行代码建立与“数据表”工作簿的连接。 第 16 行到第 24 行代码查询“数据表”工作簿的全部数据,并复制到工作表中。其中第 20 行代码将字段名称(标题行)复制到 工作表中,第 23 行代码将查询到的数据记录复制到工作表。 其它收集的相关内容: 收集的相关内容 示例代码 1: Sub testGetValuesFromClosedWorkbook() GetValuesFromAClosedWorkbook "C:", "Book1.xls", "Sheet1", "A1:G20"
End Sub
Sub GetValuesFromAClosedWorkbook(fPath As String, fName As String, sName, cellRange As String) With ActiveSheet.Range(cellRange)
.FormulaArray = "='" & fPath & "\[" & fName & "]" & sName & "'!" & cellRange
.Value = .Value
End With
End Sub
本 示 例 包 含 一 个 子 过 程 GetValuesFromAClosedWorkbook , 用 来 从 已 关 关 的 工 作 簿 中 获 取 数 据 , 主 过 程 testGetValuesFromClosedWorkbook 用来传递参数。本示例表示从 C 盘根目录下的 Book1.xls 工作簿的工作表 Sheet1 中的 A1:G20 单元格区域内获取数据,并将其复制到当前工作表相应单元格区域中。 示例代码 2: 已前面的代码相似,下面的 VBA 代码从关关的工作簿中获取值。 Sub ExtractDataFromClosedWorkBook() Application.ScreenUpdating = False '创建链接来从关闭的工作簿中获取数据 '可以将相关代码修改为相应的路径和单元格
With [Sheet1!A1:B4]
.Value = "='" & ActiveWorkbook.Path & "\[testDataWorkbook.xls]Sheet1'!A1:B4"
'删除链接
.Value = .Value
End With
Application.ScreenUpdating = True End Sub 其中,可以将代码中的路径修改为需要从中获取值的工作簿的路径,单元格也作相应的修改。 示例代码 3: Sub GetDataFromClosedWorkbook() Dim wb As Workbook
Application.ScreenUpdating = False '以只读方式打开工作簿
Set wb = Workbooks.Open("C:\文件夹名\文件.xls", True, True)
With ThisWorkbook.Worksheets("工作表名")
'从工作簿中读取数据
.Range("A10").Formula = wb.Worksheets("源工作表名").Range("A10").Formula
.Range("A11").Formula = wb.Worksheets("源工作表名").Range("A20").Formula
.Range("A12").Formula = wb.Worksheets("源工作表名").Range("A30").Formula
.Range("A13").Formula = wb.Worksheets("源工作表名").Range("A40").Formula
End With
wb.Close False
'关闭打开的源数据工作簿且不保存任何变化
Set wb = Nothing '释放内存
Application.ScreenUpdating = True
End Sub
在运行程序时,打开所要获取数据的工作簿,当取得数据后再关关该工作簿。将屏幕更新属性值设置为 False,将看不出 源数据工作簿是否被打开过。本程序代码中,“C:\文件夹名\文件.xls”、”源工作表名”代表工作簿所在的文件夹和工作簿 文件名。 示例代码 4: 下面是 JOHN WALKENBACH 先生使用 VBA 编写的一个实用函数,其作用是从关关的工作簿中取值。 VBA 没有包含从关关的文件中获取值的方法,但是利用 Excel 处理连接文件的功能,可以实现。该函数要调用 XLM 宏, 但不能在工作表公式中使用该函数。 GetValue 函数 具有四个参数,分别如下: path: 关 关 的文件的驱 动 器和路径(例如”d:¥files”) file: 工作簿名称(例如”99budget.xls”)
sheet: 工作表名称(例如”Sheet1″)
ref: 单元格引用(例如”C4″)
Private Function GetValue(path, file, sheet, ref) ' 从一个关关的工作簿中获取值
Dim arg As String ' 确保该文件存在
If Right(path, 1) <> "\" Then path = path & "\"
If Dir(path & file) = "" Then
GetValue = "File Not Found"
Exit Function
End If
' 创建参数
arg = "'" & path & "[" & file & "]" & sheet & "'!" & Range(ref).Range("A1").Address(, , xlR1C1)
' 执行 XLM 宏
GetValue = ExecuteExcel4Macro(arg)
End Function
使用 GetValue 函数 要使用该函数,将其复制到 VBA 模块中,然后使用合适的参数调用该函数。 子过程演示如下,简单地显示在名为 99Budget.xls 工作簿 Sheet1 的单元格 A1 中的值,该文件在驱动器 C:中的 XLFiles\Budget 目录下。 Sub TestGetValue() p = "c:\XLFiles\Budget"
f = "99Budget.xls"
s = "Sheet1″"
a = "A1″"
MsgBox GetValue(p, f, s, a)
End Sub
另一个示例如下,该过程从一个有关 的文件中读取 1,200 个值(100 行和 12 列),并将这些值放置到活动工作表中。
Sub TestGetValue2() p = "c:\XLFiles\Budget"
f = "99Budget.xls"
s = "Sheet1″"
Application.ScreenUpdating = False
For r = 1 To 100
For c = 1 To 12
a = Cells(r, c).Address
Cells(r, c) = GetValue(p, f, s, a)
Next c
Next r
Application.ScreenUpdating = True
End Sub
注意: 为了使该函数正常运行,在 Excel 中必须有一个活动工作表。如果所有窗口都是隐藏的,或者活动工作表为图表工作表, 那么将产生错误。 示例代码 5:
Sub ReadDataFromAllWorkbooksInFolder() Dim FolderName As String, wbName As String, r As Long, cValue As Variant
Dim wbList() As String, wbCount As Integer, i As Integer
FolderName = "C:\文件夹名" '创建文件夹中工作簿列表
wbCount = 0
wbName = Dir(FolderName & "\" & "*.xls")
While wbName <> ""
wbCount = wbCount + 1
ReDim Preserve wbList(1 To wbCount)
wbList(wbCount) = wbName
wbName = Dir
Wend
If wbCount = 0 Then Exit Sub
'从每个工作簿中获取数据
r = 0
Workbooks.Add
For i = 1 To wbCount
r = r + 1 cValue = GetInfoFromClosedFile(FolderName, wbList(i), "Sheet1", "A1")
Cells(r, 1).Formula = wbList(i)
Cells(r, 2).Formula = cValue
Next i
End Sub
Private Function GetInfoFromClosedFile(ByVal wbPath As String, wbName As String, wsName As String, cellRef As String) As Variant Dim arg As String
GetInfoFromClosedFile = ""
If Right(wbPath, 1) <> "\" Then wbPath = wbPath & "\"
If Dir(wbPath & "\" & wbName) = "" Then Exit Function
arg = "'" & wbPath & "[" & wbName & "]" & wsName & "'!" & Range(cellRef).Address(True, True, xlR1C1)
On Error Resume Next
GetInfoFromClosedFile = ExecuteExcel4Macro(arg)
End Function 本示例将读取一个文件夹内所有工作簿中工作表 Sheet1 单元格 A1 的值到一个新工作簿中。代码中,“C:\文件夹名”代 表工作簿所在的文件夹名。 |
|