我一直在讨论这个问题,我想知道是否有解决方案!
所以我有一个名为R1的表,在Access中有两个列:[Department]和[DepartmentQV],[Department]列有一些带有值的字段,但[DepartmentQV]列是空白的
我还在Excel中有一个电子表格,它还有[Department]列和[DepartmentQV]列。 [Department]列与Access中的列相同,但[DepartmentQV]列具有值。
我想要做的就是使用ADODB和SQL将[DepartmentQV]值从Excel工作表拉入到[Department]值匹配的Access数据库中。
不幸的是,这根本不起作用,我一直得到同样的错误"没有给出一个或多个所需参数的值"我完全不解。任何帮助,将不胜感激!感谢您抽出宝贵时间阅读本文!
最佳, 库尔特
到目前为止,这是我的代码!
lastRow = ActiveWorkbook.ActiveSheet.Range("B" & ActiveWorkbook.ActiveSheet.Rows.Count).End(xlUp).Row
Set cn = CreateObject("ADODB.Connection")
dbPath = glob_sdbPath
dbWb = Application.ActiveWorkbook.FullName
dbWs = ActiveWorkbook.ActiveSheet.Name
scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
dsh = "[" & Application.ActiveSheet.Name & "$B2:C" & lastRow & "]"
cn.Open scn
sSql = "INSERT INTO R1([Department_QV])"
sSql = sSql & " SELECT [Spoilage] FROM [Excel 12.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh & " WHERE " & dsh & ".[Department] = R1.[Department]"
cn.Execute sSql
答案 0 :(得分:1)
此处的问题是使用ADO在Access和Excel之间进行更新。当我尝试针对Access表INNER JOIN派生的Excel表并执行更新时,我收到错误:
"Run-time error '-2147467259 (80004005)':
You cannot edit this field because it resides in a linked Excel spreadsheet. The ability to edit data in a linked Excel spreadsheet has been disabled in this Access Release."
没关系Access表没有链接到Excel,我找不到解决方案。我决定将Excel数据推送到Access中的临时表,并针对R1和临时表运行更新。另一种执行更新的方法是打开两个记录集,一个是Excel表,另一个是Access表,另一个是针对另一个进行搜索并更新,但我选择了它。
(我引用了Microsoft ActiveX Data Objects 2.8 Library和Microsoft ADOX Ext.2.8 for DDL And Security,所以我有智能感知。你可以根据需要实例化对象。):
Public Sub ExcelToAcessUpdate()
On Error GoTo ErrorHandler
Dim cn As New ADODB.Connection
Dim rstTables As New ADODB.Recordset
Dim cat As New ADOX.Catalog
Dim dbWb As String
Dim dbWs As String
Dim dsh As Variant
Dim lastRow As Integer
Dim dbPath As String
Dim scn As String
Dim sTempTable As String
Dim sSql As String
dbWb = Application.ActiveWorkbook.FullName
dbWs = ActiveWorkbook.ActiveSheet.Name
dsh = "[" & Application.ActiveSheet.Name & "$B2:C" & lastRow & "]"
lastRow = ActiveWorkbook.ActiveSheet.Range("B" & ActiveWorkbook.ActiveSheet.Rows.Count).End(xlUp).Row
dbPath = glob_sdbPath
scn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
'This is the name of the temp table in Access
'we will use to hold our Excel data.
sTempTable = "tblMyExcelTemp"
cn.Open scn
'Make the ADO connection get a recordset of tables in database.
Set rstTables = cn.OpenSchema(adSchemaTables)
'If temp table we want to use already exists in db, delete it.
With rstTables
Do Until .EOF
If .Fields("TABLE_TYPE") = "TABLE" And _
.Fields("TABLE_NAME") = sTempTable Then
Set cat.ActiveConnection = cn
cat.Tables.Delete sTempTable
Exit Do
End If
.MoveNext
Loop
End With
'Get all our Excel data and push it into temp table.
sSql = "SELECT [Department], [Spoilage] INTO " & sTempTable & " " & _
"FROM [Excel 12.0;HDR=YES;DATABASE=" & dbWb & "]." & dsh
cn.Execute sSql
'Update R1 using inner join against Excel Temp table.
sSql = "UPDATE R1 INNER JOIN " & sTempTable & " e ON R1.[Department] = e.[Department] " & _
" SET Department_QV = e.[Spoilage]"
cn.Execute sSql
ExitMe:
If cn Is Nothing = False Then
If cn.State <> adStateClosed Then
cn.Close
End If
End If
Set cat = Nothing
Set rstTables = Nothing
Set cn = Nothing
Exit Sub
ErrorHandler:
'Lazy error handling, need to go through cn.Errors collection, actually.
MsgBox Err.Number & ": " & Err.Description
GoTo ExitMe
End Sub
我不是临时表解决方案的忠实粉丝,但是它有效,如果你需要做很多这样的事情,它可以成为你的范例。希望它对你有用。使用记录集的基于游标的解决方案效率太低,但我想也可以这样做。