Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 Other Forums
 MS Access
 Runtime error - 3014 "can't open more tables"

Author  Topic 

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-23 : 06:42:49
Hey all,

I am receiving this error when i'm trying to run a routine that I didn't create. I know this should be a sp on my sql box but I haven't got the resource to do it right now.

Basically I know that access is struggling not creating tables, but table references, I have tried all the ms knowledge base and newsgroups and I don't seem to be able to find any adequate reference material to try solve this. I have been through the code trying to make sure that all my recordsets and querydef objects are being explicitly closed, yet I cannot seem to past 1103 records of the 3000 I need to process. It stops consistently at the same point. I am using jet4.0 vanilla that comes with xp sp2;

here is my entire forms code, yes, there is DAO in there, im in the process of re-writing the whole system;


Option Compare Database
Option Explicit

Dim lUpdateID As Long

Private Sub CloseButton_Click()
DoCmd.Close
End Sub

Private Sub OKButton_Click()
Dim rst As DAO.Recordset
Dim rstP As DAO.Recordset
Dim strSQL As String
Dim strAssembly As String
Dim strComponent As String
Dim sngQty As Single
Dim SubAssemblyCost As Single
Dim I As Integer
Dim iRecords As Long
Dim dblPerCent As Double

Dim strNowTime As String
Dim dtStartTime As Date
Dim Elapsed As String
Dim EstFinish As String

DoCmd.Hourglass True
' lUpdateID = 111

strSQL = "SELECT [Product Code] FROM Product " & _
"WHERE Assembly = True"
Set rstP = CurrentDb.OpenRecordset((strSQL), dbOpenDynaset, [dbSeeChanges])
rstP.MoveLast
iRecords = rstP.RecordCount
rstP.MoveFirst

dtStartTime = Time
strNowTime = CStr(Time)
EstFinish = CStr(dtStartTime + 30)

Me!StartLabel.Caption = strNowTime

For I = 1 To iRecords
strAssembly = rstP![Product Code]
Me!ProdLabel.Caption = strAssembly
Me!RecordLabel.Caption = I & " of " & iRecords
dblPerCent = CDbl(I * (100 / iRecords))
Me!PercentLabel.Caption = Format(dblPerCent, "##") & "%"
Me.Repaint
If I Mod 10 = 0 Then
DoEvents
End If
strSQL = "SELECT * FROM BOMData " & _
"WHERE Parent = """ & strAssembly & """"
Set rst = CurrentDb.OpenRecordset((strSQL), dbOpenDynaset, [dbSeeChanges])
If rst.EOF = True Then
rst.Close
Else
SubAssemblyCost = 0
Do While rst.EOF = False
sngQty = GetSubCost(rst!Component)
If sngQty = 999999 Then
sngQty = GetProductCost(rst!Component)
If rst!Assembly = True Then
rst.Edit
rst!Assembly = False
rst.Update
End If
Else
UpdateProductCost rst!Component, sngQty
If rst!Assembly = False Then
rst.Edit
rst!Assembly = True
rst.Update
End If
End If
SubAssemblyCost = SubAssemblyCost + sngQty * rst!Qty
rst.MoveNext
Loop
rst.Close
UpdateProductCost strAssembly, SubAssemblyCost
End If

rstP.MoveNext
Elapsed = Time - dtStartTime
EstFinish = iRecords * Elapsed / I
Me!FinishLabel.Caption = CStr(EstFinish + dtStartTime)
Next I
rstP.Close
DoCmd.Hourglass False
MsgBox "Finished at " & Time
DoCmd.Close
End Sub

Function GetSubCost(strCode)
Dim rst As DAO.Recordset
Dim strSQL As String
Dim sngQty As Single
Dim SubAssemblyCost As Single

' strSQL = "SELECT * FROM BOMData " & _
"WHERE Parent = """ & strCode & """"
strSQL = "SELECT Product.[Product Code], BOMData.Component, BOMData.Qty, " & _
"BOMData.Assembly " & _
"FROM Product INNER JOIN BOMData ON Product.[Product Code] = BOMData.Parent " & _
"WHERE (((Product.[Product Code])=""" & strCode & """) AND ((Product.SparesOnly)=False));"
Set rst = CurrentDb.OpenRecordset((strSQL), dbOpenDynaset, [dbSeeChanges])
If rst.EOF = True Then
rst.Close
GetSubCost = 999999
Exit Function
End If
SubAssemblyCost = 0
Do While rst.EOF = False
sngQty = GetSubCost(rst!Component)
If sngQty = 999999 Then
sngQty = GetProductCost(rst!Component)
If rst!Assembly = True Then
rst.Edit
rst!Assembly = False
rst.Update
End If
Else
UpdateProductCost rst!Component, sngQty
If rst!Assembly = False Then
rst.Edit
rst!Assembly = True
rst.Update
End If
End If
SubAssemblyCost = SubAssemblyCost + sngQty * rst!Qty
rst.MoveNext
Loop

rst.Close
GetSubCost = SubAssemblyCost
End Function

Function GetProductCost(strCode)
Dim rstP As DAO.Recordset
Dim strSQL As String

strSQL = "SELECT Cost FROM Product " & _
"WHERE [Product Code] = """ & strCode & """"
Set rstP = CurrentDb.OpenRecordset((strSQL), dbOpenDynaset, [dbSeeChanges])
If rstP.EOF = False Then GetProductCost = Nz(rstP!Cost)
rstP.Close
End Function

Function UpdateProductCost(strCode As String, cCost As Single)
Dim strSQL As String
Dim qdfChange As QueryDef

strSQL = "UPDATE Product SET Cost = " & cCost & _
" WHERE [SparesOnly] = False AND [Product Code] = """ & strCode & """"

Set qdfChange = CurrentDb.CreateQueryDef("", strSQL)
qdfChange.Execute
'barry - closing objects
qdfChange.Close
Set qdfChange = Nothing

End Function


Thanks for your time.
Pace

"Impossible is Nothing"

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-23 : 09:13:31
I should add, it runs 1103 times before I get this error.

"Impossible is Nothing"
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-10-23 : 10:02:15
You run this 1103 times?
Set qdfChange = CurrentDb.CreateQueryDef("", strSQL)

I think that should be an EXECUTE instead for that UPDATE, right?



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-23 : 10:21:18
Hey Peso,

Thanks for the reply. Yes it loops 1103 times before it throws the error.

Im not sure what you mean when you say "I think that should be an EXECUTE instead for that UPDATE, right?"

Sorry :S

"Impossible is Nothing"
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-10-23 : 10:24:05
The function "UpdateProductCost" creates a new query 11903 times with the Set qdfChange = CurrentDb.CreateQueryDef("", strSQL) statement.

I think it should read
Set qdfChange = CurrentDb.Execute(strSQL)

or similar.




E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-23 : 11:14:20
Thanks Peso,

Im now running it again but im using an ADO command;

[Code]
Function UpdateProductCost(strCode As String, cCost As Single)
Dim strSQL As String
Dim qdfChange As QueryDef
Dim cmd As ADODB.Command

Set cmd = New ADODB.Command

strSQL = "UPDATE Product SET Cost = " & cCost & _
" WHERE [SparesOnly] = False AND [Product Code] = '" & strCode & "'"

cmd.ActiveConnection = cnnSQL
cmd.CommandType = adCmdText
cmd.CommandText = strSQL

cmd.Execute(strSQL)

Set cmd = Nothing

'Set qdfChange = CurrentDb.CreateQueryDef("", strSQL)
'qdfChange.Execute
'barry - closing objects
'qdfChange.Close
'Set qdfChange = Nothing

End Function
[/code]



"Impossible is Nothing"
Go to Top of Page

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-23 : 11:36:14
hmmm ,

seems to be bombing in GetSubCost

strSQL = "SELECT Product.[Product Code], BOMData.Component, BOMData.Qty, " & _
"BOMData.Assembly " & _
"FROM Product INNER JOIN BOMData ON Product.[Product Code] = BOMData.Parent " & _
"WHERE (((Product.[Product Code])=""" & strCode & """) AND ((Product.SparesOnly)=False));"
CRASH AFTER 1103 = > Set rst = CurrentDb.OpenRecordset((strSQL), dbOpenDynaset, [dbSeeChanges])

"Impossible is Nothing"
Go to Top of Page

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-24 : 03:29:27
Im now retrying but explicitly setting my recordset objects to nothing as well as closing them.

"Impossible is Nothing"
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-10-24 : 03:49:32
That can be the cause.
Report back with your findings.



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-24 : 06:22:59
Im still getting the error.

I have even tried re-writing the last bit to a SP hoping that will free some resources up but I still get the same problem. The most confusing part is I am closing my recordset objects, query def's etc. The only way I can see getting round this at the min is to write a cursor :S

"Impossible is Nothing"
Go to Top of Page

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-25 : 04:04:09
Right I have it...

I was burning the midnight oil last night to get the whole thing re-written into sp's.

Upon running these sp's I was getting a nesting error... SQL Server Nesting Limit Exceeded. Maximum Level 32.

So I have to chuck in some PRINT's on the components to see just what was going on in there. Basically I have found this product, now the routine splits its base parts out and calculates the cost to in turn update the product. The guys on the product and BOM team only had a Product ABC which was made of of D, E & F and ABC. So it was finding itself, looping through to work out its cost, again finding itself, looping through indefinitely.

Now I did get the routine down from 40 mins from access to a niche' 1.17 in sql server, I was just wondering was the vba really broken? Perhaps it would have handled everything and the reason it was giving the error was because it would only loop through itself n number of times.

Crazy huh. Just like to thank Peso with all his help on this one.

Thanks,
Pace

"Impossible is Nothing"
Go to Top of Page

SwePeso
Patron Saint of Lost Yaks

30421 Posts

Posted - 2007-10-25 : 04:15:12
I am quite sure you can rewrite the whole shebang to one set-based statement.



E 12°55'05.25"
N 56°04'39.16"
Go to Top of Page

Pace
Constraint Violating Yak Guru

264 Posts

Posted - 2007-10-25 : 05:24:12
Aye, it has ended up as three procedures, but they involve cursors and it involves calling only the one, which in turn cursors through calling others = )

"Impossible is Nothing"
Go to Top of Page
   

- Advertisement -