如何使用vba代码从excel数据更新Sql server表?

如何使用vba代码从excel数据更新Sql server表?,sql,vba,excel,Sql,Vba,Excel,我有一个表,我正在尝试使用vba从电子表格更新sql表月份列,但它似乎不起作用。我编辑了昨天的vba代码,得到错误“对象关闭时不允许操作”。我是vba编程新手,因此非常感谢您的帮助 CREATE TABLE [dbo].[Actual_FTE]( [EmpID] [nvarchar](15) NOT NULL, [EName] [nvarchar](50) NULL, [CCNum] [nvarchar](10) NOT NULL, [CCName] [nvarchar](50) NULL, [

我有一个表,我正在尝试使用vba从电子表格更新sql表月份列,但它似乎不起作用。我编辑了昨天的vba代码,得到错误“对象关闭时不允许操作”。我是vba编程新手,因此非常感谢您的帮助

CREATE TABLE [dbo].[Actual_FTE](
[EmpID] [nvarchar](15) NOT NULL,
[EName] [nvarchar](50) NULL,
[CCNum] [nvarchar](10) NOT NULL,
[CCName] [nvarchar](50) NULL,
[ProgramNum] [nvarchar](10) NULL,
[ProgramName] [nvarchar](50) NULL,
[ResTypeNum] [nvarchar](10) NULL,
[ResName] [nvarchar](50) NULL,
[January] [nvarchar](50) NULL,
[February] [nvarchar](50) NULL,
[March] [nvarchar](50) NULL,
[April] [nvarchar](50) NULL,
[May] [nvarchar](50) NULL,
[June] [nvarchar](50) NULL,
[July] [nvarchar](50) NULL,
[August] [nvarchar](50) NULL,
[September] [nvarchar](50) NULL,
[October] [nvarchar](50) NULL,
[November] [nvarchar](50) NULL,
[December] [nvarchar](50) NULL,
[Total_Year] [nvarchar](50) NULL,
[Year] [nvarchar](6) NULL,
[Scenario] [nvarchar](10) NULL
)

vba代码是:

Public Sub UpdateToDatabase()

 Dim sBackupUpdQry As String
Dim sBackupInsQry As String

Dim sUpdQry As String
Dim sInsQry As String
Dim sExistQry As String
Dim sWhere As String

Dim iRows As Integer
Dim iCols As Integer

On Error GoTo ErrHandler




'Find last row and last column
Dim lLastRow As Long
Dim lLastCol As Integer
lLastRow = Cells.Find("*", Range("A4"), xlFormulas, , xlByRows, xlPrevious).Row ' Find the last row with data
lLastCol = Cells.Find("*", Range("A4"), xlFormulas, , xlByColumns, xlPrevious).Column ' Find the last column with data


Dim qryUpdateArray(2000) As String
Dim qryInsertArray(2000) As String
Dim qryExistArray(2000) As String
Dim iRecCount As Integer
Dim sCellVal As String
Dim sColName As String


With Sheets("Main")

    sBackupUpdQry = "UPDATE Actual_FTE SET " ' predefined value of variable to concatenate for further at the time of updation
    sBackupInsQry = "INSERT INTO Actual_FTE ("
    sWhere = ""

    'starting from row3, which is the header/column-name row
    'prepare the insert/update queries
    iRows = 3
    iRecCount = 1
    For iCols = 1 To lLastCol
        sColName = Cells(iRows, iCols)


        If (sColName = "") Then
            MsgBox ("Empty Column Name")
            Exit Sub
        End If

        If (iCols = 1) Then
            sBackupInsQry = sBackupInsQry + sColName
        Else
            sBackupInsQry = sBackupInsQry + ("," + sColName)
        End If
    Next iCols
    sBackupInsQry = sBackupInsQry + ")VALUES("


    'loop through each column to add the insert/update data
    For iRecCount = 1 To lLastRow - 3
        iRows = iRows + 1
        sUpdQry = sBackupUpdQry
        sInsQry = sBackupInsQry

        For iCols = 1 To lLastCol
            sColName = CStr(Cells(3, iCols))



            sCellVal = CStr(Cells(iRows, iCols))
            If (InStr(1, sCellVal, "'")) Then
                sCellVal = Replace(sCellVal, "'", "''")
            End If

            If (iCols = 1) Then
                sUpdQry = sUpdQry + (sColName + "='" + sCellVal + "'")
                sInsQry = sInsQry + ("'" + sCellVal + "'")

               Else
                 sUpdQry = sUpdQry + ("," + sColName + "='" + sCellVal + "'")
                 sInsQry = sInsQry + (",'" + sCellVal + "'")

            End If


        Next iCols

        sInsQry = sInsQry + ")"
        sUpdQry = sUpdQry + sWhere

        'save all queries into string array, maximum 1000
        qryUpdateArray(iRecCount) = sUpdQry
        qryInsertArray(iRecCount) = sInsQry
        qryExistArray(iRecCount) = sExistQry

    Next iRecCount


End With

Call DBConnection.OpenDBConnection

Dim rsMY_Resources As ADODB.Recordset
Set rsMY_Resources = New ADODB.Recordset


Dim cntUpd As Integer
Dim cntIns As Integer
cntUpd = 0
cntIns = 0

For iRecCount = 1 To lLastRow - 3
    'check if the asset number exists.
    'MsgBox qryExistArray(iRecCount)
    Set rsMY_Resources = oConn.Execute(qryExistArray(iRecCount))

    'if exists, update the record; if not, insert a new record
    If (rsMY_Resources.Fields(0).Value = 0) Then
        'MsgBox "Insert"
        'MsgBox qryInsertArray(iRecCount)
        oConn.Execute qryInsertArray(iRecCount)
        cntIns = cntIns + 1
    Else
        'MsgBox "Update"
        'MsgBox qryUpdateArray(iRecCount)
        oConn.Execute qryUpdateArray(iRecCount)
        cntUpd = cntUpd + 1
    End If
Next iRecCount

'Clean up
rsMY_Resources.Close:
Set rsMY_Resources = Nothing

Call DBConnection.CloseDBConnection
MsgBox ("Actual_FTE table has been updated: " + CStr(cntUpd) + " records have been updated; " + CStr(cntIns) + " new records have been inserted")


Exit Sub
错误处理程序: MsgBox(错误)

端接头

谢谢,
H

您在
where
子句中用尾随空格填充最后4个变量,这很可能就是为什么只运行“insert”查询的原因(因为您的where从未得到任何命中)


您在
where
子句中用尾随空格填充最后4个变量,这很可能就是为什么只运行“insert”查询的原因(因为您的where从未得到任何命中)


你的分支代码是错误的。尝试使用一个数组

我建议换衣服

    'save all queries into string array, maximum 1000
    qryUpdateArray(iRecCount) = sUpdQry
    qryInsertArray(iRecCount) = sInsQry
    qryExistArray(iRecCount) = sExistQry


然后稍后从queriesArray运行sql。

您的分支代码是错误的。尝试使用一个数组

我建议换衣服

    'save all queries into string array, maximum 1000
    qryUpdateArray(iRecCount) = sUpdQry
    qryInsertArray(iRecCount) = sInsQry
    qryExistArray(iRecCount) = sExistQry



然后稍后从queriesArray运行sql。

请添加正在执行的实际更新sql的示例。运行该命令并显示实际的SQL错误。查询运行正常,没有错误,但没有更新行,而是插入了新行。如果要更新行,为什么代码中有insert语句?请添加正在执行的实际更新SQL示例。运行该命令并显示实际的SQL错误。查询运行正常,没有错误,但没有更新行,而是插入了新行。如果要更新行,为什么代码中有insert语句?即使删除了这些空格,它仍然不起作用!我的表中只有5行要更新。但每次都会显示“0条记录更新,5条记录插入”Debug.Print一个
qryExistArray
值,该值在表中应该有一个匹配的记录:运行该SQL时是否得到非零计数?@Hema为什么不在执行它之前
Debug.Print sUpdQry
?可能是,如果你发布它,调试会更简单。即使删除了这些空间,它仍然无法工作!我的表中只有5行要更新。但每次都会显示“0条记录更新,5条记录插入”Debug.Print一个
qryExistArray
值,该值在表中应该有一个匹配的记录:运行该SQL时是否得到非零计数?@Hema为什么不在执行它之前
Debug.Print sUpdQry
?可能是,如果您发布它,调试将更加复杂。代码过于复杂,但我不确定它是否错误。发生插入的原因是因为稍后的分支逻辑错误。OP也可以分支到他们发现记录是否存在的地方。我打赌“存在”查询是问题所在(在这种情况下,运行该查询的时间无关紧要),让我们看看!这也是我的赌注。。。更新不运行的原因是因为分支逻辑错误。代码过于复杂,但我不确定它是否错误。发生插入的原因是因为后面的分支逻辑错误。OP也可以分支到他们发现记录是否存在的地方。我打赌“存在”查询是问题所在(在这种情况下,运行该查询的时间无关紧要),让我们看看!这也是我的赌注。。。更新无法运行的原因是分支逻辑错误。
    'save all queries into string array, maximum 1000
    if sExistQry = '1' then
        queriesArray(iRecCount) = sUpdQry
    else
        queriesArray(iRecCount) = sInsQry
    end if