【问题标题】:VBA ADO Update QueryVBA ADO 更新查询
【发布时间】:2017-10-27 09:34:15
【问题描述】:

我正在尝试创建一个链接到“服务器”主 excel 文件的动态客户端 excel 文件。

目标是更新每个文件中的所有数据。基本上,当打开客户端文件时,我会从主文件中获得更新,然后我想根据客户端文件中所做的每一次更改来更新主文件。

我可以很容易地使用 SELECT 获取数据,但更新查询不起作用。 以下是部分代码:

Option Explicit


Private Type FichierSource
    'Objet Fichier source.
    Path As String
    SourceSheet As String
    TargetSheet As String
    Columns As String
    Filter As String
    Name As String
End Type

Sub GetFiles()
    'Take !M sheet to create files and their informations
    Dim Base As FichierSource

    '----------------------------
    'Create files object
    '----------------------------

    'Fichier Source
    Base.Path = "U:\Macros\SQL\Base.xlsx"
    Base.SourceSheet = "DATA"
    Base.TargetSheet = "Base2"
    Base.Columns = "*"
    Base.Filter = ""
    Base.Name = "Base.xlsx"


    '---------------------------
    'Launch queries
    '---------------------------

    With Base
        Call UPDATEQUERY(.Path, .SourceSheet, .TargetSheet, .Columns, .Filter)
    End With

End Sub

Sub UPDATEQUERY(SourcePath As String, SourceSheet As String, TargetSheet As String, _
Columns As String, Filter As String)

    Dim Cn As ADODB.Connection
    Dim QUERY_SQL As String
    Dim CHAINE_HDR As String
    Dim STRCONNECTION As String
    Dim i As Long

    CHAINE_HDR = "[Excel 12.0 Macro;Provider=Microsoft.ACE.OLEDB.12.0;Extended Properties='HDR=YES;'] "


    Set Cn = New ADODB.Connection

    QUERY_SQL = _
    "UPDATE [" & TargetSheet & "$] SET [Col] = (SELECT [Col] FROM [" & SourceSheet & "$] " & _
    "IN '" & SourcePath & "' " & CHAINE_HDR & Filter & ")"



    STRCONNECTION = _
    "Provider=Microsoft.ACE.OLEDB.12.0;" & _
    "Data Source='" & ThisWorkbook.FullName & "';" & _
    "Extended Properties=""Excel 12.0 Macro;"";"

'    QUERY_SQL = _
'    "UPDATE [" & TargetSheet & "$] SET " & _
'    "[Col] = '3'"

    'MsgBox (QUERY_SQL)
    Cn.Open STRCONNECTION

    Cn.Execute (QUERY_SQL)


    '--- Fermeture connexion ---
    Cn.Close
    Set Cn = Nothing

End Sub

当我执行注释的 Sql Query 以便将列 'Col' 更新为 '3 ' 它运行良好,但是当我尝试使用主文件中的 SELECT 进行更新时,出现以下错误

操作必须使用可更新的查询

更新:我认为真正的问题在那里:

我已阅读有关该主题的问题,但任何问题都对我有用。确实如果我在连接字符串中设置“ReadOnly=False”,我会收到以下错误“Pilote ISAM introuvable”(“找不到 ISAM 驱动程序”)。

更新 2:只要连接字符串不正确,就会弹出 ISAM 驱动程序错误。 (例如:坏的 excel 版本号)。 需要 ReadOnly=False(或 Mode='Share Deny Write'),内连接也是如此。

我已经通过在 excel 连接中添加到主文件的连接手动实现了所有这些,所以我知道这应该是可能的。

谢谢

【问题讨论】:

    标签: sql excel vba ado


    【解决方案1】:

    我用updatejoin 做了一个类似的测试,只是为了好玩,而且效果很好。这是我的代码:

    Sub SQLUpdateExample()
        Dim con As ADODB.Connection
        Dim rs As ADODB.Recordset
        Set con = New ADODB.Connection
        con.Open "Driver={Microsoft Excel Driver (*.xls)};" & _
               "DriverId=790;" & _
               "Dbq=" & ThisWorkbook.FullName & ";" & _
               "DefaultDir=" & ThisWorkbook.FullName & ";ReadOnly=False;"
        Set rs = New ADODB.Recordset
        Set rs = con.Execute("UPDATE [Sheet1$]  inner join [Sheet2$] on [Sheet1$].test1 = [Sheet2$].test1  SET [Sheet1$].test3 = [Sheet2$].test3 ")
    
        Set rs = Nothing
        Set con = Nothing
    End Sub
    

    也许您只需要连接字符串中的 ;ReadOnly=False; 吗?
    请注意,尽管我为驱动程序使用了名称,但它在 .XLSM 文件中有效。

    【讨论】:

    • 正如我所说,如果我将 'readonly=false' 添加到连接字符串,则会引发错误。我会尝试加入表格
    • 试试我的连接字符串?
    • 问题是 Sheet2 在另一个工作簿中。因此程序说它没有找到它。如何在更新语法中添加“FROM”?并且“ReadOnly=False”会引发相同的错误消息:“Pilote ISAM introuvable”
    • 由于未知原因(虽然我复制了连接字符串,但我可能拼错了) readonly=False 现在可以工作,我可以从同一个工作簿中的另一个表更新一个表。上面的问题(不同的 wb)仍然相关
    • 做了一些研究。这是由于我使用的提供商。使用您的连接字符串查询有效。我还必须将源文件放入 .xls (Excel 8.0) 格式。否则我会收到 ISAM 错误。我可能会就这一点提出一个新问题。感谢您的帮助!
    【解决方案2】:

    我在您的问题中添加了 SQL 标记,因此也许 SQL 专家可以为您提供更好的帮助。但是,查看 UPDATE 语法,没有 WHERE 子句的 UPDATE 查询将使用相同的值更新表的每一行的指定列。查看查询的 SELECT 部分,它看起来好像会检索多个值。

    如果要使用另一个表中匹配列的值更新表的列,则必须使用 WHERE 子句连接表。我认为以下是一个正确的例子:

    UPDATE table1 SET col = (SELECT col FROM table2 WHERE table1.key=table2.key)
    

    UPDATE t1
    SET t1.Col = t2.Col
    FROM table1 AS t1
        INNER JOIN table2 AS t2
            ON t1.Key = t2.Key
    

    【讨论】:

    • 键必须是列名吗?我试过了,但得到了同样的错误信息。
    • WHERE 子句可以采用 AND 和 OR 表达式,但本质上,是的,它必须是列名,否则您无法加入表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-11
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    相关资源
    最近更新 更多