How to locate a rogue SELECT statement in an Access frontend? - sql

I have two version of my access frontend. One for Access 2003 which is still being run by a few computers not yet upgraded to Access2010 and Win7, the Acces2010 version unfortunately is caused in Access crash in 2003 at close of the mainform that I have been unable to fix. Backend is SqlServer 2005 SqlExpress version.
Therefore I am stuck with the older frontend for 2003 people, who fortunately don't need the newer capabilities in 2010 version.
Now, a maintenance utility which loads data from a mainframe dump is getting blocked by a "SELECT 1 on Patient_Clinic_Visits" when the Access 2003 version is running somewhere. What I can't find, is where that "SELECT 1 on Patient_Clinic_visits" is coming from.
I have looked in all the module code, and all the queries, but can't find anything like that.
I assume it must therefore be in the frontend form, but how do iI search that without looking through all the objects and controls of that form for RecordSource with some SQL code in it?
cheers,
JonHD

In the end I searched some other questions and thought about programmatically dumping the likely offending information. This is my concoction of two different answers to do what I want. Do to the limits of the Instant Window in VBA over how many lines it will keep from a Debug.Print, I have used WScript object to dump to a log file.
The code basically:
opens each form in the database in turn
dumps its RecordSource description
then for each control on its form, dumps relevant information that MAY contain SQL in some way
note: I use the fact that a Writeline (some code) that causes and error will fail and not write to avoid a lot of testing for different control types for which properties to dump or not dump.
then closed the forms
then it goes through all the queries in the database, and dumps SQL code
(Note1: in the end this didn't find the answer to my problem - see my other recent question!!)
(Note2: this was a quick and dirty script. I noticed the first time it ran the WriteStream didn't write anything, even though it on Step ing through the code it seemed to be doing something. Anyhow when I ran it again it worked. Haven't taken the time to debug why!).
Function DumpFormsAndQueries()
Dim obj As AccessObject
Dim objctrl As Control
Dim frm As Form
Dim dbs As Object
Dim fsoSysObj As FileSystemObject
Dim filFile As Object
Dim txsStream As TextStream
Dim strPath As String
Set dbs = Application.CurrentProject
Set fsoSysObj = New FileSystemObject
' Return Windows Temp folder.
strPath = "C:\Temp\"
On Error Resume Next
' See if file already exists.
Set filFile = fsoSysObj.GetFile(strPath & "Database_Form_dump.Log")
' If not, then create it.
If Err <> 0 Then
Set filFile = fsoSysObj.CreateTextFile(strPath & "Database_Form_dump.Log")
End If
Debug.Print ">> dumping to: " & strPath & "Database_form_dump.log"
Set txsStream = filFile.OpenAsTextStream(ForAppending)
For Each obj In dbs.AllForms
DoCmd.OpenForm obj.name, acDesign
Set frm = Forms(obj.name)
Debug.Print ">>>> dump form: " & obj.name
txsStream.WriteLine "====================================================================="
txsStream.WriteLine "Form : " & obj.name
txsStream.WriteLine "RecordSource: " & frm.RecordSource
txsStream.WriteLine "====================================================================="
For Each objctrl In frm.Controls
txsStream.WriteLine " --------------------------------------------------"
txsStream.WriteLine " : " & objctrl.name & " Type = " & TypeName(objctrl)
txsStream.WriteLine " --------------------------------------------------"
On Error Resume Next
txsStream.WriteLine " >>>> Recordsource: (" & objctrl.RecordSource & ")"
txsStream.WriteLine " >>>> Controlsource: (" & objctrl.ControlSource & ")"
txsStream.WriteLine " >>>> Rowsource: (" & objctrl.RowSource & ")"
txsStream.WriteLine " >>>> Caption: (" & objctrl.Caption & ")"
txsStream.WriteLine " >>>> Text: (" & objctrl.Text & ")"
txsStream.WriteBlankLines 1
Next objctrl
DoCmd.Close acForm, obj.name, acSaveNo
txsStream.WriteBlankLines 3
Next obj
txsStream.WriteLine "====================================================================="
txsStream.WriteLine " Q U E R I E S - in database"
txsStream.WriteLine "====================================================================="
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = CurrentDb()
For Each qdf In db.QueryDefs
txsStream.WriteLine "Query: " & qdf.name
txsStream.WriteLine "SQL (start) ---------------------------------------------------- "
txsStream.WriteLine qdf.sql
txsStream.WriteLine "SQL (end) ---------------------------------------------------- "
Next qdf
Set qdf = Nothing
Set db = Nothing
txsStream.Close
Debug.Print ">> ended"
End Function

In Access menu select Database Tools->Database Documenter. There, select all objects and push OK. It will take some time, but then you will be presented with a report that lists everything in your database, including the code at the end.
The report could be quite big for big databases.
You can export the report to Word (there is an option for it). There, search for your string. (I think it should be "SELECT 1 from Patient_Clinic_visits")

Related

Access VBA Export to New CSV Run-time Error 3011

I have code that exports a dynamic query to a csv. First I save the sql to an existing query, updating it's sql. Then I use that as the query defs, provide saved specs, and want to export to a dynamically constructed csv file name. The csv doesn't exist yet, so I am creating it. I thought doing a docmd.transfertext acExportDelim would create the file.
I end up getting the following error:
Run-time error '3011':
The Microsoft Access database engine could not find the object 'filename.csv'.
Make sure it is spelled correctly. If 'filename.csv' is not a local object,
check your network connection or contact the server administrator.
The "filename.csv" in the error, is exactly what I construct in the below code, and the name of the csv file I want to be created by this process.
Private Sub cmdExportList_Click()
Dim fsql As String
Dim f As Form
Dim RS As DAO.Recordset
Dim MyDate As String
Dim args As String
Set f = Forms!frmMyLists.Form.frmMyLists_SubResults.Form
args = Nz(Forms!frmMyLists.Form.cboMyList.Value, "00")
fsql = "SELECT * " & _
"FROM tblVFileImport "
fsql = fsql & "WHERE tblVFileImport.ListName = '" & args & "' "
fsql = fsql & "ORDER BY tblVFileImport.ID"
CurrentDb.QueryDefs("qryListExportSpecs").SQL = fsql
MyDate = Format(Now(), "yyyymmdd")
If IsDev = True Then
vFile = "C:\LocalPath\VFileData\ExportList\" & args & MyDate & ".csv"
Else
vFile = "\\Server\Share\ExportList\" & args & MyDate & ".csv"
End If
DoCmd.TransferText acExportDelim, "MyListExportSpecs", "qryListExportSpecs", vFile, True
Application.FollowHyperlink vFile
MsgBox "All Set! " & args & " tagged list is now open in Excel. Have Fun!", vbOKOnly, "Export Complete"
End Sub
Right now, I am in my dev copy (IsDev = True) so I'm just going to that local path. I tried creating a csv with the name first, but if I don't write anything to it (which I don't want to, because I'm wanting to transfer the text to it) then it goes away when I close it. I am wondering if it does that because it's 0 bytes. Does anyone know what I am doing wrong? Thanks!
Edit:
I found that if I tested by creating the csv before running the code, so it would already exist, the code was deleting it. I researched that and found the export specs can sometimes mess things up. I removed the export specs and now it works!
So this is :
DoCmd.TransferText acExportDelim, "", "qryListExportSpecs", vFile, True

Master-Detail Query in SQL

I am having trouble querying my data where the expected result is a master-detail type output.
I have a table. In this table I have three columns, they are all strings:
Version
URL
Application
In this table, I have the following data:
**Version** **URL** **Application**
New http://www.stackoverflow1.com Application1
New http://www.stackoverflow2.com Application1
Old http://www.stackoverflow3.com Application2
The expected Output would be
New - Application 1 - (2)
http://www.stackoverflow1.com
http://www.stackoverflow2.com
Old - Application 2 - (1)
http://www.stackoverflow3.com
This table represents an inventory of applications that are deployed on a company’s network. An application can exist on multiple URLs, and be one of two versions, in this example “new” or “old
“. The goal of the query I am having a problem with is to be able to provide a report where the Version, then Application, group the URLs so that one could see, for example, I have the “new” version of application “X” deployed at such and such URLs. In addition, I also need to provide the amounts/counts of URL’s for each grouping of Versions and Application, for example the “new” version of application “X” appeared this many times (this data will eventually be exported from SQL to a spreadsheet).
You likely don't need to write any code.
Use the report wizard - it will group for you.
Assuming you have the table in Access. Just click on the table (highlight).
Then from ribbon create - choose the report wizard.
ORDER that you choose the fields is VERY important.
So, application, version, URL.
Group by Application, version.
Choose "stepped"
The report will look like this:
Now, you can save the report -
Now open report in design mode.
Now from ribbon - choose Group and sort.
Choose to add a sum - but choose your "new" column - it will offer a count due to this being a text value.
You get this:
And then you can move up the total box to the detail section.
You get this:
I suppose you could consider a SQL group by, but the sorting and grouping with the report writer can quite much group and total on rows of data just about anyway you want.
You can remove all the extra heading stuff and other junk - once done, then from the ribbon you can export to excel.
Below is some VBA code that uses two recordsets, one to get the "title" information for each group, and the other to get the detailed information for each group, and outputs it all to an Excel file:
Sub sExportAppData()
On Error GoTo E_Handle
Dim db As DAO.Database
Dim rsMaster As DAO.Recordset
Dim rsDetail As DAO.Recordset
Dim strSQL As String
Dim objXL As New Excel.Application
Dim objXLBook As Excel.Workbook
Dim objXLSheet As Excel.Worksheet
Dim strXLFile As String
Dim lngRow As Long
strXLFile = "J:\downloads\app-data.xlsx"
If Len(Dir(strXLFile)) > 0 Then Kill strXLFile
Set db = DBEngine(0)(0)
strSQL = "SELECT A.AppVersion, A.AppApplication, Count(A.AppApplication) AS AppFrequency " _
& " FROM tblApplication A " _
& " GROUP BY A.AppVersion, A.AppApplication " _
& " ORDER BY A.AppVersion ASC, A.AppApplication ASC;"
Set rsMaster = db.OpenRecordset(strSQL)
If Not (rsMaster.BOF And rsMaster.EOF) Then
Set objXLBook = objXL.Workbooks.Add
Set objXLSheet = objXLBook.Worksheets(1)
lngRow = 1
Do
objXLSheet.Cells(lngRow, 1) = rsMaster!AppVersion & " - " & rsMaster!AppApplication & " - (" & rsMaster!AppFrequency & ")"
lngRow = lngRow + 1
strSQL = "SELECT AppURL FROM tblApplication " _
& " WHERE AppVersion='" & rsMaster!AppVersion & "' AND AppApplication='" & rsMaster!AppApplication & "' " _
& " ORDER BY AppURL ASC;"
Set rsDetail = db.OpenRecordset(strSQL)
If Not (rsDetail.BOF And rsDetail.EOF) Then
Do
objXLSheet.Cells(lngRow, 1) = rsDetail!AppURL
lngRow = lngRow + 1
rsDetail.MoveNext
Loop Until rsDetail.EOF
End If
rsMaster.MoveNext
Loop Until rsMaster.EOF
objXLBook.SaveAs strXLFile
End If
sExit:
On Error Resume Next
rsDetail.Close
rsMaster.Close
Set rsDetail = Nothing
Set rsMaster = Nothing
Set objXLSheet = Nothing
objXLBook.Close
Set objXLBook = Nothing
objXL.Quit
Set objXL = Nothing
Exit Sub
E_Handle:
MsgBox Err.Description & vbCrLf & vbCrLf & "sExportAppData", vbOKOnly + vbCritical, "Error: " & Err.Number
Resume sExit
End Sub
Regards,

SQL statement in ms access db bringing up InputBox

I have VBA for a form.
I'm trying to take the information in a textbox on the form and update a particular field in a table. (haven't figured out how to do that properly)
This line of code is my current try but I'm getting unexpected behavior
The program doesn't continue executing after this
If (Not IsNull([New_Value_Box].Value)) Then
DoCmd.RunSQL "Update [Export_NDC_Certification] Set " & [Field_List].Value & " = " & [New_Value_Box].Value & " WHERE SellerLoanIdentifier = " & Current_Loan
End If
it does however open an input box with the value of Current_Loan as the caption. It doesn't appear to do anything with the input and it doesn't execute any further code. I've used MsgBox's for debugging and its definitely coming from this line. This line was what I came across for taking a value and updating a particular table value with it. if this isn't the way to do it any push in the right direction would be appreciated. Thank you!
First, I would recommend using the Execute method (of either DAO.Database or DAO.QueryDef), instead of using DoCmd.RunSQL. This makes debugging a lot easier (here's a forum post with more information).
Also, since it seems that you need values in all your controls ([Field_List], [New_Value_Box], and Current_Loan), you should do a null check on all of those.
As noted by #HansUp, your actual SQL string is likely causing the issue, so you probably want to store that in a separate variable you can then output to the immediate window.
With all that being said, revised code might look something like this:
Dim db As DAO.Database, qdf As DAO.QueryDef
Dim strSQL As String
If _
IsNull([New_Value_Box].value) Or _
IsNull([Field_List].value) Or _
IsNull([Current_Loan].value) _
Then
' handle missing input
Else
' we know all required fields have values, so can proceed
strSQL = _
"UPDATE [Export_NDC_Certification " & _
"SET " & [Field_List].value & "=" & [New_Value_Box].value & " " & _
"WHERE SellerLoanIdentifier=" & Current_Loan
Debug.Print strSQL
Set db = CurrentDb
Set qdf = db.CreateQueryDef("")
qdf.SQL = strSQL
qdf.Execute dbFailOnError
End If
' clean up DAO objects
Set qdf = Nothing: Set qdf = Nothing: Set db = Nothing

How to limit the number of results in an LDAP query

I'm programming an Office 2010 Word template that needs to interact with the Active Directory, to retrieve some user info. The user filling out the template can give some input for the search that is used to retrieve the AD info.
I'm using the ADODB Recordset and Command to setup my query:
Public Function GetActiveDirectoryInfo(searchString As String) As Object
Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim strQuery, adoRecordset
'remove user input asteriks
searchString = Replace(searchString, "*", "")
' Setup ADO objects.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
Set adoCommand.ActiveConnection = adoConnection
strBase = "<LDAP://" & GLOBAL_LDAP_USER_OU & ">"
' Filter on user objects.
strFilter = "(&(objectCategory=person)(objectClass=user)(|(sn=" & searchString & "*)(cn=" & searchString & "*)))"
' Comma delimited list of attribute values to retrieve.
strAttributes = ACTIVE_DIRECTORY_FIELDS
' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";OneLevel"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 10
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
'adoCommand.Properties("Maximum Rows") = 10 'error: read only
On Error GoTo err_NoConnection
' Run the query.
Set adoRecordset = adoCommand.Execute
Set foundItems = adoRecordset
Debug.Print "Found : " & foundItems.RecordCount & " records"
Exit Function
err_NoConnection:
'in case of error: return <nothing>
Debug.Print Err.description
Set GetActiveDirectoryInfo = Nothing
End Function
THis function is part of a User Class in MS Word.
My question: how to prevent the user from retrieving thousands of records? I have been reading about paging, but that seems more like a network-load-thing than actually limiting the search results that will eventually get back to me.
I've tried several things but with no results. For instance setting the MaxRecords or Maximum Rows properties. Both give an error (non existing property for the first, and read only error for the second).
ANy ideas anyone.
MS Office 2010 dutch
ADO Objects 6.0
Thanx!
Unfortunately ADO MaxRecord that limits the number of search results is not implemented for ADsDSObject. The link https://support.microsoft.com/kb/269361 details the workaround to solve the issue.

Error 3027, Database or object is ready only?

When I run the code blow on, it stops and gives me an error
3027
Database or Object is Read only
When I clicked debug, it pointed at rec.edit.
Yet I have no idea how it is read only. I did check to make sure that the object was closed and the same error still came up. The person who came up with it said it worked for them and that they didn't have any issues with readonly. Any ideas?
Public Function HitTest()
Dim db As Database
Dim rec As DAO.Recordset
Dim fld As DAO.Field
Set db = CurrentDb
Set rec = db.OpenRecordset("PlayerSal")
EditTable = "PlayerSal"
For Each fld In rec.Fields
If fld.Name <> "Name" And fld.Name <> "Salary" And Left(fld.Name, 4) <> "Per_" Then
strFieldName = "Per_" & fld.Name & ""
'rs.Fields (strFieldName)
'X = "IIf(rec([" & fld.Name & "]) <> 0, Format((rec([Salary]) / rec([" & fld.Name & "])), '$#,###.##'), 0)"
If FieldExists(EditTable, strFieldName) Then
Else
'AltTable = "ALTER TABLE " & EditTable & " ADD COLUMN " & strFieldName & " Double;"
'CurrentDb.Execute (AltTable)
End If
rec.Edit
X = IIf(rec((fld.Name)) <> 0, Format((rec("Salary") / rec((fld.Name))), "$#,###.##"), 0)
rec.Fields(strFieldName).Value = X
rec.Update
End If
Next fld
End Function
Because I know that Access can be really silly at times, I decided to try a new Database and just import the few files I needed. I've had times where doing that randomly makes things work for some reason. When I imported the module you see below, it then stopped at the
If FeildsExists(EditTable, strFieldName)
and it said Sub or Function not defined... I don't know if either of these two are related to something simple.. but this is getting silly... especially when the guy who put this together had it work fine.
I know the second half. :o) Your function name is wrong. You have "If FeildsExists" and it should be "If FieldExists".