Classic ASP error in Windows Server 2012 / IIS8 - vbscript

I recently had to migrate an (inherited) old Classic ASP VBScript reporting website from a windows server 2003 to windows server 2012.
After messing about with the AppPool to make it use 32bit mode, and also set up parent paths, I've been able to get the application to work.
However, the following page is currently throwing this error:
Microsoft VBScript runtime error '800a01a8'
Object required: ''
/Dashboard/modules/Monthly_Report/footfall/Save_Session_Variables_Stock.asp, line 69
The code behind the page is
<!--#include file="../../../../Connections/Dashboard_Connection.asp" -->
<%
Session.LCID=2057
'Session("strMonthly_Site")=trim(request("select_site"))
''xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
'Set the search screen variables to be nothing
Session("strCategory_Lookup")=""
Session("strSearch_String")=""
'*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
'Get the market code based on the site
'*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
DIM rsGet_Market
Set objConn = Server.CreateObject("ADODB.Connection")
objConn.Open strConnection
'Get the Site Level_Code
Session("SITE_LVL") = MID(Session("strMonthly_Site"),INSTR(Session("strMonthly_Site"),",")+ 1, 2)
Session("SITE_LVL_CODE") = LEFT(Session("strMonthly_Site"),INSTR(Session("strMonthly_Site"),",")-1)
SELECT CASE CINT(Session("SITE_LVL"))
CASE 1 'Site
strQuery = "SELECT SITE_MARKET.MARKET_CODE, SITE_MARKET.MARKET_TEXT, SITE_ZONE.ZONE_CODE, SITE_ZONE.ZONE_TEXT, SITE_AREA.AREA_CODE, SITE_AREA.AREA_TEXT, SITE.SITE_CODE, SITE.SITE_TEXT " & _
"FROM SITE_REGION INNER JOIN SITE_MARKET ON SITE_REGION.REGION_CODE = SITE_MARKET.REGION_CODE INNER JOIN SITE INNER JOIN SITE_AREA ON SITE.AREA_CODE = SITE_AREA.AREA_CODE " & _
"INNER JOIN SITE_ZONE ON SITE_AREA.ZONE_CODE = SITE_ZONE.ZONE_CODE ON SITE_MARKET.MARKET_CODE = SITE_ZONE.MARKET_CODE " & _
"WHERE SITE.SITE_CODE = '" & Session("SITE_LVL_CODE") & "'"
Set rsGet_Market = Server.Createobject("ADODB.Recordset")
rsGet_Market.Open strQuery, objConn
Session("Market_Market_Code") = rsGet_Market("MARKET_CODE") & " - " & rsGet_Market("MARKET_TEXT")
Session("Market_Zone_Code") = rsGet_Market("ZONE_CODE") & " - " & rsGet_Market("ZONE_TEXT")
Session("Market_Area_Code") = rsGet_Market("AREA_CODE") & " - " & rsGet_Market("AREA_TEXT")
Session("Market_Site_Code") = rsGet_Market("SITE_CODE") & " - " & rsGet_Market("SITE_TEXT")
Session("MARKET_CODE") = rsGet_Market("MARKET_CODE")
Session("Market_Market_Code1") = rsGet_Market("MARKET_TEXT")
Session("Market_Zone_Code1") = rsGet_Market("ZONE_TEXT")
Session("Market_Area_Code1") = rsGet_Market("AREA_TEXT")
Session("Market_Site_Code1") = rsGet_Market("SITE_CODE") & " - " & rsGet_Market("SITE_TEXT")
Session("Table_Lvl_Label") = "Shop"
CASE 4 'Market
strQuery = "SELECT SITE_MARKET.MARKET_CODE, SITE_MARKET.MARKET_TEXT, SITE_ZONE.ZONE_CODE, SITE_ZONE.ZONE_TEXT, SITE_AREA.AREA_CODE, SITE_AREA.AREA_TEXT, SITE.SITE_CODE, SITE.SITE_TEXT " & _
"FROM SITE_REGION INNER JOIN SITE_MARKET ON SITE_REGION.REGION_CODE = SITE_MARKET.REGION_CODE INNER JOIN SITE INNER JOIN SITE_AREA ON SITE.AREA_CODE = SITE_AREA.AREA_CODE " & _
"INNER JOIN SITE_ZONE ON SITE_AREA.ZONE_CODE = SITE_ZONE.ZONE_CODE ON SITE_MARKET.MARKET_CODE = SITE_ZONE.MARKET_CODE " & _
"WHERE SITE_MARKET.MARKET_CODE = '" & Session("SITE_LVL_CODE") & "'"
Set rsGet_Market = Server.Createobject("ADODB.Recordset")
rsGet_Market.Open strQuery, objConn
Session("Market_Market_Code") = rsGet_Market("MARKET_CODE") & " - " & rsGet_Market("MARKET_TEXT")
Session("Market_Zone_Code") = "N/A"
Session("Market_Area_Code") = "N/A"
Session("Market_Site_Code") = "N/A"
Session("MARKET_CODE") = rsGet_Market("MARKET_CODE")
Session("Market_Market_Code1") = rsGet_Market("MARKET_TEXT")
Session("Market_Zone_Code1") = "N/A"
Session("Market_Area_Code1") = "N/A"
Session("Market_Site_Code1") = "N/A"
Session("Table_Lvl_Label") = "Market"
END SELECT
rsGet_Market.close
objConn.Close
set rsGet_Market= Nothing
set objConn= Nothing
response.redirect "Footfall_Report.asp"
%>
When tracing the SQL query, I can execute the same SELECT without any visible issues.
Would anyone have any ideas as to why this could be failing?

Without going into how to structure your code etc, it is a simple enough fix.
SELECT CASE CINT(Session("SITE_LVL"))
CASE 1 'Site
'Recordset instantiated here
Set rsGet_Market = Server.Createobject("ADODB.Recordset")
rsGet_Market.Open strQuery, objConn
'Lots of fluff here removed to emphasize the point
'...
'Close Recordset inside the Case statement
rsGet_Market.close
CASE 4 'Market
'Recordset instantiated here
Set rsGet_Market = Server.Createobject("ADODB.Recordset")
rsGet_Market.Open strQuery, objConn
'Lots of fluff here removed to emphasize the point
'...
'Close Recordset inside the Case statement
rsGet_Market.close
END SELECT
'Don't close rsGet_Market here as it might not exist and cause an error.
objConn.Close
By moving the rsGet_Market.close inside the Case statement it will only be called when there is a corresponding ADODB.Recordset in the rstGet_Market object.
You can't Close a Recordset that never exists in the first place.
We could improve on this though by moving the instantiation outside of the Case statement to remove yet more duplication (DRY Principle)
'Recordset instantiated here
Set rsGet_Market = Server.Createobject("ADODB.Recordset")
SELECT CASE CINT(Session("SITE_LVL"))
CASE 1 'Site
'Recordset will be open if data is returned.
rsGet_Market.Open strQuery, objConn
'Lots of fluff here removed to emphasize the point
'...
'Close Recordset inside the Case statement
rsGet_Market.close
CASE 4 'Market
'Recordset will be open if data is returned.
rsGet_Market.Open strQuery, objConn
'Lots of fluff here removed to emphasize the point
'...
'Close Recordset inside the Case statement
rsGet_Market.close
END SELECT
'Release Recordset object from memory
Set rsGet_Market = Nothing
'Don't close rsGet_Market here as it might not exist and cause an error.
objConn.Close

Correction, line 71 is rsGet_Market.close
OK. Let's take a look closer to your code.
You calling rsGet_Market.close always, but create it only for Case 1 and Case 4. Perhaps you have CINT(Session("SITE_LVL")) not equal to 1 and not equal to 4.
but that doesn't generate any data.
Yes, but you always calling method (function) for not existing object (Set create it in your case for rsGet_Market). That why you have error Object required: ''

Related

Search using Combo Box and Filter the results in text boxes

I am trying to do a small program on VB 6.0 to find the records in database and print it in text box based on combo box selection but i failed to find a code which allow me to do this.
Any help please.
Dim adoCon
Dim adoRs
Dim strSQL As String
Dim strDB As String
'Change YourDatabaseName to actual database you have
strDB = "c:\path\YourDatabaseName.accdb"
Set adoCon = CreateObject("ADODB.Connection")
adoCon.Open "Provider = Microsoft.ACE.OLEDB.12.0; " & _
"Data Source = " & strDB & ";" & _
"Persist Security Info = False;"
'Change Table1 to your table name in MS Access
'change the name of combobox and the fieldname in MS Access table
'
'''''''''''''''''''''''''''''''''''''''''''''''''' ''''''''''''''''''''''
' if combo is numeric
strSQL = "SELECT [fieldNameToReturn] FROM Table1 Where [fieldName] = " + [combo].Value + ";"
' if combo is text
'strSQL = "SELECT [fieldNameToReturn] FROM Table1 Where [fieldName] = '" + [combo].Value + "';"
'''''''''''''''''''''''''''''''''''''''''''''''''' '''''''''''''''''''''''
Set adoRs = CreateObject("ADODB.Recordset")
'Set the cursor type we are using so we can navigate through the recordset
adoRs.CursorType = 2
'Set the lock type so that the record is locked by ADO when it is updated
adoRs.LockType = 3
'Open the tblComments table using the SQL query held in the strSQL varaiable
'adoRs.Open strSQL, adoCon
If Not adoRS.Eof() Then
[yourTextBox] = adoRs(0)
End If
adoRs.Close
adoCon.Close
Set adoRs = Nothing
Set adoCon = Nothing
"BOF" below is not a typo. If the recordset is empty (the query returned no records) BOF will be true.
adoRs.Open strSQL, adoCon
If Not adoRS.BOF Then
'If not _BOF_ we have records so load the first record
adoRs.MoveFirst
'If first field is a string then use this
[yourTextBox] = adoRs.Fields(0).Value
'If first field is numeric then use this
[yourTextBox] = CStr(adoRs.Fields(0).Value)
Else
Msgbox "No records returned."
End If
If you were processing multiple records you would still do the MoveFirst and then loop until EOF was true, processing each record. The MoveNext will set EOF = True when there are no more records to process.
adoRs.Open strSQL, adoCon
If Not adoRS.BOF Then
'If not _BOF_ we have records so load the first record
adoRs.MoveFirst
Do While Not adoRS.EOF
'Process records here
'.
'.
'.
adoRS.MoveNext
Loop
Else
Msgbox "No records returned."
End If

Dropdownlist is taking long time to load in VB 6.0

I'm using vb6 and sql server.in which on the form load I'm filling 4 combobox.But its taking 10 to 12 minutes to load the form.
My code is as follows:
Can anybody help me to make the form load fast?
Public Sub fillCombo(Id As String, Name As String, Table As String, obj As Object, Optional cond As String)
Dim rsF As New ADODB.Recordset
With rsF
If .State = adStateOpen Then .Close
If cond = "" Then
.Open "Select " & Id & "," & Name & " From " & Table & " Order by " & Name, Cn, adOpenKeyset, adLockOptimistic
Else
.Open "Select " & Id & "," & Name & " From " & Table & " Where " & cond & " Order by " & Name, Cn, adOpenKeyset, adLockOptimistic
End If
obj.Clear
'obj.AddItem ""
While Not .EOF
obj.AddItem .Fields(1)
obj.ItemData(obj.NewIndex) = .Fields(0)
.MoveNext
Wend
.Close
End With
End Sub
function call is as follows:
fillCombo "JobId", "JobName", "Jobs", cboJob
The problem (I believe) is that you are using a server-side recordset. When you do this, you are making one round trip to the server for each iteration of your loop, which is, as you have found, glacially slow.
The solution is to create a client-side recordset. That sends the data from the server to the client in one go. Keep in mind that client-side recordsets are always static; if you set the CursorType to adOpenKeyset the CursorLocation to adUseClient, the latter will override the former and your CursorType will still be adOpenStatic.
Here's a mod to your code, with various improvements (in particular, with your atrocious indenting corrected; you might consider being a bit nicer to the poor folks who have to work with your code down the line when you write it):
Public Sub fillCombo(Id As String, Name As String, Table As String, obj As Object, Optional cond As String)
Dim sql As String
Dim rsF As ADODB.Recordset 'Don't use "As New" in VB6, it's slow
'sql variable with ternary conditional (IIf) is cleaner way to do what you want
sql = "Select " & Id & "," & Name & " From " & Table & IIf(cond = "", "", " Where " & cond) & " Order by " & Name
Set rsF = New ADODB.Recordset
With rsF
.CursorLocation = adUseClient 'Client-side, static cursor
'If .State = adStateOpen Then .Close --Get rid of this: if you just created rsF, it can't be open, so this is a waste of processor cycles
.Open sql, Cn 'Much prettier, yes? :)
obj.Clear 'All this is fine
Do Until .EOF
obj.AddItem .Fields(1)
obj.ItemData(obj.NewIndex) = .Fields(0)
.MoveNext
Loop
.Close
End With
End Sub

How to LDAP query without knowing exact OU

Set objDomain = GetObject("WinNT://abc.local")
For each objDomainItem in objDomain
if objDomainItem.Class = "User" then
'WScript.echo "Name: " & objDomainItem.Name + " : Full Name: " + objDomainItem.FullName
Set objUser = Nothing
err.clear
Set objUser = GetObject("LDAP://cn=" & objDomainItem.FullName & ",OU=IS, OU=Users, OU=ABC Company, DC=ABC, dc=local")
if err.number = 0 then
wscript.echo "distinguishedName: " & objUser.distinguishedName
end if
end if
Next
Right now, this works fine to list all users in the IS department (OU=IS). But when I take out "OU=IS" to list all users in all departments, it returns nothing; no user objects at all. The only way it will return the user object for the given fullName is if I also specify the OU that that user is contained in; but I do not have the OU to supply it.
Our AD structure is
ABC Company --> Users --> IS
ABC Company --> Users --> FINANCE
ABC Company --> Users --> Management
ABC Company --> Users --> Flight Operations
etc etc etc
I want to use the code above to enumerate all users from the "Users" level, down through ALL departments, but again, as soon as I remove "OU=IS", it returns nothing.
Any help?
Do a query with scope Subtree using an ADODB.Connection and an ADODB.Command object:
base = "<LDAP://OU=Users,OU=ABC Company,DC=ABC,DC=local>"
fltr = "(&(objectClass=user)(objectCategory=Person))"
attr = "distinguishedName,sAMAccountName"
scope = "subtree"
Set cn = CreateObject("ADODB.Connection")
cn.Provider = "ADsDSOObject"
cn.Open "Active Directory Provider"
Set cmd = CreateObject("ADODB.Command")
Set cmd.ActiveConnection = cn
cmd.CommandText = base & ";" & fltr & ";" & attr & ";" & scope
Set rs = cmd.Execute
Do Until rs.EOF
WScript.Echo rs.Fields("distinguishedName").Value
WScript.Echo rs.Fields("sAMAccountName").Value
rs.MoveNext
Loop
Add other attributes to attr as required (the variable contains a list of attribute names as a comma-separated string).
Since these queries require the same boilerplate code every time, I got fed up with writing it over and over again some time ago and wrapped it in a custom class (ADQuery) to simplify its usage:
'<-- paste or include class code here
Set qry = New ADQuery
qry.SearchBase = "OU=Users,OU=ABC Company,DC=ABC,DC=local"
qry.Attributes = Array("distinguishedName", "sAMAccountName")
Set rs = qry.Execute
Do Until rs.EOF
WScript.Echo rs.Fields("distinguishedName").Value
WScript.Echo rs.Fields("sAMAccountName").Value
rs.MoveNext
Loop

How to update a recordset

here is my code
Dim Cn1 As ADODB.Connection
Dim iSQLStr As String
Dim field_num As Integer
Set Cn1 = New ADODB.Connection
Cn1.ConnectionString = _
"Driver={Microsoft Text Driver (*.txt; *.csv)};" & _
"DefaultDir=" & "C:\path\"
Cn1.Open
iSQLStr = "Select * FROM " & "file.txt" ' & " ORDER BY " & txtField.Text
field_num = CInt(1) - 1
Set Rs1 = Cn1.Execute(iSQLStr)
lstResults.Clear
While Not Rs1.EOF
DoEvents
Rs1.Fields(field_num).Value = "qaz"
If IsNull(Rs1.Fields(field_num).Value) Then
lstResults.AddItem "<null>"
Else
lstResults.AddItem Rs1.Fields(field_num).Value
End If
Rs1.MoveNext
Wend
The error i get is in this line
Rs1.Fields(field_num).Value = "qaz"
it says "The current recordset does not support updating", what is wrong in the code?
I'm not sure if this is valid for text files but with SQL Server you need to change the LockTypeEnum Value setting to allow editing see this link, the default is adLockReadOnly
Edit
According to this link it is not possible to edit a text file via ADO.

Speed up this Find/Filter Operation - (VB6, TextFile, ADO, VFP 6.0 Database)

I'm trying to figure out how to speed up this operation. Before I import a record from the text file I first need to see if one exists in the database. If it does exist I'm going to perform an update operation on it. If it does not exist I'm going to create a new record.
Running the code you see below this operation takes somewhere in the neighborhood of 3 hours.
I've tried using ADO's find method and it actually appears to be slower than the filter method.
The database is a Visual Foxpro 6 database. The table does have an index on the item_cd field but the table does not have any primary key established. This is out of my control since I didn't write the software and I'm trying to stay away from making any structural changes to the database.
There are 46652 rows in the text file and about 650,000 records/rows in the ADO recordset. I think slimming down the recordset would be the biggest step in fixing this but I haven't come up with any way of doing that. I'm trying to prevent creating duplicate records since there is no primary key and so I really need to have the entire table in my recordset.
Because I'm running this on my local machine it appears that the operation is limited by the power of the CPU. In actuality this might be used across the network, especially if I can get it to go faster.
Dim sFileToImport As String
sFileToImport = Me.lstFiles.Text
If sFileToImport = "" Then
MsgBox "You must select a file from the listbox to import."
Exit Sub
End If
If fConnectToDatabase = False Then Exit Sub
With gXRst
.CursorLocation = adUseClient
.CursorType = adOpenKeyset
.LockType = adLockReadOnly
.Open "SELECT item_cd FROM xmsalinv ORDER BY item_cd ASC", gXCon
End With
Call fStartProgress("Running speed test.")
Dim rstTxtFile As ADODB.Recordset
Set rstTxtFile = New ADODB.Recordset
Dim con As ADODB.Connection
Set con = New ADODB.Connection
Dim sConString As String, sSQL As String
Dim lRecCount As Long, l As Long
Dim s As String
sConString = "DRIVER={Microsoft Text Driver (*.txt; *.csv)};Dbq=" & gsImportFolderPath & ";Extensions=asc,csv,tab,txt;Persist Security Info=False;"
con.Open sConString
sSQL = "SELECT * FROM [" & sFileToImport & "]"
rstTxtFile.Open sSQL, con, adOpenKeyset, adLockPessimistic
If Not (rstTxtFile.EOF And rstTxtFile.BOF) = True Then
rstTxtFile.MoveFirst
lRecCount = rstTxtFile.RecordCount
Do Until rstTxtFile.EOF = True
'This code appears to actually be slower than the filter method I'm now using
'gXRst.MoveFirst
'gXRst.Find "item_cd = '" & fPQ(Trim(rstTxtFile(0))) & "'"
gXRst.Filter = "item_cd = '" & fPQ(Trim(rstTxtFile(0))) & "'"
If Not (gXRst.EOF And gXRst.BOF) = True Then
s = "Item Found - " & Trim(rstTxtFile(0)) 'item found
Else
s = "Item Not Found - " & Trim(rstTxtFile(0)) 'Item not found found
End If
l = l + 1
Call subProgress(l, lRecCount, s)
rstTxtFile.MoveNext
Loop
End If
Call fEndProgress("Finished running speed test.")
Cleanup:
rstTxtFile.Close
Set rstTxtFile = Nothing
gXRst.Close
A simple solution to speed up Yours_Rs.find response is to use the Yours_Rs.move statement first if it is possible for you. What I have done is to use MyRs.move statement prior to using MyRs.find to come in the vicinity of my actual record. It had really worked for me as response of move statement is quite brisk.
I was using it to locate a patient record. So, moving the pointer to a record near the actual record made MyRs.find statement to work with the speed of light.
regards,
MAS.
doesn't answer your question and this is a pretty old thread, but
why don't you import your text file to a temporary table on your db then do a join?
something like
SELECT tt.* FROM texttemp tt left outer join xmsalinv xal on tt.field1=xal.item_cd where xal.item_cd is null
this should return the contents of your imported text file which don't have any item_cd matches in the database, since you're dealing with a text file that complicates the query which is why i'm wondering your not importing the contents to a temporary table.
now assuming you know the mapping of the fields, you can probably also use this to insert assuming your db accepts insert select notation it'd be insert into xmsalinv (fields) select (matching fields) from (as above...)
this moves your choke points to the import process, which i'm hoping is quick.
the ado collections seem like they're pretty stupid, so they don't benefit from any sort of knowledge about the data and are kinda slow.
ah next item on "vb6 filter" google http://www.techrepublic.com/article/why-ados-find-method-is-the-devil/1045830
this response is based on basic sql knowledge and not tailored to foxpro
Use a firehose cursor for the VFP query's results if you aren't, and see your other post here for suggestions regarding the text file Recordset.
Perhaps better yet though, you might try getting rid of your slow "loop and search" aproach.
I would probably create a temporary Jet 4.0 MDB from scratch for each text file you want to look up. Import the text data, index your key field. Use ADOX to define a linked table over in the VFP database. The use a query to do your matching.
Close and dispose of the MDB afterward.
In response to Bob Riemersma's post, the text file is not causing the speed issues. I've changed my code to open a recordset with a query looking for a single item. This code now runs in 1 minute and 2 seconds as opposed to the three to four hours I was looking at the other way.
Dim sFileToImport As String
sFileToImport = Me.lstFiles.Text
If sFileToImport = "" Then
MsgBox "You must select a file from the listbox to import."
Exit Sub
End If
If fConnectToDatabase = False Then Exit Sub
Call fStartProgress("Running speed test.")
Dim rstTxtFile As ADODB.Recordset
Set rstTxtFile = New ADODB.Recordset
Dim con As ADODB.Connection
Set con = New ADODB.Connection
Dim sConString As String, sSQL As String
Dim lRecCount As Long, l As Long
Dim sngQty As Single, sItemCat As String
sConString = "DRIVER={Microsoft Text Driver (*.txt; *.csv)};Dbq=" & gsImportFolderPath & ";Extensions=asc,csv,tab,txt;Persist Security Info=False;"
con.Open sConString
sSQL = "SELECT * FROM [" & sFileToImport & "]"
rstTxtFile.Open sSQL, con, adOpenKeyset, adLockPessimistic
If Not (rstTxtFile.EOF And rstTxtFile.BOF) = True Then
rstTxtFile.MoveFirst
lRecCount = rstTxtFile.RecordCount
Do Until rstTxtFile.EOF = True
l = l + 1
sItemCat = fItemCat(Trim(rstTxtFile(0)))
If sItemCat <> "[item not found]" Then
sngQty = fItemQty(Trim(rstTxtFile(0)))
End If
Call subProgress(l, lRecCount, sngQty & " - " & sItemCat & " - " & rstTxtFile(0))
sngQty = 0
rstTxtFile.MoveNext
Loop
End If
Call fEndProgress("Finished running speed test.")
Cleanup:
rstTxtFile.Close
Set rstTxtFile = Nothing
My Functions:
Private Function fItemCat(sItem_cd As String) As String
'Returns blank if nothing found
If sItem_cd <> "" Then
With gXRstFind
.CursorLocation = adUseClient
.CursorType = adOpenKeyset
.LockType = adLockReadOnly
.Open "SELECT item_cd, ccategory FROM xmsalinv WHERE item_cd = '" & fPQ(sItem_cd) & "'", gXCon
End With
If Not (gXRstFind.EOF And gXRstFind.BOF) = True Then
'An item can technically have a blank category although it never should have
If gXRstFind!ccategory = "" Then
fItemCat = "[blank]"
Else
fItemCat = gXRstFind!ccategory
End If
Else
fItemCat = "[item not found]"
End If
gXRstFind.Close
End If
End Function
Private Function fIsStockItem(sItem_cd As String, Optional bConsiderItemsInStockAsStockItems As Boolean = False) As Boolean
If sItem_cd <> "" Then
With gXRstFind
.CursorLocation = adUseClient
.CursorType = adOpenKeyset
.LockType = adLockReadOnly
.Open "SELECT item_cd, bal_qty, sug_qty FROM xmsalinv WHERE item_cd = '" & fPQ(sItem_cd) & "'", gXCon
End With
If Not (gXRstFind.EOF And gXRstFind.BOF) = True Then
If gXRstFind!sug_qty > 0 Then
fIsStockItem = True
Else
If bConsiderItemsInStockAsStockItems = True Then
If gXRstFind!bal_qty > 0 Then
fIsStockItem = True
End If
End If
End If
End If
gXRstFind.Close
End If
End Function
Private Function fItemQty(sItem_cd As String) As Single
'Returns 0 if nothing found
If sItem_cd <> "" Then
With gXRstFind
.CursorLocation = adUseClient
.CursorType = adOpenKeyset
.LockType = adLockReadOnly
.Open "SELECT item_cd, bal_qty FROM xmsalinv WHERE item_cd = '" & fPQ(sItem_cd) & "'", gXCon
End With
If Not (gXRstFind.EOF And gXRstFind.BOF) = True Then
fItemQty = CSng(gXRstFind!bal_qty)
End If
gXRstFind.Close
End If
End Function
First can try creating an in-memory index on item_cd with gXRst!item_cd.Properties("OPTIMIZE").Value = True which will speed up both Find and Filter.
For ultimate speed in searching initialize helper index Collection like this
Set cIndex = New Collection
On Error Resume Next
Do While Not gXRst.EOF
cIndex.Add gXRst.Bookmark, "#" & gXRst!item_cd.Value
gXRst.MoveNext
Loop
On Error GoTo ErrorHandler
And insetad of Find use some function like this
Public Function SearchCollection(Col As Object, Index As Variant) As Boolean
On Error Resume Next
IsObject Col(Index)
SearchCollection = (Err.Number = 0)
On Error GoTo 0
End Function
3 hours just for a few hundred thousands of records!!! You are doing it the wrong way. Simply:
-append text file to a VFP table,
-then insert the ones that do not exist in existing table with a single SQL
-and update the ones that exist with another Update sql.
That is all and should take less than a minute (a minute is even very slow). You can do all these using the VFPOLEDB driver and it doesn't matter that you have VFP6 database, VFPOLEDB has VFP9 engine built-in.

Resources