6

如何链接 Excel 电子表格中的数据范围,以便该范围中的数据在 Access 中显示为可用表?

链接到具有从单元格 A1 开始的数据的 Excel 工作表很容易,但是 Excel 电子表格中的数据从工作表的其他地方开始,我不确定如何让 Access 精确定位它,特别是如果那个非 A1范围是动态的。

通过导入/链接向导时,访问似乎没有选择命名/动态范围。

真实世界场景:

我有一个 Excel 电子表格文件,我们称之为“ ExcelFile1.xls ”,它是从外部提供给我的(所以我不能真正改变它的格式)。

1 个工作表/选项卡,我们称之为“动态”,有一个我希望在 Access 中作为表可用的数据范围,但它的列标题从第 14 行开始,一直到 EL 列。我希望 Access 将这个数据范围作为一个表格。此外,“ ExcelFile1.xls ”也将定期更新,即“ExcelFile.xls”文件的新版本将可用,但在第 14 行的列标题下方有更多数据,所以理想情况下我希望 Access 获取新版本每当我覆盖以前版本的“ ExcelFile1.xls ”时,此范围内的数据。

我还有另一个 Excel 电子表格文件,我们称它为“ ExcelFile2.xls ”,再次由外部提供给我。

这有一个工作表/选项卡,我们称之为“静态”,它同样有一个我想要在 Access 中作为表格的数据范围,并且同样会有更新版本的“ ExcelFile2.xls ”,它将覆盖我之前的版本理想情况下,就像 Access 一样。这个范围是A14:O19并且将永远是这个范围(即静态范围)。

总而言之:我想将 Access 链接到来自 2 个各自 Excel 文件的 2 个数据范围,以在 Access 中生成 2 个单独的表。源数据范围中的 1 个是动态的,另一个是静态的。如果可能的话,我希望 Access 通过使用完全相同的文件名和路径的新版本覆盖源 Excel 文件来获取新数据。

4

2 回答 2

5

好的,从这里关于这个问题的有用指针,以及我在其他地方提出的其他一些问题,我认为对于任何想要从 Excel 电子表格中提取数据作为动态范围或静态范围的人来说,我有一个相当简单的解决方案,其中Excel 中的数据不在单元格 A1 中开始。

这两个示例都使用按钮来启动代码。您显然不必这样做,但如果这样做,您将需要创建一个表单和按钮,然后从按钮上运行代码生成器,并用下面您需要的任何解决方案替换该代码。

动态范围:

请注意,此动态范围示例假定 Excel 中的单元格范围始终从相同的最左上角位置开始,并且列数始终相同 - 即唯一动态的是底部行数你的细胞范围。

您需要根据自己的设置换出的参考资料:

  • C:\Users\Matt\Desktop\ExcelFile1.xls替换为 Excel 文件的完整路径

  • Dynamic替换为 Excel 文件中包含的工作表名称

  • A14:A2000替换为您要测试的范围以查看有多少非空单元格。这个范围应该: 从列标题所在的数据行开始;覆盖您要导入的数据中永远不会有空单元格条目的列;覆盖的范围足够大,以至于它总是会超过 Excel 电子表格中包含实际数据的行数。

  • ExcelDynamicRangeData替换为您想要在 Access 中调用包含从 Excel 范围中提取的数据的表的任何内容。

  • Dynamic!A14:EL替换为工作表的名称、Excel 范围的最顶部/最左侧的单元格引用和最右侧的列字母。不要包括最底部/最右侧的行号,因为这是需要动态的,因此numberofrows稍后将其分配给该范围的末尾并将其连接到该范围的末尾。

  • numberofrows = 13 ...将 13 替换为列标题开始位置上方的行数。例如,如果您的列标题从第 4 行开始,则此数字需要为 3。

  • Command0替换为用于启动所有此代码的按钮的名称。

Sub ImportDataFromRange()

' Assign the Excel Object
Dim excelapp As Object
Set excelapp = CreateObject("excel.application")

' Assign the workbook
Dim wb As Object
Set wb = excelapp.Workbooks.Open("C:\Users\Matt\Desktop\ExcelFile1.xls")

' Assign the result of your CountA function used in the next line
Dim numberofrows As Integer

' Get the bottom-most row number needed to complete our dynamic range address
numberofrows = 13 + excelapp.Application.CountA(wb.worksheets("Dynamic").Range("A14:A2000"))

' Delete any previous access table, otherwise the next line will add an additional table each time it is run
DoCmd.DeleteObject acTable, "ExcelDynamicRangeData"

' Import data from Excel using a range that now knows where bottom row number is
DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel9, "ExcelDynamicRangeData", "C:\Users\Matt\Desktop\ExcelFile1.xls", True, "Dynamic!A14:EL" & numberofrows

' Close and clean
wb.Close
Set wb = Nothing
excelapp.Quit
Set excelapp = Nothing

End Sub    

Private Sub Command0_Click()

ImportDataFromRange

End Sub

静态范围:

这要简单得多,因为无需打开 Excel 工作簿即可CountA对数据应用函数。

您需要根据自己的设置换出的参考资料:

  • C:\Users\Matt\Desktop\ExcelFile2.xls替换为 Excel 文件的完整路径

  • ExcelStaticRangeData替换为您想要在 Access 中调用包含从 Excel 范围中提取的数据的表的任何内容。

  • Static!A14:EL20替换为工作表的名称,以及要导入的 Excel 中单元格的完整范围地址。由于此方法描述了如何从 Excel 中获取静态数据范围以访问 Excel 中的数据,因此您要导入的数据永远不应超出此范围。

  • Command0替换为用于启动所有此代码的按钮的名称。

Sub ImportDataFromRange()

' Delete any previous access table, otherwise the next line will add an additional table
DoCmd.DeleteObject acTable, "ExcelStaticRangeData"

' Import data from Excel using a static range
DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel9, "ExcelStaticRangeData", "C:\Users\Matt\Desktop\ExcelFile2.xls", True, "Static!A14:EL20"

End Sub    

Private Sub Command0_Click()

ImportDataFromRange

End Sub

注意

  • 两种方法中的acSpreadsheetTypeExcel9位指的是您正在导入的 Excel 文件的版本;在我的示例中,我正在导入 Excel 2000 格式;您可能正在导入不同版本的 Excel,因此请参阅以查看您需要在代码中引用哪个版本;.xlsx文件未列出,但应该是acSpreadsheetTypeExcel12Xml.

  • 我的示例将数据作为源数据的活动链接引入 Access。如果您有大量数据,您可能会发现将数据实际导入并存储到 Access 中会更好,因为链接可能会导致一些性能问题。如果是这种情况,请换掉acLinkacImport

  • 如果您尚未在 Access 中手动创建一个空白表(在代码中引用了相同的表名),那么您要么需要这样做,要么DoCmd.DeleteObject acTable, "yourAccessTable"在第一次运行代码时注释掉,然后再恢复这部分.

可能还有更多的事情可以做 - 即,如果您的数据源具有不同数量的列,则调整 CountA 函数以考虑动态的列数。

再次感谢@david-zemens、@gord-thompson 以及其他 StackoverFlow 用户帮助我实现这一点 - 这对我和希望其他人都非常有用。

于 2013-04-11T11:08:04.917 回答
2

我不是 Access 的人,但让我给你一些应该能够帮助你的建议。

1 个工作表/选项卡,我们称之为“动态”,有一个我希望在 Access 中作为表格可用的数据范围,但它的列标题从第 14 行开始,一直到 EL 列。我希望 Access 将这个数据范围作为一个表格。此外,“ExcelFile1.xls”也将定期更新,即“ExcelFile.xls”文件的新版本将可用,但在第 14 行的列标题下方有更多数据,所以理想情况下我希望 Access 获取新版本每当我覆盖以前版本的“ExcelFile1.xls”时,此范围内的数据。

好的,所以在此工作表上,您将要建立一个动态命名范围。基本上,您创建一个公式来确定/调整范围的大小,只要向其中添加新数据。

有关如何创建动态命名范围的概述,请从这里开始:

http://support.microsoft.com/kb/830287

那么,使用 VBA,最坏的情况是您可以访问此命名范围,将其内容读入数组变量或简单地遍历行/列,然后将这些内容写入您的 Access 表。但是,不是 Access 程序员,可能有一些更有效的方法可以做到这一点。

这有一个工作表/选项卡,我们称之为“静态”,它同样有一个我想要在 Access 中作为表格的数据范围,并且再次,将有更新版本的“ExcelFile2.xls”覆盖我之前的版本理想情况下,就像 Access 一样。这个范围是 A14:O19 并且总是这个范围(即静态范围)。

您同样可以创建另一个命名范围,=$A$14:$O$19该范围定义为静态命名范围。然后,您可以像上面一样对待它。

编辑这是获取 Excel 数据然后遍历行和列的示例,您只需添加代码以将字段/记录/等添加到 Access 中的表中。

Sub ImportDataFromRange()
'Access variables
Dim dbFile As Database
Dim tbl As TableDef, fld As Field

'Excel variables
Dim xlApp As Excel.Application
Dim xlFile As Excel.Workbook
Dim xlSheet As Excel.Worksheet
Dim xlRange As Excel.Range
Dim r#, c#
Dim clVal As String 'string to hold cell's value, may need to modify this type.

Set dbFile = CurrentDb

'Use this to create a new table definition
'    Set tbl = dbFile.CreateTableDef("Test")
'Use this if your table already exists:
    Set tbl = dbFile.TableDefs("Test")

'Get the info from Excel:
Set xlApp = New Excel.Application

Set xlFile = xlApp.Workbooks.Open("C:\Users\david_zemens\desktop\Book1.xlsx")
Set xlSheet = xlFile.Sheets("Sheet1")
Set xlRange = xlSheet.Range("A1:B10")

    For r = 1 To xlRange.Rows.Count
        For c = 1 To xlRange.Columns.Count

            'Add code to append new fields/records/etc to your table

        Next c
    Next r

xlApp.Quit
Set xlApp = Nothing


End Sub

希望这足以让你开始!

于 2013-04-10T16:30:59.537 回答