【问题标题】:VBA code to export data from Excel to corresponding SQL field将数据从 Excel 导出到相应 SQL 字段的 VBA 代码
【发布时间】:2019-07-15 14:09:04
【问题描述】:

我有一个 Excel VBA 程序,它可以扫描条形码以打印标签。我要做的是编写一个子程序,当与其余代码一起执行时,它将获取今天的日期并将其插入 SQL 数据库中的特定日期字段中。为了进一步解释 Excel 程序使用与我们数据库中的订单号相对应的订单号。我不是 100% 确定如何进行此操作,如果有帮助可以提供更多信息。

|OrderNo| |TodaysDateFromExcel|   
033707     7/15/2019   

到目前为止我的 VBA 代码

Dim conn As New ADODB.Connection

Dim sDate As Date

sDate= Today()

'Open a connection to SQL Server
        conn.Open "Provider=SQLOLEDB;Data Source=ANF-M2MCLIENT;Initial Catalog=ExcelDemo;Integrated Security=SSPI;"

 conn.Execute "insert into dbo.Customers (TodaysDate) values ('" & sDate & "')"

MsgBox "Today's Date imported."

        conn.Close
        Set conn = Nothing

End sub

【问题讨论】:

  • 查看ADODB
  • 我有 ADOODB 连接设置。我的问题更多集中在从 VBA 代码中获取日期到数据库中相应的 OrderNo 上。 @MathieuGuindon
  • 从您的问题无法判断您配置了 ADODB 连接。请包含相关代码,以便我们知道哪个特定部分存在问题。您是否编写了INSERT SQL 语句?你是在问如何参数化它?就目前而言,很难说...
  • @MathieuGuindon 编辑了更多信息
  • 太棒了!看起来你在正确的轨道上,你在conn.Execute 上遇到错误吗? SQL Server 可以使用getdate() 获取今天的日期,所以我很难了解 Excel 工作表带来了什么,或者为什么 TodaysDate 甚至需要成为一个东西。还是您的意思是插入/更新一个带有来自 Excel 工作表的 OrderDate 值的 Orders 表?

标签: excel vba tsql ssrs-2008-r2


【解决方案1】:

我将假设您有一个标准化的架构 - 像这样:

如果您想INSERT 一个新的Order 记录,您需要知道Id 是针对哪个客户(以及可能为Order 定义的任何其他外键)。

INSERT INTO dbo.Orders (CustomerId, OrderNumber, OrderDate) VALUES (?, ?, ?)

如果您的 Customers 表具有唯一键,例如CustomerNumber,那么你可以从中得到Id外键:

INSERT INTO dbo.Orders (CustomerId, OrderNumber, OrderDate) 
SELECT c.Id, ?, ?
FROM dbo.Customers c
WHERE c.Number = ?

如果您想 UPDATE 现有的 Order 记录,您需要知道要更新的 Id 的顺序 - 假设有一个 自然键OrderNumber 定义为在 @987654337 中唯一@ 记录,您可以在给定 OrderNumber 的情况下更新订单的 OrderDate - SQL 命令字符串如下所示:

UPDATE o SET o.OrderDate = ? FROM dbo.Orders o WHERE o.OrderNumber = ?

这需要两个参数,它在 VBA 中看起来像这样:

Public Sub SaveOrderDate(ByVal orderNumber As String, ByVal orderDate As Date)

    Dim conn As ADODB.Connection
    Set conn = New ADODB.Connection 'note: avoid auto-instantiated "As New" objects
    conn.ConnectionString = "your connection string"
    conn.Open

    Const sql As String = "UPDATE o SET o.OrderDate = ? WHERE OrderNumber = ?"

    Dim cmd As ADODB.Command
    Set cmd.ActiveConnection = conn
    cmd.CommandType = adCmdTypeText
    cmd.CommandText = sql

    cmd.Parameters.Append cmd.CreateParameter(Type:=adDate, Value:=orderDate)
    cmd.Parameters.Append cmd.CreateParameter(Type:=adVarChar, Value:=orderNumber)

    cmd.Execute
    conn.Close

End Sub

然后你会从你的宏中调用它,像这样:

Public Sub Macro1()
    On Error GoTo CleanFail
    SaveOrderDate Sheet1.Cells(1, 1).Value, Sheet1.Cells(1, 2).Value
    MsgBox "Order updated!"
CleanExit:
    Exit Sub
CleanFail:
    MsgBox "Something went wrong, couldn't update the order."
    Debug.Print Err.Description
    Resume CleanExit 'break here to debug (F9 to toggle a breakpoint)
    Resume 'make this the current statement to step through errorring SaveOrderDate call
End Sub

注意:未经测试的空气代码。

【讨论】:

  • 哪里有“?”我会将那些 = 设置为我的 excel 工作表单元格中的参数值吗?
  • ? 是 ADODB 理解的序数参数占位符 - 从不将用户输入连接到 SQL 语句中。 XKCD 有一个classic comic 解释当你这样做时你允许发生的事情。参数在服务器端处理,通过其Parameters 集合传递给命令,如上面的示例代码所示。
  • 使用参数化的 ADODB 命令,您不必担心转义单引号和日期文字:这是服务器需要担心的。当您在客户端执行此任务时,您很容易受到 SQL 注入攻击,并且每当您的输入实际上需要具有合法的单引号字符时,就会出现烦人的错误。 O'Neil 先生和 Null 夫人将非常高兴您正确参数化您的数据访问代码。
  • @David 如果您在服务器上有 SSMS 和足够的权限来创建存储过程,请考虑编写一个接受需要插入/更新的值的参数的过程。这样,您的 VBA 代码除了存储过程名称之外没有任何 SQL 语句,并且您将数据库问题放在数据库方面。
  • 感谢您的帮助。在我继续找出最佳行动方案时,我会考虑所有这些。
【解决方案2】:
Private Sub CommandButton1_Click()

Dim cn_ADO As ADODB.Connection
    Dim cmd_ADO As ADODB.Command
    Set cmd_ADO = New ADODB.Command

    Dim Dbconn As String

    Dim SQLQuery As String
    Dim strWhere As String


    Dim i As Integer
    Dim j As Integer
    Dim jOffset As Integer
    Dim iStartRow As Integer

    'Data Columns
     Dim strOrderNumber As String
     Dim strOrderDate As String

    jOffset = 3
    iStartRow = 2
    i = iStartRow

Dbconn = "Provider=SQLOLEDB;Data Source=ANF-M2MCLIENT;Initial Catalog=ExcelDemo;Integrated Security=SSPI;"


 Set cn_ADO = New ADODB.Connection

 cn_ADO.Open Dbconn

While Cells(i, jOffset).Value <> ""
    strOrderNumber = Cells(i, 0 + jOffset).Value
    strOrderDate = Cells(i, 1 + jOffset).Value

    strWhere = "OrderNumber = " & strOrderNumber

         'Update Statement

         SQLQuery = "update dbo.Orders " & _
                    "set " & _
                    "OrderDate = '" & strOrderDate & "' " & _
                    "where " & strWhere

    cmd_ADO.CommandText = SQLQuery
    cmd_ADO.ActiveConnection = cn_ADO
    cmd_ADO.Execute

    i = i + 1
    Wend


       Set cmd_ADO = Nothing
        Set cn_ADO = Nothing

End Sub

【讨论】:

    猜你喜欢
    • 2020-10-30
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    相关资源
    最近更新 更多