Access Report Detail Format - Default Values and Referencing - ms-access

This question is mainly for curiosity, but also, in the description, I had intended to highlight an infrequently documented behavior of Access.
Background
When creating an Access report, we can use the On Format method of the detail section to modify values or properties per-record. For example, assume we want to hide a field label when the value is empty:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
If (IsNull(Me.SomeField) Or Me.SomeField = "") Then
Me.SomeFieldLabel.Visible = False
Else
Me.SomeFieldLabel.Visible = True
End If
End Sub
What I did not realize about this until today is that the assignment .Visible = False does not modify the instance of the label in the Detail section, but rather is modifying the definition of the label on the report.
This can be demonstrated with the following modifiction to the code:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
If (IsNull(Me.SomeField) Or Me.SomeField = "") Then
Me.SomeFieldLabel.Visible = False
End If
End Sub
Assuming the label is initially visible (in form Designer), the event produces somewhat unexpected behavior: the label will remain visible until the first empty record; after that, it will remain hidden for all other records - I had originally expected that at each call of Detail_Format the controls where starting with their default definitions.
Question
Is there any way to reference the particular instance of a control within the Detail_Format event?
In this simple case of visible true/false, this is easily handled by just a simple if-then-else, but I can imagine more advanced scenarios where one might want to leave the default values in tact.

I don't believe so, in all of my experience, properties of report objects always apply universally across the report, not to specific instances of the abject (if the object is repeated).
For your example, I would use a text box instead of a label to label the field, and use something like =IIf(IsNull(Field1), "", "Label:") for the controlsource. That way it won't show anything if the field is null, yet still show the label text if there is a value.

Related

Concatenate Rich Text Fields (HTML) and display result on Access form

I have an access database which deals with "articles" and "items" which are all textual stuff. An article is composed of several items. Each item has a rich text field and I wish to display the textual content of an article by concatenating all rich text fields of its items.
I have written a VBA program which concatenates the items rich text fields and feeds this into an independent TextBox control on my form (Textbox.Text = resulting string) but it does not work, I get an error message saying "this property parameter is too long".
If I try to feed a single textual field into the Textbox control, I get another error stating "Impossible to update the recordset" which I do not understand, what recordset is this about ?
Each item field is typically something like this (I use square brackets instead of "<" and ">" because otherwise the display of the post is not right) [div][font ...]Content[/font] [/div]", with "[em]" tags also included.
In front of my problem, I have a number of questions :
1) How do you feed an HTML string into an independent Textbox control ?
2) Is it OK to concatenate these HTML strings or should I modify tags, for example have only one "[div]" block instead of several in a row (suppress intermediate div tags) ?
3) What control should I use to display the result ?
You might well answer that I might as well use a subform displaying the different items of which an article is made up. Yes, but it is impossible to have a variable height for each item, and the reading of the whole article is very cumbersome
Thank you for any advice you may provide
It works for me with a simple function:
Public Function ConcatHtml()
Dim RS As Recordset
Dim S As String
Set RS = CurrentDb.OpenRecordset("tRichtext")
Do While Not RS.EOF
' Visually separate the records, it works with and without this line
If S <> "" Then S = S & "<br>"
S = S & RS!rText & vbCrLf
RS.MoveNext
Loop
RS.Close
ConcatHtml = S
End Function
and an unbound textbox with control source =ConcatHtml().
In your case you'd have to add the article foreign key as parameter to limit the item records you concatenate.
The "rich text" feature of a textbox is only intended for simple text.
We use the web browser control to display a larger amount of HTML text, and load it like this:
Private Sub Form_Current()
LoadWebPreview
End Sub
Private Sub HtmlKode_AfterUpdate()
LoadWebPreview
End Sub
Private Sub LoadWebPreview()
' Let the browser control finish the rendering of its standard content.
While Me!WebPreview.ReadyState <> acComplete
DoEvents
Wend
' Avoid the pop-up warning about running scripts.
Me!WebPreview.Silent = True
' Show body as it would be displayed in Outlook.
Me!WebPreview.Document.body.innerHTML = Me!HtmlBody.Value
End Sub

How to check whether a combobox selection contains specific text or word

My combobox has 5 values, and three of them contain a particular word that, if selected, should enable two other controls on the form that would be otherwise disabled. I already figured out how to enable/disable the controls but im trying to figure out the correct syntax for the code that would check if these values are selected or not, but cannot find a clear format of code. Please help.
If your combobox only has 5 values and is limited to those 5 values, then just use the whole value and not the containing word.
private sub cmb1_AfterUpdate()
if me![cmb1].value ="value1" Or me![cmb1].value ="value2" Or me![cmb1].value ="value3" then
me!txtbox.enabled = true
else
me!txtbox.enabled = false
end if
end sub

MS Access de-select listbox after running macro/query

So I have a form (frmBookingForm) in Access, and a listbox (lstMyBookings) that displays the results of a query.
Below this, I have a button (cmdDeleteBooking) which runs a delete query using the lstMyBookings selection as input. The button then runs a macro that firstly checks whether a record in the listbox is selected, and if one is, runs the delete query and requeries the data, so the deleted record is no longer shown in the listbox. If not, an error message is displayed.
However, if I then click the button again, it again runs the delete query, even though there is apparently nothing selected in the list box.
Essentially, how can I 'clear' the listbox selection?
I'd prefer a solution that can be done in a macro format, as I have little to no understanding of VBA. However, if providing a VBA solution, I'd greatly appreciate a short explanation of it.
Thanks :)
Looks like this website has a nice little function to do it. Essentially, you need to test if it's a multiselect, and then do one of two things. I suppose if you know ahead of time that it is/isn't a multiselect, you wouldn't even need the "if" statement:
If List0.MultiSelect = 0 Then
List0 = Null
Else
For Each varItem In List0.ItemsSelected
List0.Selected(varItem) = False
Next
End If
If the control's MultiSelect property is set to None, this code just sets List0 to Null. If the control's MultiSelect property is set to anything else, the code loops through all items that are currently selected, and sets the Selected property of that item to False. My example assumes your control is called List0.
EDIT
To use this code, use an event instead of a macro. Here's how you do this:
Right click on the button, select properties
In the Property Sheet window, click on the "Event" tab
Click inside of the "On Click" blank area, and click the dropdown arrow, then select "[Event Procedure]"
Click the ellipsis ("...") to go into the code editor.
In the code editor, your should already have your event for the button (let's assume the button is called Command1:
Private Sub Command1_Click()
End Sub
Add your code in between (assuming the listbox is called List0):
Private Sub Command1_Click()
If List0.MultiSelect = 0 Then
List0 = Null
Else
For Each varItem In List0.ItemsSelected
List0.Selected(varItem) = False
Next
End If
End Sub

How to reference a button in Do While within an If Else statement in VBA Access

I'm a newbie to VBA, and will try to make my question clear. I want to add another If Else statement to say when the button OR is clicked, it should to certain stuff else other. So my question is do I have to code anything within Private Sub OR_Click() ... End Sub first then reference it in my new If Else statement?
If .RecordCount > 0 Then
.MoveFirst
Do While Not .EOF
If Filter Is Nothing Then
Set Filter = XFormToFilter.FilterBuilder
Filter.SetPrimaryFilter PrimaryFilter, primaryTable, primaryKey
End If
'This is where I want the button to go
Filter.AddSubFilter "Filter" & .fields("ID"), _
filterString, targetTable, subformDict(targetTable)
.MoveNext
Loop
End If
Thanks a bunch!
You should have created a toggle button in the form designer (not a standard button). Every control has a generic Name which Access will set unless you change it -- something like ToggleButton115. You can then write code within the filter handler like this:
If ToggleButton15 Then
'OR option has been set; change the filter appropriately
Else
'OR option has not been set
End If
NB: This works because the togglebutton's Value property is True or False depending on whether it has been toggled or not. The Value property is the default property -- the property VBA assumes you want to use when you don't specify a property on an object.
See here for more details.

Access: Display Textbox Control In Sub-report when it has No Data

In a subreport I created a sub on detail_format event that will display a text when there is no data returned.
‘Code in sub-report
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
If Me.Report.HasData Then
Me.Label43.Visible = True
Me.txtNotEntered.Visible = False
Else
Me.Label43.Visible = True
Me.txtNotEntered.Visible = True
End If
End Sub
It works fine on the subreport when run alone. When I run the main report it doesn’t trigger.
I added the same code in the main report to see if it would work. It runs through the lines of code but still cannot see the txtNotEntered textbox control.
‘Code in main report
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
If Me!rptResults_Comments.Report.HasData Then
Me!rptResults_Comments.Report.Label43.Visible = True
Me!rptResults_Comments.Report.txtNotEntered.Visible = False
Else
Me!rptResults_Comments.Visible = True
Me!rptResults_Comments.Report.Label43.Visible = True
Me!rptResults_Comments.Report.txtNotEntered.Visible = True
End If
End sub
I am using MS Access 2003.
Since the subreport is bound to the main report, the subreport itself will not be shown if there is no data to connect it to the main report. You can see this better by setting the background color of the subreport's detail section to red, or any other non-white color.
One workaround is to move your txtNotEntered control to the main report and put it "under" the subreport control (using Send to Back). Then set your subreport control's Can Shrink property to True.
Then, when there is data in the subreport you will see the subreport and it will cover the txtNotEntered control. When there is no data, the subreport will shrink out of the way and you will be able to see the txtNotEntered control.
One advantage to this approach is that it requires no code. Just leave the txtNotEntered Visible property set to True. The shrinking of the subreport will take care of revealing it when appropriate.
In addition to the answer from mwolfe02, I would suggest instead of using a label and VB code use a textbox with the following expression:
=IIf([HasData],"","No data found")
I use this on all my reports. An expression like
=IIf([rptResults_Comments].[Report].[HasData],","No data found")
should work as well. I didn't test the latter expression, so I'm not sure if [Report] is needed or not.
In addition to #rick's problem, how to display "No data" text when a subreport has No Data, it is also common enough to want to handle the case where main report controls reference subreport controls (and the subreport(s) has(have) No Data). This might occur when you are calculating a total that references subtotals from many subreports.
So we can put together #mwolfe02's and #TheOtherTimDuncan solutions (repurposing from #TheOtherTimDuncan his use of the HasData property), with some incidental additions of my own, as a checklist.
We have a main report rptMain and a subreport srpSub. In rptMain, detail section, we have a subcontrol sbctSub which references srpSub.
On rptMain create a label (there's no general need for it to be a textbox) lblNoData with whatever text you like (e.g. "No Data Returned"). Place lblNoData under sbctSub (using Send to Back). Use the same Top value. This ensures these don't overlap vertically so problems don't occur when Shrinking/Growing occurs.
Add an "annotating" label that is always viewable by a developer in design view but is permanently set to Visible = No (which makes it invisible in non-design views) with text like "Hidden lblNoData under subcontrol". If this needs to shrink (Can Shrink = Yes) then make it an unbound textbox. Colour such an annotating label (or textbox) to stand out in design view (e.g. I generally use a blue). Otherwise, down the track, there's a danger of losing sight, as a developer, of what's going on (worse still if another developer has to analyze your work).
Ensure the following are set to Can Shrink = Yes:
rptMain, Detail.
sbctSub.
When srpSub has no data then lblNoData will be revealed to the user as sbctSub will have shrunk to zero.
In production there might be issues with the No Data label showing through (white backgrounds seem to act transparently in some circumstances). If so, in rptMain:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Me.lblNoData.Visible = (Not Me.sbctSub.Report.HasData)
End Sub
(My "design spike" testing worked as #mwolfe02 mentioned. That is, no additional code was necessary and I could rely on the subcontrol to hide and reveal the No Data label as needed. However my production report had these weird transparency issues.)
If you have any control on rptMain (e.g. txtGrandTotal) that references a control on srpSub, then set the control source as follows
=IIf([sbctTemp].[Report].[HasData],[sbctTemp].[Report]![txtSubTotal],0)
Null to zero Nz() won't work where the referenced control doesn't even exist, due to the subreport returning no data.
Edit 01: Added additional code to hide and show the No Data label in case of transparency issues. Rearranged this from being listed the last step, to being listed more sensibly in the order.
Edit 02: Made mention that the annotating label should be a textbox if it needs to shrink.