I'm familiar with programming in general but not with Access forms or VBA.
I have the conditional formatting working. Now I need to make it respond to the result of a custom VBA function.
Let's say there is a limit, based on the customer, to how many times something can happen.
The label will show the count, "Trip 3 of 5".
When we get to 5 of 5 it should be yellow and 6 of 5 should be red.
Note that I want the conditional formatting rules to be in Access, not in VBA. VBA just returns the value we test in the condition.
I don't see how to use the result of a VBA function in the conditional formatting expression, but it seems like you can use variables.
I tried
TripCountValid: GetTripCountValid(ID)
and then used TripCountValid in my condition, but that didn't seem to work.
GetTripCountMsg and GetTripCountValid are in the Orders module because that is where GetBillAcctMsg is, which I am emulating.
I could move it to the code-behind for the form.
My MsgBox in GetTripCountMsg gets called but not the one in GetTripCountValid.
A function can be referenced in Conditional Formatting. Use the Expression Is: option. Assuming your function returns a Boolean (True/False), the CF rule would simply be:
Expression Is: GetTripCountValid([ID])
Set the desired formatting to display if the function returns True. Or if you prefer to change display for False:
Expression Is: NOT GetTripCountValid([ID])
If those expressions are not explicit enough use = sign with whichever Boolean value you prefer.
Expression Is: GetTripCountValid([ID]) = True
If function returned something other than Boolean, use the last syntax to compare with whatever parameter appropriate for situation. The point is, the expression must evaluate to True or False.
Related
Hello I'm fairly new to SSRS and I'm working on making my first report for work. It has been going fine until today when I needed make a textbox in Tablix handle both a numbers calculation and text. A column in my SQL table that was previously a purely number field now has n|a for certain rows. So I wrote the following expression to handle those n|as. When the proceeds field is numeric the formula works, but when it's an n|a it shows up on the report as #error and I can't figure out why. I've removed all formatting from the textbox to the same result.
=IIF(Fields!Proceeds.Value<>"n|a",Fields!Proceeds.Value / Fields!DealBalance.Value,"n|a")
As TnTinMn explained, IIF always evaluates both the true and false part of the expression.
The simple fix is to do something like
EDIT Revised due to update from OP
=IIF(Fields!Proceeds.Value<>"n|a",VAL(REPLACE(REPLACE(Fields!Proceeds.Value,",",""),"$","")) / Fields!DealBalance.Value,"n|a")
This simply strips out the $ symbol and commas and then converts the text to a number using VAL(), if the text is not a number it will return zero which will not cause an error as the false part of your expression would give 0/DealBalance.
I have a spreadsheet formula in which I use exactly the same FILTER function twice inside an INDEX function. Is there any way to avoid repeating myself, and/or a simpler version of the expression?
The expression looks like this (separated into multiple lines for a tiny bit of extra clarity):
=INDEX(
FILTER($A$1:$P$1, ($A$1:$P$1 = "ANIM")+($A$1:$P$1 = "COMP")+($A$1:$P$1 = "SENT TO EDIT"),
NOT (ISBLANK(A2:P2))),
COLUMNS(
FILTER($A$1:$P$1, ($A$1:$P$1 = "ANIM")+($A$1:$P$1 = "COMP")+($A$1:$P$1 = "SENT TO EDIT"),
NOT (ISBLANK(A2:P2)))))`
What the expression does is return the heading of the rightmost non-blank column in the row, so long as the column is one of ANIM, COMP, or SENT TO EDIT.
See the formula in action in column Q of this Google Sheets.
Since the FILTER function is exactly the same both times, if I could use a variable, it could be re-written something like this:
range1 = FILTER(.....); INDEX(range1, COLUMNS(range1));
Is there any way to do something like that - or an equivalent - in order to avoid repeating my FILTER expression?
You have the right idea, the way to avoid repeating long subformulas is to move them out of the formula and call the result someway. On certain cases you could use a reference to the range that displays the result but for formulas that returns a dynamic array, a custom function could be a better alternative.
Example:
Let say that you move out
FILTER($A$1:$P$1, ($A$1:$P$1 = "ANIM")+($A$1:$P$1 = "COMP")+($A$1:$P$1 = "SENT TO EDIT"),
NOT (ISBLANK(A2:P2)))
to dry!A1 (don't forget to prepend it with =)
The following is just a "mcve". It assumes that te dry sheet only contains the above formula:
function headers(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets().getSheeyByName('dry');
return sheet.getDataRange().getValues();
}
Replace your original formula for the following:
=INDEX(headers(dry!A1:P1),COLUMNS(headers(dry!A1:P1))
Note: The use of dry!A1:P1 as arguments of headers() is to force it's recalculation every time that the result for the subformula changes.
See also: Is there a way to evaluate a formula that is stored in a cell?
You could try something like this:
=REGEXEXTRACT(JOIN("|",FILTER($A$1:$P$1, Regexmatch($A$1:$P$1,"ANIM|SENT TO EDIT|COMP"), NOT (ISBLANK(A2:P2)))),"([^|]+)$")
Using regular expressions is a way to handle arrays like a text.
What you are looking for is called a temporary variable, and last I checked, Google sheets doesn't support temporary variables (https://webapps.stackexchange.com/questions/71095/how-to-save-temporary-variables-in-google-sheets-formula). It would be nice if they did!
Can I write a UDF in Excel VBA where the return value from the function will override the cell value from it is called from?
The function get information with a sql request. In this case it's only master data for example the item description. If the user will use this function in a worksheet in many cells excel will recalculate the cell value every time you change something. This has poor performance and normally it's only necessary to get the information one time and it hasn't to be updated in this case.
I thought to use application.caller.address method to get the address the function was called from but it seems it can't set the cell value for this address within the function.
So the return value of the function should override the original formula that run the function.
Is this possible
thanks for your help
No.
As you may have noticed Excel cells have multiple layers.
One is the "value". Another one the formula you can assign.
A funtions returns a value, therefore the return value only accesses this layer. So you cannot return a replacement for the formula cause it is on another layer.
A function differs from a sub in the return value, a sub does not return anything. Due to your behaviour of "one time usage" a sub will fit your need more than a function, because you dont want to return a value but to remove or replace certain content from cell (the formula).
However, this does not mean you cannot do this with a function - but still not with a return value. But you need to rewrite the whole formula on a data refresh if you would use such a function.
You may have missed a point that you make you laugh yourself I guess. Excel has such a thing natively. But it is not a function.
Copy your cells and paste them but use "values only".
Totally has the same effect.
Also in terms of recalculation... why not turn it off?
This would you not make to rewrite the function each time.
Using Excel VBA code, is there any way by which I can check whether a
particular cell has satisfied Conditional Formatting or not?
I have data in a single column with than 80000 cells.
I used the following code but it gives same value for Interior.ColorIndex or Interior.PatternIndex or Font.Bold irrespective of whether the Conditional Formatting is applied or not
Sub Check_CF()
MsgBox Range("B4").Interior.PatternColorIndex
End Sub
My conditional formatting rule is not important. I can change the rule if I am able to check whether it is applied or not.
Found this rather long article with example functions on the subject that might be of help to you:
http://www.xldynamic.com/source/xld.CFConditions.html
I have a very long condition, about 3,000 characters. Access has only space for about one tenth of that.
Is there some other way to set conditional formatting on a textbox besides through the dialogue, or can I do it in VBA and, if so, HOW?
I have conditional formatting on a bunch of textboxes that trigger when the report is opened.
Would be curious to know if the VBA approach worked?
Another idea: create a hidden field on the form and set it's value based on your 3000-character condition. If you are just trying to have 1 conditional expression, you could give this hidden field a false/true or 0/1 value; if you want mulitple conditions, you could give it a value of 0, 1, 2, or 3 corresponding to the conditions you want applied. In either case, your conditional expression test(s) is(are) now trivial: [HiddenFieldName]=ConditionValue
According to Access' Help topic, the FormatConditions Collection has methods (Add, Delete, Modify) which should allow you to adjust your FormatConditions with VBA code. I've never tried, so offer no opinion as to whether this would be a practical approach for you.
I also tried to find out if there is a capacity limit for the number of characters FormatConditions can accept. I didn't find anything there.
Yes, you can manipulate Format Conditions in VBA. There's a full detailed article knowledgebase article at http://support.microsoft.com/kb/304104.
Code snippet here showing a basic example. Refer to the above link to get the VBA for AddFormats:
Public Function HighLightForeignKeys(argFieldName As String, argFieldValue As Integer)
Dim FormatCondition As String
Dim CodeReception As Integer
FormatCondition = "[" & argFieldName & "] = " & ArgFieldValue
With Me.ID
.FormatConditions.Delete
.FormatConditions.Add acExpression, , FormatCondition
.FormatConditions(0).BackColor = 16510422
AddFormats Me.ID, Me
End With
End Function
I dont know if this is what you were after, since you mentioned there was only a tiny box to enter all of your conditional text. Others have shown you VBA solutions - since you asked if that was one way to achieve it.
I have always resorted to using the "zoom" feature which is accessible via the SHIFT-F2 keystroke. Is that what you were after? I think it goes back several Access versions too.
A good set of Access shortcut keystrokes is here:
http://www.joyedaniels.com/keys_access.htm