Conditional Formatting via VBA MS Access Report not working - ms-access

I am having a trouble while trying to conditionally format the exhibition of records in a report inside a MS Access 2007 form.
I have search the Internet and I have seen lots os fellows stating that it is possible to perform visual changes in a single record via code implementing the method Detail_Paint() for the event Paint of the Detail section in a Report. Those people say that something like this is going to work:
Private Sub Detail_Paint()
val = CStr(Me.someTextBox.Value)
If val = "constraint" Then
Me.lineStrikethrough.BorderStyle = 0
End If
End Sub
The problem is that although the reading statement Me.someTextBox.Value returns the value of each record when the Paint event is thrown, the writing statement Me.lineStrikethrough.BorderStyle = 0 writes the value of the property BorderStyle for every single line in my report, not only for the one respecting the single record whose value I read from someTextBox field.
Can anyone tell me why such is happening? If this is the correct behaviour (although it does not seem right to me), how can I achieve my goal?
Note: lineStrikethrough is used to perform a strikethrough effect over the record in a Report. If there is another way to do that I would be happy to know.

Two things:
1 - Use the Detail's On Print event and not On Paint event.
Private Sub Detail_Print(Cancel As Integer, PrintCount As Integer)
val = CStr(Me.someTextBox.Value)
If val = "constraint" Then
Me.lineStrikethrough.BorderStyle = 0
End If
End Sub
2 - To see the conditional formatting, always open your report in Print Preview and not Report View.

You are really close!! :-) In my testing, it appears that the Detail_Paint() event allows you to change the formatting of controls, but changes will continue in subsequent records until you change/reset them to something else.
In your code sample, you just need to add another line to turn the strikethrough BorderStyle back on when the condition is no longer met.
Private Sub Detail_Paint()
Val = CStr(Me.someTextBox.Value)
If Val = "constraint" Then
Me.lineStrikethrough.BorderStyle = 0
Else
Me.lineStrikethrough.BorderStyle = 1
End If
End Sub
I found this clue on a code sample on MSDN which demonstrates conditional formatting using the Detail_Paint() method.

I found that Select Case to work best in the detail paint over if statements for a continuous form.
'Private Sub Detail_Paint()
Select Case CStr(Me.someTextBox.Value)
Case "constraint"
Me.lineStrikethrough.BorderStyle = 0
Case Else
Me.lineStrikethrough.BorderStyle = 1 'or what the default value is
End Select

Related

vba in access and conditional formatting of forms

I have a form that collects different types of data. One of them is the type of document. On accessing the tab the user has to select a type of document, from a pull-down list. If the document is selected as "NDA", then a tab named "type of NDA" must be enabled. The following is the code I am trying to use:
Private Sub doc_AfterUpdate()
If doc.Value="NDA" then
tnda.enabled=true
else
tnda.enabled=false
End if
End Sub
The pgm is simple, yet whenever I run my forms it keeps showing "error:type mismatch" and the code stops working.
Thanks for helping me with the above code.
This time i tried the code on a little more complicated form with more options. I tried to disable all the other options and enable them only according to the options i choose(from "type of document" tab in the form).Given below is the code:
Private Sub doc_BeforeUpdate(cancel as integer)
tnda.enabled=false
tagr.enabled=false
odoc.enabled=false
End Sub
Private Sub doc_AfterUpdate()
Select Case doc.column(1)
Case "NDA"
tnda.enabled=true
Case "Agreement"
tagr.enabled=true
Case "Other"
odoc.enabled=true
Case Else
End Select
End Sub
Private Sub doc_Oncurrent()
Select Case doc.column(1)
Case "NDA"
tnda.enabled=true
Case "Agreement"
tagr.enabled=true
Case "Other"
odoc.enabled=true
Case Else
End Select
End Sub
After running the pgm, all my tabs remain disabled irrespective of the choice of doc. Please provide valuable inputs in this regard.
Note tnda:type of NDA
tagr:type of agreement
odoc:Other document and doc=type of document Find image of my form here
It's because Doc is a combobox, thus probably bound to an ID that is numeric.
So either:
If doc.Value = <insert value of ID of text "NDA"> then
or use the column ID that holds "NDA", most likely the next:
If doc.Column(1) = "NDA" then

Access VBA - Turn off aggregation when opening form/sub-form

What I'm trying to do is, whenever a user opens a form (and the sub-form that opens by default), I want to search through all the columns (controls?) on the form, check to see if they are currently set to aggregate (sum, count etc.) with Access' built-in Totals row, and if so, set them to not aggregate.
The reason for this is there are several millions records that are stored, so when someone queries it down to 3-4 and turns on Sum, then closes it, when the next person opens it, it tries to sum millions of numbers and freezes up. The form displays the queried results from a table which is populated via SQL (I think, if that sentence makes sense). Here's what I have so far:
Private Sub Form_Load()
'this form_load is in the UserApxSub sub-form, for reference
Call De_Aggregate
End Sub
Private Sub De_Aggregate()
Dim frm As Form, con As Control
Set frm = Forms!UserAPX!UserApxSub.Form!
For Each con In frm.Controls
If con.ControlType = acTextBox Then
If con.Properties("AggregateType").Value <> -1 Then
'crashes on following line
con.Properties("AggregateType").Value = -1
End If
End If
Next con
End Sub
I have not so much experience in Access VBA (usually work in Excel VBA) so please forgive me if I'm entirely off the mark here. The command con.Properties("AggregateType").Value = -1 doesn't throw an error, but Access just straight-up crashes when reaching that line specifically.
I've tried a number of variations in the syntax with no success, and I've also tried looping through other elements of the file (tabledefs, querydefs, recordsets, etc.) as well to see if I'm trying to change the wrong value, but the controls on this subform are the only things in the entire .mdb file that results when I search for elements with the AggregateType property.
I switched out the line that errors with Debug.Print con.Name & " - " & con.Properties("AggregateType").Value and I can check, have nothing return anything other than -1, turn on aggregation in some column manually, and have it return the correct result (0 for sum for example), so I think I'm looking in the right place, just missing some key factor.
I've been working on this for a couple weeks with no success. Any way to fix what I have or point me toward the right direction would be greatly appreciated!
This is not necessarily the answer but I don't have enough reputation
to give a "comment"...
I tried your scenario and verified can change the property value as you are however I did not iterate through all controls and simply used an onDoubleClick event on a column to simulate.
I would suggest trying to fire your sub with Form_Open or Form_Current to see if the property is getting reset after your code has been called for some reason.
UPDATE:
You are referencing the "Subform" Object of your main Form:
Set frm = Forms!UserAPX!UserApxSub.Form!
Try referencing the actual UserApxSub FORM explicitly.
Something like Set frm = Forms!UserApxSub! (assuming UserApxSub is the name of the form)
then stick in the Form_Open of your main form:
Private Sub Form_Open(Cancel As Integer)
'// the following would set a single control only. You can add your loop through all controls
Me!{your control name}.Properties("AggregateType").Value = -1 '// set control in your main form
Form_UserApxSub!{your control name}.Properties("AggregateType").Value = -1 '// set control in your "sub" form
End Sub

If value is nothing, do something

I use a report in MS Access which displays records out of a database based on dates (given by the user).
I seem to having some trouble using my If Else statement when the Report is loading. I have one row in the database named BDatGift90. Sometimes, this value may be empty for a record. In that case, I want to use the If Else statement.
My If Else statement is:
Private Sub Report_Open(Cancel As Integer)
If IsNull(BDatGift90.Value) Then
Me.GBedrag10.Visible = True
Else
Me.GBedrag.Visible = True
End If
End Sub
The report is not loading at all. The text boxes GBedrag and GBedrag10 are not visible and I would like to use my If Else statement to decide what text box has to be visible.
Can I use some error reporting somewhere or is my if else wrong? I could use some explanation from somebody.
You check the BDatGift90 while the report is opening. But is BDatGift90 one column in the recordsource of the record? If yes, which row of the recordsource is being checked by your if else statement? I'm asking because Report_Open() is called only once. In contrast, an event like GroupHeader1_Format()is called several times, and the values are stepping forward through the recordsource each time.
So, one approach is to clarify the life cycle of BDatGift90. Another approach is to set a breakpoint and to inspect BDatGif90 (VBE > Debug > Add Watch...). Is it null, is it empty, nothing or ""?
Here is an interesting check for zero-length string in textboxes: Proper way to check if an unbound control has a value
And here are more hints about isEmpty(), isNothing() etc. http://allenbrowne.com/vba-NothingEmpty.html
Hope this helps :-)
Corresponding to your question, try this:
Private Sub Report_Open(Cancel As Integer)
If BDatGift90.Value Is Nothing Then
Me.GBedrag10.Visible = True
Else
Me.GBedrag.Visible = True
End If
End Sub

How to get values in a report, like in a form?

here is my situation:
I have a report that is displaying several values like the expected value and the obtained value. I would like to display an alert when the expected is over the obtained. This kind of manipulation is straightforward in a form:
If expectedCtrl > obtainedCtrl Then alertCtrl = "PROBLEM"
The problem is that in a report, its continuous aspect makes it impossible to get the expectedCtrl and obtainedCtrl values that way. Does anybody know the right way to perform this simple task ?
Thank you very much for your help, I'm really stuck on it and I don't have much time...
Just create an unbound control and set an expression for the control data source. Something like this...
=iif(expectedCtrl>obtainedCtrl, "PROBLEM","")
Alternatively you can use the Conditional Formatting feature and define a condition to change the color, for example, of the obtainedCtrl field if it is greater than the expectedCtrl.
I believe you need to set up some code for one of the events in the Detail section of the report. In the report's design view, right-click 'Detail', then properties, and check its events. This will allow you to run code for each detail record that shows up on the report.
You need to include both If and Else. For a picture, I suggest you set the visible property, say:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
If expectedCtrl > obtainedCtrl Then
Me.PicAlert.Visible = True
Else
Me.PicAlert.Visible = False
End If
End Sub
Or more simply:
Private Sub Detail_Format(Cancel As Integer, FormatCount As Integer)
Me.PicAlert.Visible = (expectedCtrl > obtainedCtrl)
End Sub

Access Report won't allow me to refer to a field in VBA unless it's on the report in its own right

So, in an Access Form or Report a good way to show something dynamic on the screen that is more complex than =[UnitPrice]*[Quantity] is to drop into VBA.
e.g. in this simplified example, the underlying table for this Report has two fields ShowTax and TaxRate. By making a TextBox's control source =GetTaxInfo I get to introduce some complexity in VBA:
Public Function GetTaxInfo() As String
Dim result As String
If Me!ShowTax = 0 Then
result = "Tax included # " & Me!TaxRate
Else
result = ""
End If
GetTaxInfo = result
End Function
OK, this works ... so long as I have a field somewhere else that refers to TaxRate. Otherwise it just prints #Error. It's as if it needs to preload the field before it can be used in VBA code. It isn't the end of the world because I can have a bunch of fields in the report all set to not be visible, but it's untidy.
So is it the case that you can't refer to a field in VBA code backing a report unless you have already referred to the field in the conventional way as a field baked into the report?
I can't remember encountering this limitation before. Or is it that I have a corrupt report? (I have tried the usual compact/repair, export/reimport the Report etc)
Edit:
the weird thing is ... now it's working again. And - I'm pretty sure - there is no control in the report. which is why I was thinking it was a corruption in the report.
You'll need a control on the form/report.
If this is too messy, you could put the function in a Module and use in the RecordSource (based on a query). No sense burying all this logic in a report when it could be used in other places as well.
Public Function GetTaxInfo(ShowTax as Boolean, TaxRate as Single) As String
Dim result As String
If ShowTax = 0 Then
result = "Tax included # " & TaxRate
Else
result = ""
End If
GetTaxInfo = result
End Function
Then the control is set to this field in this report and others.