List reports along with their description - ms-access

Variety of ways to get a list of report names:
Query
SELECT [Name] FROM MsysObjects
WHERE ([Type] = -32764)
Or VBA
Dim rpt As AccessObject
Dim dB As Object
On Error GoTo Error_Handler
Set dB = Application.CurrentProject
For Each rpt In dB.AllReports
Debug.Print rpt.Name
Next rpt
A report can have a Description under the Properties (Right-Click on report object), but I cannot access with code.
I'd like to have a listbox display a user-friendly report name associated with the actual report name. I'm trying to avoid creating a separate table to manage this at this point.

CurrentProject is an ADO object, and I don't know how to do what you want from ADO. You can use DAO to retrieve the Description property.
? CurrentDb.Containers("Reports").Documents("rptFoo").Properties("Description")
Foo Report
Since Description is a user-defined property, it doesn't exist until you assign a value for it. Therefore the next line triggers error 3270 (Property not found) for rptLinks, since it doesn't have a Description assigned.
? CurrentDb.Containers("Reports").Documents("rptLinks").Properties("Description")
You could trap that error. Or see if you can make use of Allen Browne's HasProperty function
A totally different approach would be to create tblReports with report_name and friendly_name fields. You would have to maintain that table, but the workload should be roughly equivalent to maintaining the Description properties on the report objects. Then you could use a simple SELECT on the table as the RowSource for your list box.
Update: You could also SELECT from MSysObjects with a custom function to return the Description for each report.
Public Function ReportDescription(ByVal pName As String) As String
Dim strReturn As String
Dim strMsg As String
On Error GoTo ErrorHandler
strReturn = _
CurrentDb.Containers("Reports").Documents(pName).Properties("Description")
ExitHere:
On Error GoTo 0
ReportDescription = strReturn
Exit Function
ErrorHandler:
Select Case Err.Number
Case 3270 'Property not found.'
'strReturn = "(no Description)"'
'* no Description -> just echo report name *'
strReturn = pName
Case Else
strMsg = "Error " & Err.Number & " (" & Err.description _
& ") in procedure ReportDescription"
MsgBox strMsg
strReturn = vbNullString
End Select
GoTo ExitHere
End Function
Revise your original query to use the function.
SELECT
[Name] AS report_name,
ReportDescription([Name]) AS friendly_name
FROM MsysObjects
WHERE ([Type] = -32764);

Related

How do I programmatically retrieve the values from a linked table's property sheet?

I am working in MS Access. All the tables and views are linked to a SQL Server database. I want to write a procedure that will retrieve and store all of the formatting information about these objects. A lot of this information is available from the property sheet (I open a table in Design View, and hit F4 for the property sheet). Eg:
Filter
Order By
Filter On Load
Order by On Load
Order by On
How do I retrieve these properties programmatically? I only see them listed for Reports.
Note that I need to retrieve the values, not just set them. I know about the SetFilter method, and that's not what I need.
The linked table exists as a DAO.TableDef in your database's TableDefs collection. So you can check the TableDef.Properties collection for those 5 properties.
However beware that both Filter and OrderBy are user-created instead of default properties, which means they are not included in the Properties collection unless you've assigned them values. Attempting to retrieve one which doesn't exist triggers error 3270, "Property not found". You can trap that error, respond to it as you wish, and continue on for the other properties you're interested in. Or you could first determine whether the property exists and only attempt to retrieve its value when it does exist.
This code sample uses the first approach (trap the error):
Const cstrTable As String = "YourLinkedTableNameHere"
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim strMsg As String
Dim varProp As Variant
Dim varProperties As Variant
On Error GoTo ErrorHandler
varProperties = Array("Filter", "FilterOnLoad", "OrderBy", _
"OrderByOn", "OrderByOnLoad")
Set db = CurrentDb
Set tdf = db.TableDefs(cstrTable)
For Each varProp In varProperties
Debug.Print varProp, tdf.Properties(varProp).Value
Next
ExitHere:
Exit Sub
ErrorHandler:
Select Case Err.Number
Case 3270 ' Property not found.
strMsg = "Property '" & varProp & "' not found."
'MsgBox strMsg
Debug.Print strMsg
Resume Next
Case Else
strMsg = "Error " & Err.Number & " (" & Err.Description & ")"
MsgBox strMsg
Resume ExitHere
End Select
How about something like this? (I've defined "table2" to have two fields, "PropertyName" and "PropertyValue"..."table1" is a placeholder for any of your existing tables)
Dim i As Integer
Dim j As Integer
Dim RS As DAO.Recordset
On Error Resume Next
Set RS = CurrentDb.OpenRecordset("select * from table2")
j = CurrentDb.TableDefs("table1").Properties.Count
For i = 0 To j - 1
RS.AddNew
RS!PropertyName = CurrentDb.TableDefs("table1").Properties(i).Name
RS!PropertyValue = Nz(CurrentDb.TableDefs("table1").Properties(i).Value, "-")
RS.Update
Next i

Check if certain data exists in a field in a table

I have a table (tblForms) in which one of the fields is a lookup to another table (tblClients). How can I find if a certain Client has data or does not have data in tblForms? DCount only works if the Client does appear in tblForms.
I have a form (frmDisclosure) with a command button - onClick:
Private Sub Command245_Click()
On Error GoTo Command245_Click_Err
DoCmd.OpenForm "frmClient", acNormal, "", "[ClientID]= " & Me.Client, , acNormal
DoCmd.Close acForm, "frmDisclosure"
Command245_Click_Exit:
Exit Sub
Command245_Click_Err:
MsgBox Error$
Resume Command245_Click_Exit
End Sub
When I click this I get the error (N.B. I f I open frmClient directly form Switchboard I don't get the error). frmClient has a subform (continuous) frmFormsList which derives its data from:
SELECT tblForms.ClientLookup, tblForms.Issued, First(tblForms.RefNo) AS FirstOfRefNo, Last(tblForms.RefNo) AS LastOfRefNo, Count(tblForms.RefNo) AS CountOfRefNo, tblClient.KnownAs, tblClient.EMail
FROM tblForms INNER JOIN tblClient ON tblForms.ClientLookup = tblClient.ClientID
GROUP BY tblForms.ClientLookup, tblForms.Issued, tblClient.KnownAs, tblClient.EMail
HAVING (((tblForms.Issued) Is Not Null));
This function resides in frmFormsList:
Public Function NumRecs() As Integer
NumRecs = DCount("*", "tblForms", "ClientLookup = " & Me.ClientLookup)
End Function
My query shows data where I have issued forms to a client. Therefore if I have not issued forms to a Client tne the query shows nothing for that client so does not give a result 0. I get RunTime Error 2427 "You entered ans expression that has no value". NumRecs = DCount("*", "tblForms", "ClientLookup = " & Me.ClientLookup) is highlighted in debug.
In frm Disclosure, if I Rem out ", acNormal, "", "[ClientID]= " & Me.Client, , acNormal" the problem does not occur, but I don't get straight to the Client I am interested in. So the problem occurs when I try to open a form using the Rem'd out bit where the client has not been issued with any forms. When I opne the frm Client directly the rocord presented does not have forms issued but the problem does not occur.
Here's the solution:
Public Function NumRecs() As Integer
Dim dbs As DAO.Database
Dim rs As Object
Set dbs = CurrentDb
Set rs = dbs.OpenRecordset("qryDisclosure", dbOpenDynaset)
If Me.Recordset.RecordCount = 0 Then
NumRecs = 0
Else
NumRecs = Nz(DCount("*", "qryDisclosure", "ClientLookup = " & Me.ClientLookup), 0)
End If
End Function

compile error: expected end of statement

A Microsoft Access 2010 database is giving me the following error message:
Compile Error: Expected End Of Statement
Here is the method that is throwing the error message:
Private Sub Form_BeforeUpdate(Cancel As Integer)
'Provide the user with the option to save/undo
'changes made to the record in the form
If MsgBox("Changes have been made to this record." _
& vbCrLf & vbCrLf & "Do you want to save these changes?" _
, vbYesNo, "Changes Made...") = vbYes Then
DoCmd.Save
Else
DoCmd.RunCommand acCmdUndo
End If
Dim sSQL As String
sSQL = "SELECT max(Clients.ClientNumber) AS maxClientNumber FROM Clients"
Dim rs As DAO Recordset
Set rs = CurrentDb.OpenRecordset(sSQL)
MsgBox ("Max client number is: " & rs.Fields(1))
End Sub
The line of code that is throwing the error message is:
Dim rs As DAO Recordset
I am not sure if the problem has to do with the syntax of what is on the line preceding it. Can anyone show how to fix this problem? And explain what is going on?
You are missing a full stop (period) between the DAO and the Recordset - it should be
Dim rs As DAO.Recordset
Beyond that, you will also have a runtime error on reading the field value, since a DAO Fields collection is indexed from 0, not 1. Hence, change the penultimate line to this:
MsgBox ("Max client number is: " & rs.Fields(0))
Alternatively, reference the field by its name:
MsgBox ("Max client number is: " & rs!maxClientNumber)
You're mising the semicolon at the end of your Sql statement

Auto Populate Access Form using simple VBA code by setting a variable

I was recently given the task of creating a form that will autofill with the information from a table. The information the form autofills is selected using a primary key called ModID. I have a combo box that has a List of the ModIDs that are listed as Active.
SELECT ModID
FROM P_Review
WHERE Status = "Active"
Simple enough. I then have VBA code running on the event After Update. So after the value for the combo box is select or changed it will run this VBA code.
Option Compare Database
Option Explicit
Private Sub selectModID_AfterUpdate()
'Find the record that matches the control.
On Error GoTo ProcError
Dim rs As Object
Set rs = Me.RecordsetClone
With rs
.FindFirst "ModID=" & Me.selectModID
If Not .NoMatch Then
Me.Bookmark = .Bookmark
Else
DoCmd.RunCommand acCmdRecordsGoToNew
Me!localModID = Me.selectModID.Column(0)
End If
End With
ExitProc:
Exit Sub
ProcError:
MsgBox "Error: " & Err.Number & ". " & Err.Description
Resume ExitProc
End Sub
The code runs fine (I get no errors when I debug or run).
Now for the access text box. I would like to populate certain fields based off the variable localModID. I have a dlookup in a text box to find the information in the table P_Review.
=DLookUp("Threshold","P_Review","ModID =" & [localModID])
So the DlookUp should find the value for the column threshold, in the table P_Review, where the ModID in P_Review equals the localModID set in the VBA code. But when I go to form view and select a ModID I get the Error 3070: The Microsoft Access database engine does not recognize as a valid field name or expression. I did copy this code from another database we are already using but it fails in this new instance.
Private Sub ModID_AfterUpdate()
Dim rs As Object
Set rs = Me.RecordsetClone
With rs
.FindFirst "ModID='" & Me.ModID & "'"
If Not .NoMatch Then
Me.Bookmark = .Bookmark
Else
DoCmd.GoToRecord , , acNewRec
Me!ModID = Me.ModID
End If
End With
End Sub
This is the answer to question. I used this code to auto update.
Try
Forms!<whatever_this_form_name_is>![localModID]
in your DLOOKUP

What are the Access startup properties that can be changed using VBA

I have an app that uses the following procedure to change some of the Current DB properties.
Public Sub SetStartupOptions(propname As String, propdb As Variant, prop As Variant)
On Error GoTo Err_SetStartupOptions
'Set passed startup property.
'some of the startup properties you can use...
' "StartupShowDBWindow", DB_BOOLEAN, False
' "StartupShowStatusBar", DB_BOOLEAN, False
' "AllowBuiltinToolbars", DB_BOOLEAN, False
' "AllowFullMenus", DB_BOOLEAN, False
' "AllowBreakIntoCode", DB_BOOLEAN, False
' "AllowSpecialKeys", DB_BOOLEAN, False
' "AllowBypassKey", DB_BOOLEAN, False
Dim dbs As Object
Dim prp As Object
Set dbs = CurrentDb
If propname = "DBOpen" Then
dbs.Properties("AllowBreakIntoCode") = prop
dbs.Properties("AllowSpecialKeys") = prop
dbs.Properties("AllowBypassKey") = prop
dbs.Properties("AllowFullMenus") = prop
dbs.Properties("StartUpShowDBWindow") = prop
Else
dbs.Properties(propname) = prop
End If
Set dbs = Nothing
Set prp = Nothing
Exit_SetStartupOptions:
Exit Sub
Err_SetStartupOptions:
Select Case Err.Number
Case 3270
Set prp = dbs.CreateProperty(propname, propdb, prop)
Resume Next
Case Else
Dim ErrAns As Integer, ErrMsg As String
If ErrChoice = vbYesNoCancel Then
ErrMsg = Err.Description & ": " & Str(Err.Number) & vbNewLine & "Press 'Yes' to resume next;" & vbCrLf & _
"'No' to Exit Procedure." & vbCrLf & "or 'Cancel' to break into code"
Else
ErrMsg = Err.Description & ": " & Str(Err.Number) & vbNewLine & "Press 'Yes' to resume next;" & vbCrLf & _
"'No' to Exit Procedure."
End If
ErrAns = MsgBox(ErrMsg, _
vbCritical + vbQuestion + ErrChoice, "SetStartupOptions")
If ErrAns = vbYes Then
Resume Next
ElseIf ErrAns = vbCancel Then
On Error GoTo 0
Resume
Else
Resume Exit_SetStartupOptions
End If
End Select
End Sub
procedure can be used to add and set values for DB.properties, These are the properties that are set in the Access options screen. I have a limited list of property names but, does anyone know where I can find the full list of properties that are recognized? ( i.e. the startup form name, start up ribbon name,... )
You can list all of the properties for the database that exist at the time you run the code using a very simple procedure as seen here.
Public Sub ListDBProps()
Dim db As Database
Dim prp As Property
Set db = CurrentDb
For Each prp In db.Properties
Debug.Print prp.Name
Next prp
End Sub
There are a couple of gotcha's in this. Notice I said "that exist at the time you run the code". That is, Access creates properties for the database (and presumably other objects as well) on an "as needed" basis. For instance, when you compile the database into, what used to be called an MDE, now an ACCDE, Access will add a new property of Type "Text" [10] named "MDE" with a value of "T". There are a couple of properties in the list you provided that fall into this category as well, such as "AllowBypassKey" and "AllowBreakIntoCode".
Here is the list that I got when I ran this code on a simple database I opened up:
Name
Connect
Transactions
Updatable
CollatingOrder
QueryTimeout
Version
RecordsAffected
ReplicaID
DesignMasterID
Connection
ANSI Query Mode
Themed Form Controls
AccessVersion
NavPane Category
UseMDIMode
ShowDocumentTabs
Build
CheckTruncatedNumFields
ProjVer
StartUpShowDBWindow
StartUpShowStatusBar
AllowShortcutMenus
AllowFullMenus
AllowBuiltInToolbars
AllowToolbarChanges
AllowSpecialKeys
UseAppIconForFrmRpt
AllowDatasheetSchema
Show Values Limit
Show Values in Indexed
Show Values in Non-Indexed
Show Values in Remote
Auto Compact
DesignWithData
Picture Property Storage Format
NavPane Closed
NavPane Width
NavPane View By
NavPane Sort By
Track Name AutoCorrect Info
Perform Name AutoCorrect
HasOfflineLists
You can add the Type property to your output easily enough. It is an integer value corresponding to the DataTypeEnum enumeration. The Value property of the Property can be a little more tricky. Usually it's a value that can be easily converted to a string value but there are a couple that cause a runtime error when you try to print them out or store them in a String variable. A little error handling in a small function can handle that with no trouble.
My example was run on an ACCDB in Microsoft Access 2007.
Enjoy . . . Doug