将Excel中的dynamic和静态范围导入到不在单元格A1开始的MS-Access中

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

链接到单元格A1上有数据的Excel工作表很容易,但是Excel电子表格中的数据从工作表的其他位置开始,我不确定如何让Access指向它,特别是如果非A1范围是dynamic的。

通过导入/链接向导时,Access似乎没有拿起命名/dynamic范围。

真实世界场景:

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

我们把它称为“ dynamic ”,它有一个我希望作为Access表中的数据范围,但是它的列标题从第14行开始,到达列EL。 我想要做的是拿起这个数据范围作为一个表。 此外,“ ExcelFile1.xls ”也将定期更新,即“ExcelFile.xls”文件的新版本将变得可用,但更多的数据在第14行的列标题下,所以理想情况下,我希望Access拿起新的每当我覆盖以前版本的“ ExcelFile1.xls ”时,数据就在这个范围内。

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

这有一个表单/选项卡,我们称之为“ 静态 ”,同样有一个数据范围,我希望作为Access中的一个表格,再次,会有更新版本的“ ExcelFile2.xls ”,将覆盖以前的版本,我会理想地喜欢接入去接。 这个范围是A14:O19并且一直是这个范围(即静态范围)。

总之:我想将Access从2个Excel文件链接到2个数据范围,以在Access中生成2个独立的表。 源数据范围中的1个将是dynamic的,另一个将是静态的。 如果可能,只需使用完全相同的文件名和path的新版本覆盖源Excel文件,就可以使用Access访问新数据。

好的,从这个问题的有用指针和其他地方提出的一些其他问题,我想我有一个相当简单的解决scheme,任何人想要从Excel电子表格中提取数据作为dynamic范围或静态范围, Excel中的数据不能在单元格A1中启动。

这两个例子都使用一个button来启动代码。 你显然不需要这样做,但是如果你这样做,你需要创build一个表单和button,然后运行代码生成器closuresbutton,并用下面你需要的解决schemereplace代码。

dynamic范围:

请注意,这个dynamic范围的例子假设你在Excel中的单元格区域总是从最左上angular的位置开始,而列的数量总是相同的 – 即唯一dynamic的是最后一行你的细胞的范围。

您需要根据自己的设置进行交换:

  • C:\Users\Matt\Desktop\ExcelFile1.xls用您的Excel文件的完整pathreplace

  • Dynamicreplace您的Excel文件中包含的工作表的名称

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

  • ExcelDynamicRangeDatareplace任何你想调用Access中的表,将包含从您的Excel范围内拉出的数据。

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

  • numberofrows = 13 ...numberofrows = 13 ...replace为上面列标题开始的那么多行。 例如,如果您的列标题从第4行开始,则此数字需要为3。

  • Command0replace为用于启动所有这些代码的button的名称。

 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文件的完整pathreplace

  • ExcelStaticRangeDatareplace为您要调用Access中的表格,该表格将包含从Excel范围内拉取的数据。

  • Static!A14:EL20用您的工作表的名称以及要导入的Excel中单元格的全范围地址进行replace。 由于此方法描述了如何从Excel中获取数据的静态范围,因此在Excel中访问数据时,您想要导入的数据绝对不能超出此范围。

  • Command0replace为用来启动所有这些代码的button的名称。

 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中会更好,因为链接可能会导致一些性能问题。 如果是这种情况, acImport

  • 如果您尚未在Access中手动创build一个空白表格(在您的代码中引用了相同的表格名称),那么您需要执行该操作或注释掉DoCmd.DeleteObject acTable, "yourAccessTable"代码的第一次然后运行,然后恢复此部分。

可能还有更多的事情可以做到 – 即如果数据源的列数不同,可以使用CountA函数来考虑列的dynamic数量。

还要感谢@ david-zemens,@ gord-thompson以及其他StackoverFlow的用户帮助我实现这一目标 – 这对我和其他人来说都是非常有用的。

我不是一个访问的人,但让我给你一些指针,应该能够帮助你。

我们把它称为“dynamic”,它有一个我希望作为Access表中的数据范围,但是它的列标题从第14行开始,到达列EL。 我想要做的是拿起这个数据范围作为一个表。 此外,“ExcelFile1.xls”也将定期更新,即“ExcelFile.xls”文件的新版本将变得可用,但更多的数据在第14行的列标题下,所以理想情况下,我希望Access拿起新的每当我覆盖以前版本的“ExcelFile1.xls”时,数据就在这个范围内。

好的,所以在这个工作表上,你需要build立一个dynamic命名范围。 基本上你创build一个公式来决定/调整范围,每当新的数据添加到它。

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

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

对于VBA,最坏的情况是你可以访问这个命名的范围,把它的内容读入一个数组variables,或者只是遍历行/列,然后把这些内容写到你的Access表中。 但是,不是一个Access程序员,可能会有一些稍微有效的方法来做到这一点。

这有一个表单/选项卡,我们称之为“静态”,同样有一个数据范围,我希望作为Access中的一个表格,再次,会有更新版本的“ExcelFile2.xls”,将覆盖以前的版本,我会理想地喜欢接入去接。 这个范围是A14:O19,并且一直是这个范围(即静态范围)。

你也可以创build另一个命名范围,定义为=$A$14:$O$19 ,这将是一个静态命名范围。 那么,你可以像上面那样对待它。

编辑这里是获取Excel数据,然后迭代行和列的示例,您只需要添加代码以将字段/logging/等添加到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 

希望这足以让你开始!