'Error 380: Could not set the RowSource property. Invalid Property value' Excel 用户表单将数据从 Access 导入到 Excel

'Error 380: Could not set the RowSource property. Invalid Property value' for Excel user form to import data from Access to Excel

我在 Windows 7 中使用 Excel 2013。

我在 Excel 中创建了一个用户窗体,在 Excel 中使用 VBA 将数据从 Access 导入到 Excel 中,点击每个 onlinepclearning(点)按钮后com/append-and-delete-ms-access-record-sets-from-an-excel-userform/.该站点是他修改导入子例程的地方。

点击“导入”按钮后,Access 中的数据应显示在用户窗体的列表框中。数据不会直接导入到用户窗体中,而是导入到工作表中并在工作表中引用为命名范围(称为 DataAccess,命名范围公式为:OFFSET(Import!$A$1,1,COUNTA(Import!$ A$2:$A$10000),7)——在用户表单中,我们从 Access 传输到 Excel) 的 table 有 7 个字段。

Name Manager

Excel 中用户表单的屏幕截图:

Excel Userform

当我点击用户表单上的“导入”按钮时,我得到 'Error 380: Could not set the RowSource property. Invalid Property value'。命名范围或列表框有问题吗?翻了那么多tuts都没有答案

我也试过改变:

  1. 我到 UserForm1 并在过程 Import_Data.
  2. 中收到错误 424(需要 Object)
  3. Me.listData...="Sheet2!DataAccess" 我收到了原始错误 380,但导入到 Excel Sheet2 的数据不是 Excel 用户表单上的列表框.
  4. Me.listData...=Sheet2!DataAccess 没有引号,我在过程 Import_Data 中收到错误 438(Object 不支持此 属性 或方法)但是导入到 Excel Sheet2 的数据不是 Excel 用户表单上的列表框。
  5. Me.listData...Import!DataAccess 并且我收到编译错误:预期函数或变量。 Excel.
  6. 的Sheet2没有数据过来
  7. Me.listData...Sheet2.Range("DataAccess") 但在程序 Import_Data 但导入到 Excel Sheet2 的数据不是 Excel 用户表单上的列表框。

(1) 更新 1 8/5/2016 - 我已经删除了 DataAccess 周围的引号,而没有参考 Sheet2!因此 Sub ImportUserForm() 中的一行代码读取

Me.lstDataAccess.RowSource = DataAccess

我现在不会收到任何错误消息,而是会收到一个消息框,说明数据已导入;但是,数据仅出现在 OFFSET/Named 范围引用的电子表格(Sheet2!又名导入!)中,而不是我的列表框。

其他教程说要设置列宽(我设置为 40 pt;40pt,等等...总共 7 倍)和列数(我设置为 7)

Excel.

用户窗体的列表框中仍然没有数据出现

这是名为 lstDataAccess 的列表框代码以及初始化用户窗体的代码。我不知道他们为什么要双击它(不确定这意味着什么)b/c 他在教程中所做的一切都是点击导入按钮,Access table 中的所有数据都将导入到 Excel 用户表单。

(Arec1-7是userform上的文本框名称,对应Access中的字段名--Surname, FirstName, Address等)
(lstDataAccess 是用户窗体上列表框的名称。)

Private Sub lstDataAccess_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
'dim the variables
Dim i As Integer

'find the selected list item
i = Me.lstDataAccess.ListIndex
Me.lstDataAccess.Selected(i) = True

'add the values to the text boxes
Me.Arec1.Value = Me.lstDataAccess.Column(0, i)
Me.Arec2.Value = Me.lstDataAccess.Column(1, i)
Me.Arec3.Value = Me.lstDataAccess.Column(2, i)
Me.Arec4.Value = Me.lstDataAccess.Column(3, i)
Me.Arec5.Value = Me.lstDataAccess.Column(4, i)
Me.Arec6.Value = Me.lstDataAccess.Column(5, i)
Me.Arec7.Value = Me.lstDataAccess.Column(6, i)
End Sub

Private Sub UserForm_Initialize()
'does not get assigned to any button
Me.Arec1 = Sheet1.Range("J3").Value
End Sub

(同样,所有这些代码都在用户窗体中,而不是教程电子表格部分的模块中。)

(1) END OF UPDATE 1 8/5/2016 -(我将在下面的答案中尝试 Private Sub Import_Click(),但是我看到没有其他代码适用于该项目的导入部分。剩下的就是关闭,打开用户窗体,然后追加和删除数据,但我需要先将数据导入列表框,然后才能铲球 append/delete.)

(2) 更新 8/5/2016 - 为了清楚起见,我用整个代码替换了 Sub ImportUserForm () 的代码。

我只能添加两个 link b/c 根据论坛规则我需要 10 个声望,但我已经添加了命名范围的范围和用户表单的截图。数据从 Access table 导入到 Sheet2!根据命名范围中的 OFFSET 公式将电子表格的一部分添加到 A2 并超过 7 列,如果需要,所有原因都下降到 A10000。目前看起来像这样:

单元格 A1:ID |单元格 B2:Surname |单元格 C3:FirstName |单元格 D4:Address |单元格 E5:Phone |单元格 F6:Mobile |单元格 G7:Email

它正在换行,但是 headers 遍历 Excel 中的 7 列,数据从第 2 行(A2 到 G2)一直到第 7 行 b/c 我只有Access 中的 7 行数据。

(3) 更新 8/6/2016 下面是 link 从 Google 文档下载文件。请参阅下面的请注意 b/c 它半工作但我想在名称 mgr 中使用 OFFSET 函数而不是我现在使用的使用绝对范围的修复。

-Excel wkbk 和 userform -(我不允许包含更多 links 所以见下文)https(冒号)//docs(点)google(点)com/spreadsheets/d/1tRF3bJf4ng-bM6Kiefptpbrw9jr4T_BGZ0gKm9S9614/edit?usp=共享 (只需单击导出 wksht 上的按钮,单击用户窗体,即可激活用户窗体。我不需要帮助与任一工作表上的任何其他按钮,包括。导入 wksht 上的导入按钮。)

-使用PhoneList访问数据库table - https(冒号)//drive(点)google(点)com/file/d/0B9IyKJSJ52ghNEFfYVNWUE1wcEU/view?usp=sharing

工作原理:我想导入的原因是 b/c 我需要查看 append/delete 按钮是否适用于用户窗体。您应该能够将数据从 Access table PhoneList 导入到 Excel 用户窗体上的列表框,它实际上是导入到 Import wksht 并通过命名范围 DataAccess 反映到列表框。然后您应该能够从列表框中 select 一行导入的数据,它将出现在上面的文本框中,这样您就可以根据需要更改数据,然后在 Access 中附加 table 或者您可以只需通过添加或删除按钮删除数据行。

请注意: 用户窗体上的导入现在将数据导入用户窗体上的列表框,但仅在我关闭并打开用户窗体之后。我应该能够单击“导入”按钮,即使旁边的搜索框中没有任何内容,也可以从 Access 数据库中导入所有数据。您必须从导入工作表中删除数据才能清除用户表单上的数据并重新开始。

  1. 我转到用户窗体列表框的属性并更改:
    列数为 7
    列宽为 40 pt
    multiselect 到 1-fmmultiselectmulti
    RowSource to Import!DataAccess(我相信这是一个大关键)

  2. 为了使上述工作正常,我必须更改 DataAccess 命名范围并使其成为绝对范围并删除 OFFSET 函数。 (顺便说一下,带有 OFFSET 的命名范围没有出现在范围 selector 框中,所以现在它出现在范围 selector 中)。名为 KEEP 的名称 mgr 中的命名范围是使用 OFFSET 函数的 DataAccess 的旧命名范围。如果可以的话,我想用这个。

  3. 我尝试使用 Private Sub FillListBoxFromOffsetRange () 但收到错误

    arr.Data=Application.Range("DataAccess")

尝试调试代码时突出显示为黄色。我也尝试从我的 ImportUserForm 代码调用它,但它没有用(也许我做错了),但互联网说你需要从第二个模块调用 Private Sub。我放弃了尝试并开始进行上面的第 1 步并获得 semi-success,但仍然需要帮助。

更新结束 2016 年 8 月 6 日

(以下是原始 post 的延续)

P.S。在将新代码添加到用户窗体之前,我没有双击窗体上的“导入”按钮,但我没有使用另一个按钮这样做,它适用于用户窗体。此外,我将代码添加到用户窗体而不是模块(这是我们用来通过 Excel 工作表上的一些按钮导入和导出 btw Access 和 Excel 的模块)。

我是 VBA 和用户表单的新手。这是他根据网站进行的更正以及摘录的代码:

提前致谢

(1) 更新 2 8/5/2016 - 我在下面添加了 Sub ImportUserForm () 的完整代码。

'Import button click event
Private Sub cmdImport_Click()
ImportUserForm
'Inform the user that the macro was executed successfully.
MsgBox "Congratulation the data has been successfully Imported",  
vbInformation, "Import successful"
End Sub
_____

Sub ImportUserForm()
'we are not importing the data directly into user form but importing onto     
'the worksheet and referencing _
'it as a named range in the user form
'he made a slight change to the code per his Append and Delete webpage b/c     
'once we delete and append data we want to import back into _
'list box again to show new values have been removed or appended
'Declaring the necessary variables.
Dim cnn As ADODB.Connection 'dim the ADO collection class
Dim rs As ADODB.Recordset 'dim the ADO recordset class
Dim dbPath As String
Dim SQL As String
Dim i As Integer
Dim var
'add error handling
On Error GoTo errHandler:
'Disable screen flickering.
Application.ScreenUpdating = False
'clear the values from the worksheet
Sheet2.Range("A2:G10000").ClearContents
'get the path to the database
dbPath = Sheet1.Range("I3").Value
'set the search variable
var = Me.txtSearch
Set cnn = New ADODB.Connection ' Initialise the collection class variable

'Connection class is equipped with a —method— named Open
'—-4 aguments—- ConnectionString, UserID, Password, Options
'ConnectionString formula—-Key1=Value1;Key2=Value2;Key_n=Value_n;
cnn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath

'Create the SQL statement to retrieve the data from table.
If CheckBox1 = True Then
SQL = "SELECT * FROM PhoneList WHERE SURNAME = '" & var & "'"
Else
SQL = "SELECT * FROM PhoneList WHERE SURNAME LIKE '" & var & "%" & "'"
End If

'Create the ADODB recordset object.
Set rs = New ADODB.Recordset 'assign memory to the recordset

'ConnectionString Open '—-5 aguments—-
'Source, ActiveConnection, CursorType, LockType, Options
rs.Open SQL, cnn

'Check if the recordset is empty. 'EOF is end of file
If rs.EOF And rs.BOF Then
'Close the recordet and the connection.
rs.Close
cnn.Close
'clear memory
Set rs = Nothing
Set cnn = Nothing
'Enable the screen.
Application.ScreenUpdating = True
'In case of an empty recordset display an error.
'DataAccess is a named range in the worksheet _
'OFFSET(Import!$A,1,,COUNTA(Import!$A:$A000),7)
MsgBox "There are no records in the recordset!", vbCritical, "No Records"
Me.lstDataAccess.RowSource = ""
Exit Sub
End If

'Write the reocrdset values in the sheet.
Sheet2.Range("A2").CopyFromRecordset rs

'Close the recordset and the connection.
rs.Close
cnn.Close
'clear memory
Set rs = Nothing
Set cnn = Nothing

'Enable the screen.
Application.ScreenUpdating = True

Me.lstDataAccess.RowSource = DataAccess
'Me.lstDataAccess.ColumnCount =     
Sheets("Import").Range("DataAccess").Columns.Count

'error handler
On Error GoTo 0
Exit Sub
errHandler:
'clear memory
Set rs = Nothing
Set cnn = Nothing
MsgBox "Error " & Err.Number & " (" & Err.Description & ") in procedure     
Import_Data"
End Sub

我们一直在绞尽脑汁寻找隐藏在所有细节背后的答案。问题出在您的范围定义上。

即使您使用的是命名范围 - 如果您查看名称管理器中的值,也可以立即发现问题。它们未定义。

同样,如果您 运行 通过使用 VBA 命名范围,您可以立即看到问题。 VBA 没有将 Offset 函数视为返回范围 - 它 returns 是对范围的引用 - 格式实际上是一个 Variant 数组。

在测试函数中,您可以通过向 [DataAccess] 添加一个手表来查看您的范围。它是一个二维 Variant 数组。

所以简单的答案是:

您不能直接将 RowSource 设置为使用偏移函数的命名范围

可能有一些方法可以将变体数组转换为真实范围,但您不能将此类范围名称视为真实范围。

只需尝试使用 Debug.Print Range("DataAccess").Cells.Address 或向 Range("DataAccess") 添加手表,它会给您一个错误,这与引用单元格的其他基本范围名称不同。

您可以通过将范围名称括在方括号中来访问此类范围的值,例如。 [DataAccess]

EDIT - You can fill the ListBox using the OFFSET range by using the AddItem method on the resulting array.

我仍然认为您的 OFFSET 公式存在问题,因为根据我的测试,您最终在数组中只得到 1 个填充列。

但是 - 如果不确认您的列表框属性、查看数据的屏幕截图、查看实际的记录集字段或填充电子表格的代码(而不是 "etc.etc.etc"),则很难测试甚至猜测。

但是此代码将根据使用 OFFSET 函数的范围名称填充您的列表框:

将设置 .Rowsource = DataAccess 的行替换为 FillListBoxFromOffsetRange

将此代码添加到您的用户窗体模块

Private Sub FillListBoxFromOffsetRange()

    Dim arrData     As Variant

    Dim intRow      As Integer
    Dim intCol      As Integer
    Dim strRowData  As String

    With ListBox1
        .Clear              'Make sure the Listbox is empty
        .ColumnCount = 7    'Set number of columns

        ' In order to access Workbook ranges need to use Application Object
        arrData = Application.Range("DataAccess")

        For intRow = LBound(arrData, 1) To UBound(arrData, 1)

            ' Process first column of new row
            intCol = 1
            strRowData = arrData(intRow, intCol)
            .AddItem strRowData ' Add the first Column of the row

            ' Append remaining columns to end of row
            For intCol = LBound(arrData, 2) + 1 To UBound(arrData, 2)
                strRowData = arrData(intRow, intCol)
                ' List rows have zero-based index
                .List(intRow - 1, intCol) = strRowData
            Next intCol

        Next intRow
    End With

End Sub

No Problem - Works as it should - your data - your simulated userform

我所更改的只是完全按照我的建议使用我的上述功能并注释掉您的代码

FillListBoxFromOffsetRange

'Me.lstDataAccess.RowSource = DataAccess
'Me.lstDataAccess.ColumnCount =
'Sheets("Import").Range("DataAccess").Columns.Count

并更改了 With ListBox1 以匹配实际的列表框名称 With lstDataAccess

Results in: