September 28, 2006 at 2:31 pm
I have been searching this forum and the web to find the answer for this question, but no luck. I am not new the VBA but I am new to using ADO in VBA. Hopefully, someone in this forum has experience with this.
Basically, I want the result set from my stored procedure to be posted in Excel spreadsheet. The result set has more than 8 columns. This stored procedure has two parameter and both are datetime type (proc_Charge @Start, @End). These parameter will get when the input from the Excel spreadsheet after user selection.
Below is my sub procedure in the form:
Sub GetData()
Dim RangeA As Range
Dim RangeB As Range
Set RangeA = Worksheets("CS").Range("B3")
Set RangeB = Worksheets("CS").Range("E3")
Dim cmd As New ADODB.Command
Dim param As New ADODB.Parameter
Dim conn As ADODB.Connection
Dim rst As New ADODB.Recordset
Dim stParam As String
Dim svrConn As String
Dim i As Interger, j As Integer
Const SERVER As String = "MyPC"
svrConn = "Provider=SQLOLEDB;Server=" & SERVER & ";Database=Test;Integrated Security=SSPI"
Set conn = New ADODB.Connection
conn.Open svrConn
With cmd
.ActiveConnection = conn
.CommandType = adCmdStoredProc
.CommandText = "proc_Charge"
End With
stParam = "Start"
Set param = cmd.CreateParameter(stParam, adDBDate, adParamInput)
cmd.Parameters.Append param
cmd.Parameters(stParam).Value = RangeA.Value
stParam = "End"
Set param = cmd.CreateParameter(stParam, adDBDate, adParamInput)
cmd.Parameters.Append param
cmd.Parameters(stParam).Value = RangeB.Value
Set rst = cmd.Execute
rst.Open cmd
If rst.EOF <> True Then
rst.MoveFirst
j=5
Do Until rst.EOF
For i = 0 To rst.Fields.Count - 1
ActiveSheet.Cells(j, i + 1).Value = rst.Fields(i).Value
Next
j = j + 1
rst.MoveNext
Loop
End If
rst.Close
conn.Close
Set cmd = Nothing
Set conn = Nothing
Set rst = Nothing
End Sub
This procedure always stop with run-time error at "If rst.EOF <> True Then" statement saying the operation is not allowed when the object is closed. I don't see how the object is close.
Any help will be greatly appreciated. If there is anything wrong with the sub procedure, feel free to correct me too. Thank you so much.
September 29, 2006 at 7:38 am
KC
The first thing to check for is to make sure that in your stored procedure you place at the top (after your parameters) SET NOCOUNT ON. That may be the reason why the proc is not returning a recordset, even though it may work perfectly well in Query Analyser. Give that a shot and let's see what happens.
cje
September 29, 2006 at 7:48 am
Thank you for the reply, cje.
On my stored procedure, I do have the SET NOCOUNT at the top. Like you said, it ran perfectly find in QA. Below is how my stored proc looks like:
CREATE PROCEDURE dbo.proc_GetData
(
@Start datetime,
@End datetime
)
AS
BEGIN
SET NOCOUNT ON
...
...
END
SET NOCOUNT OFF
END
GO
Thank you again.
September 29, 2006 at 8:43 am
>>I don't see how the object is close.
The problem may be that you did this, paradoxical as it may seem:
Set rst = cmd.Execute rst.Open cmd ' <-- this line here may be the problem
After the Execute, it's like you're telling the rst to get ready to do something else.
Try code that looks like this, without the .Open:
Set rst = cmd.Execute If Not rst.BOF() Then ...
If that doesn't work, take your parameters-arranging and command-handling out of the question, like this (I'm not sure I have your params right, I'm just looking at your code quickly, but it will be something similar):
Set rst = .Execute("proc_Charge @Start='" & _ Trim(CSTR(RangeB.Value)) & "'")If Not rst.BOF() Then ...
Once you've verified what should be happening, using the simpler syntax above but still using the sproc, you can go back to using the command object if you like.
Regards,
>L<
September 29, 2006 at 9:37 am
I had to take out the following line to get it to work
rst.Open cmd
September 29, 2006 at 1:31 pm
I have tried the above suggestion suggestions, none works for me.
Below is my new sub procedure code:
Sub GetData()
Dim RangeA As Range
Dim RangeB As Range
Set RangeA = Worksheets("CS").Range("B3")
Set RangeB = Worksheets("CS").Range("E3")
Dim cmd As New ADODB.Command
Dim conn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim param1 As ADODB.Parameter, param2 As ADODB.Parameter
Dim stParam As String
Dim svrConn As String
Dim i As Interger, j As Integer
Const SERVER As String = "MyPC"
conn.Provider = "SQLOLEDB"
svrConn = "Server=" & SERVER & ";Database=Test;Integrated Security=SSPI"
conn.Open svrConn
cmd.ActiveConnection = conn
With cmd
.CommandType = adCmdStoredProc
.CommandText = "proc_Charge"
End With
Set param1 = cmd.CreateParameter("Start", adDBDate, adParamInput)
cmd.Parameters.Append param1
param1.Value = Trim(CStr(RangeA.Value))
Set param2 = cmd.CreateParameter(stParam, adDBDate, adParamInput)
cmd.Parameters.Append param2
param2.Value = Trim(CStr(RangeB.Value))
Set rst = cmd.Execute
j=5
While Not rst.EOF
For i = 0 To rst.Fields.Count - 1
ActiveSheet.Cells(j, i + 1).Value = rst.Fields(i).Value
Next
j = j + 1
rst.MoveNext
Wend
rst.Close
conn.Close
Set cmd = Nothing
Set conn = Nothing
Set rst = Nothing
End Sub
The procedure still crashed @ the "While Not rst.EOF" with error message "Operation is not allowed when the object is closed."
Any idea? I used the immediate watch window to troubleshoot the variable, the parameters returns the correct values. Thank you once again.
September 29, 2006 at 1:39 pm
Did you try what I suggested, about removing the command object from the picture, while still executing your stored procedure?
Note: this is different from confirming that the parameters return the correct values.
>L<
September 29, 2006 at 1:44 pm
on your parameters, you're using Cstr() - try Cdate() function instead, since your proc is looking for DateTime parameters
September 29, 2006 at 2:01 pm
Wow!! just noticed that you append the parameters to the collection before you set the values for them - switch the 2 lines where you append and set the values.
September 29, 2006 at 2:48 pm
Yes, I did try both of your suggestion, Lisa.
1) Try this way and it made no different, gave me the same error code.
Set rst = cmd.Execute
If Not rst.BOF() Then ...
2) Try this way and recevied a different error message. It complained the stored procedure expecting a @Start parameter.
Set rst = .Execute("proc_Charge @Start='" & _
Trim(CSTR(RangeB.Value)) & "'")
If Not rst.BOF() Then ...
As for your suggestion, cje. I did change the function to use CDate() and made no different. Still said the object was closed. Then I moved the statement for setting the value for the parameter before the append statement, it still gave me the same error. Now, it is like this:
Set param1 = cmd.CreateParameter("Start", adDBDate, adParamInput)
param1.Value = Trim(CDate(RangeA.Value))
cmd.Parameters.Append.param1
Any more suggestion?
September 29, 2006 at 2:57 pm
no, no
set param1 = cmd.createparameter("@start", adDBDate, adParamInput, ,CDate(RangeA.value))
cmd.Parameters.Append param1 --(no period after append)
Do this for both parameters
September 29, 2006 at 3:06 pm
>>It complained the stored procedure expecting a @Start parameter.
That's funny, I do it this way and it works fine. Are you sure you used the connection.Execute() method?
Remember, we're not talking to the command object here, and we're definitely not talking to a stored procedure-configured instance of a command object. We're just executing a line of SQL code against a connection. That line of code just happens to be executing a stored procedure, including its arguments, just as you might do it in the query analyzer.
If this does not turn out to be the problem... then what version of MDAC components is on the computer you're using? Here is some typical mdac-version checking code. (If this sub crashes for you, of course, you *know* you need to update MDAC <g>
Function CheckMDACVer() Dim MDACVer As MDACVer.Version Set MDACVer = CreateObject("MDACVer.Version") CheckMDACVer = (MDACVer.Major = 2 And _ MDACVer.Minor >= 8) Or _ MDACVer.Major > 3 If (Not CheckMDACVer) Then MsgBox "This application requires an updated version " _ & vbCr & _ "of Microsoft MDAC components to function." & vbCr & vbCr & _ "Please contact the developer (Lisa).", _ vbCritical, "Update your computer!" End If Set MDACVer = Nothing End Function
>L<
September 29, 2006 at 3:11 pm
sorry, cje. I made the change and it still crashes. Same error, "Operation is not allowed when the object is closed".
set param1 = cmd.createparameter("@Start", adDBDate, adParamInput, ,CDate(RangeA.value))
cmd.Parameters.Append param1
set param2 = cmd.createparameter("@Start", adDBDate, adParamInput, ,CDate(RangeA.value))
cmd.Parameters.Append param2
September 29, 2006 at 3:26 pm
Lisa, I used the MS Component Checker to check my MDAC version. It reports that I have MDAC 2.8 SP1 on my PC.
September 29, 2006 at 3:32 pm
OK, KC, what about the other question I asked you in that message? Are you sure you executed the command against the right object? I can't understand how you could get a complaint about a stored procedure when, as far as the MDAC component knows, it's not executing a stored procedure.
Maybe you should post the entire revision that (attempt to) follow my the suggestion to remove the command object from your code?
>L<
Viewing 15 posts - 1 through 15 (of 47 total)
You must be logged in to reply to this topic. Login to reply