Vba 使用大量参数调用存储过程

Vba 使用大量参数调用存储过程,vba,vb6,adodb,Vba,Vb6,Adodb,嘿,我在这段代码中遇到了这个错误,我不知道为什么。这将是一个很大的帮助,因为我正在努力使我的代码更容易阅读 Public Function SaveProperty() As Boolean '** Save Current Personal Data Record ' Error Checking On Error GoTo Err_SaveProperty ' Dimension Local Variables Dim uRecSnap As ADODB.Recordset Dim uP

嘿,我在这段代码中遇到了这个错误,我不知道为什么。这将是一个很大的帮助,因为我正在努力使我的代码更容易阅读

Public Function SaveProperty() As Boolean
'** Save Current Personal Data Record

' Error Checking
On Error GoTo Err_SaveProperty

' Dimension Local Variables
Dim uRecSnap As ADODB.Recordset
Dim uPar As ADODB.Parameter

' Check For Open Connection
If uDBase Is Nothing Then
    OpenConnection()
    bConnection = True
End If

' Run Stored Procedure - Save Property Record
uCommand = New ADODB.Command
With uCommand
    .ActiveConnection = uDBase
    .CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
    .CommandTimeout = 0
    .Parameters.Append.CreateParameter("@PropertyID", ADODB.DataTypeEnum.adInteger, ADODB.ParameterDirectionEnum.adParamInput, 50, Val(lblPropertyIDValue.Text))
    .Parameters.Append.CreateParameter("@PropertyManager", ADODB.DataTypeEnum.adLongVarChar, ADODB.ParameterDirectionEnum.adParamInput, 60, cmbPropertyManager.Text)
    .Parameters.Append.CreateParameter("@AddressLine1", ADODB.DataTypeEnum.adLongVarChar, ADODB.ParameterDirectionEnum.adParamInput, 30, txtAddress1.Text)
    .Parameters.Append.CreateParameter("@AddressLine2", ADODB.DataTypeEnum.adLongVarChar, ADODB.ParameterDirectionEnum.adParamInput, 30, txtAddress2.Text
'...ETC

.CommandText = "PropertyMaster_SaveRecord"

    .Execute()
End With

' Close Connection
uRecSnap = Nothing
uCommand = Nothing
If bConnection Then CloseConnection()
SaveProperty = True

Err_SaveProperty:
If Err.Number <> 0 Then
    sErrDescription = Err.Description
    WriteAuditLogRecord("clsProperty", "SaveProperty", "Error", sErrDescription)
    SaveProperty = False
End If

欢迎来到精彩的
With
声明的注意事项

正如@RubberDuck所暗示的,您的问题在于:

.Parameters.Append.CreateParameter(...)
应该是:

.Parameters.Append .CreateParameter(...)
如果没有
With
块,您将拥有以下功能:

uCommand.Parameters.Append uCommand.CreateParameter(...)

Append
CreateParameter
都是
uCommand
对象的成员,
With
块正在使用该对象。

如果您确实想让代码更易于阅读,只需执行以下操作:

' Run Stored Procedure - Save Property Record
Set uCommand = New ADODB.Command  'Note use of Set keyword
With uCommand
    .ActiveConnection = uDBase
    .CommandType = adCmdStoredProc 'Don't need the entire object hierarchy here
    .CommandTimeout = 0
    .CommandText = "PropertyMaster_SaveRecord"
    .Parameters.Refresh
    .Parameters(1) = cmbPropertyManager.Text 'Collections are usually 1-based in VB6
    .Parameters(2) = txtAddress1.Text
    .Parameters(3) = txtAddress2.Text
    '...ETC
    .Execute()
End With
这确实需要额外的往返来查找参数。但是,如果您能负担得起性能开销,这是一种更简单的方法。此外,它还减少了潜在的维护开销,因为它与存储过程的参数列表耦合得不够紧密;例如,您可以重命名存储过程中的参数,而不必担心会破坏代码

还请注意,在使用枚举时,不需要详细说明枚举的整个对象层次结构;事实上,我以前从未见过这样做。因此,不这样做也会使代码更易于阅读

接下来,在实例化新对象时使用Set关键字

最后,将其替换为:

If uDBase Is Nothing Then
    OpenConnection()
    bConnection = True
End If
为此:

If uDBase.State = adStateClosed Then
    OpenConnection()
    bConnection = True '?? Probably don't need this, see below
End If
您不想依赖于检查对象是否为空的原因是您可能会在代码中的其他地方关闭连接,而忘记将uDBase设置为空。这会产生一个很难找到的bug。此外,如果使用bConnection变量的唯一原因是因为您使用它来跟踪连接是否打开,那么您可以安全地将其删除,只使用State属性

进一步的改进是将OpenConnection例程更改为GetConnection例程,并在其中封装所有打开连接的检查等。像这样:

Public Function GetConnection() As ADODB.Connection
    Static myConn As ADODB.Connection
    If myConn.State = adStateClosed Then
        Set myConn = New ADODB.Connection
        myConn.Open "myConnectionString"
    End If
    GetConnection = myConn
End Function

这假设您在整个应用程序中使用一个连接,并且在应用程序运行时它保持打开状态。uDBase变量的范围暗示了这一点。当然,有更经济的方法来管理连接,您可能需要根据您处理的流量查看这些方法。

您的错误是哪一行?我只是复制/粘贴了。“在
.Append
.CreateParameter.
之间添加一个空格。仔细比较您所写的内容与我在回答其他问题时给出的内容。“您看到的错误是什么?”?
Public Function GetConnection() As ADODB.Connection
    Static myConn As ADODB.Connection
    If myConn.State = adStateClosed Then
        Set myConn = New ADODB.Connection
        myConn.Open "myConnectionString"
    End If
    GetConnection = myConn
End Function