Archive for the 'Formulas' Category



Highlighting an empty string

Sunday 20 March 2022 @ 11:02 pm

One of my customers wanted to highlight all of the empty values in a string column, but still leave the highlighted space empty. I tried using a background color formula but that didn’t work. Then I remembered an article I wrote about display strings  and how you can’t force a display string to show anything when a field was empty. It seems the same thing is true about background colors.

I tried using IsNull, converting nulls to default values and even the highlight expert. The only thing that worked was to replace the field with a formula like this:

If {Table.Field} = ''
then ' ' //single space
else {Table.Field}

The second line isn’t an empty string but is a single space. Because a space is a character, Crystal will format it with a background color.




(re)Introducing the MRound() function

Sunday 6 March 2022 @ 3:51 pm

Timing is everything. In October of 2004 I added a new formula to my website. Formula #22 showed how to round a dollar amount to the nearest nickel, but could also be used to round any number to whatever increment was needed. I have used that formula many times since – including my blog post from 2 weeks ago about rounding a DateTime to the nearest 15 minutes.

Today I heard from Ido Millet of Millet Software who suggested some improvements to that blog formula. His formula used the Crystal Reports MRound() function. I had never used the MRound function so I looked it up to see what it did. It does exactly the same thing as Formula #22.

After a bit of research I found that I mentioned the MRound() function in my January 2005 Newsletter. It was one of a dozen new functions in Crystal Reports XI.  But I somehow missed the fact that it did the same thing as Formula #22, which I had posted 3 months earlier.  Today I updated Formula #22 to use the MRound() function, but I have left the original formula for users who are still using CR versions before XI.




Rounding DateTime values to the nearest 15 minutes

Thursday 24 February 2022 @ 2:49 pm

This morning a customer asked me to round a DateTime value to the nearest quarter hour. I had written this logic for them before but we couldn’t find the formula so I started from scratch. When I was done it didn’t look familiar so I suspected I had used a different approach this time.

Later we found the original formula, and it was longer and more complex. That is when I remembered writing it, and saying at the time that there had to be a more elegant approach. I must have been off that day because I couldn’t seem to find the simple solution and just wrote something that worked.  Today it clicked:

Local DateTimeVar DT := {Orders.Ship Date};
Local DateVar D := Date(DT);
Local numbervar Sec := DateDiff('s', D, DT);
DateAdd('s', Mround(Sec, 15*60), D);

And thanks to Ido Millet of Millet Software for suggesting the even better approach to this formula now shown above.




Adding an “All” option to a dynamic parameter

Sunday 19 September 2021 @ 10:05 am

If you want your parameter’s list of values to be pulled from the database you can use a dynamic parameter. But one of the down sides of a dynamic parameter is that you can’t type additional values to include in the list.  A dynamic parameter can only show values pulled from the data source. So if, for instance, you are pulling in a list of products and you want the list to have an “All” option at the top, you can’t simply add the word “All” to the list like you could with a static parameter.

My preferred way for adding an “All” option to a dynamic parameter is to use a SQL command as the source for the dynamic parameter. Using a SQL command gives you several other advantages as well, such as allowing you to filter your the list of values. Here is an example of a SQL command that will add an “All” option to the list of values (incorporating suggestions from MHurwood below):

Select Items.ID, Items.Desc
From Items
Where Items.Status = ‘A’

UNION ALL

Select ‘…All’, ‘…All’

The part above the UNION creates a list of all the active items, showing both the ID and the description of the items. The part below the UNION adds one row to the results of the query with the “All” option. Notice that “All” entry has several periods in front of it. This is one way to sort that value to the top of the list. You can use this method to add several values to your dynamic list, if needed.

Note that you wan to avoid using the fields from this command in other parts of the report. It should be used only for the dynamic parameter.

One of my colleagues, Angela Meharg of Datisfy, reminded me that you can use optional parameters to do something similar.  Instead of explicitly selecting a word like “All”, you can skip over the parameter.  Then you can program the selection formula to say that when the users doesn’t select a value they get all values.  The formula would look something like this in the Crystal selection formula:

and (if not (HasValue({?Items})) then True else {Table.Item} = {?Items})

In English this means, if there are no values in the items parameter, then every record qualifies. Otherwise the items that qualify are the ones that match the parameter.

If you have trouble with one of these options, you can schedule a short consult and I can give you a hand.




“Column mode” in the Crystal formula editor

Sunday 5 September 2021 @ 11:31 pm

I have written several articles about using Notepadd++ for writing long formulas or SQL statements. I just found out that one of the features I use in Notepad++ has been (partially) available in Crystal Reports forever.  I never noticed. The feature is called “column mode” and allows you to select text in a column without selecting the entire row.

Lets say you start a formula with DateTime variables like this:

WhilePrintingRecords;
DateTimeVar DateA;
DateTimeVar DateB;
DateTimeVar DateC;
DateTimeVar DateD;
DateTimeVar DateE;

Then you realize that you want them to be Date instead of DateTime. You can highlight a “column” made up of the word “Time” on all 5 rows at once, and then hit delete. To select a column you hold down the ALT key and then click the mouse in the upper left corner of rectangle and drag to the lower right corner. In this case you would start just before the “T” in Time in the first row, and drag down and across until your cursor was just after the “e” in Time in the last row. By using the ALT key you will highlight a rectangle of 4 characters across and 5 rows down. Then you hit delete and just those 20 characters are deleted.

You can also copy and paste a rectangle. Say you have to write a formula that is something like this:

If month({Trans.Date}) = 01 then {Balance.Pd01} else
If month({Trans.Date}) = 02 then {Balance.Pd02} else
If month({Trans.Date}) = 03 then {Balance.Pd03} else
If month({Trans.Date}) = 04 then {Balance.Pd04} else
If month({Trans.Date}) = 05 then {Balance.Pd05} else
If month({Trans.Date}) = 06 then {Balance.Pd06} else
If month({Trans.Date}) = 07 then {Balance.Pd07} else
If month({Trans.Date}) = 08 then {Balance.Pd08} else
If month({Trans.Date}) = 09 then {Balance.Pd09} else
If month({Trans.Date}) = 10 then {Balance.Pd10} else
If month({Trans.Date}) = 11 then {Balance.Pd11} else
If month({Trans.Date}) = 12 then {Balance.Pd12}

Normally I would start by typing the first row and then copy it 11 more times. Then I would change each row to use a different number from 1 to 12.  Once I have changed the column of values after the ‘=’ sign I could copy that 2-digit column and past it over the values in the other 2-digit column in one step.

To do this you select the 2 digit column as a rectangle using the ALT key. You can right clock in the column to copy (or use Ctrl-C). Then you select the other 2-digit column and right-click to paste (or use Ctrl-V).

Note, in Crystal you should select these rectangles starting in the upper left corner, especially if you plan to copy and paste.  You can get inconsistent results if you start in one of the other corners.

NotePad++ has a much more sophisticated column mode, allowing you to:

  1. Paste a single word or character value into multiple rows at once.
  2. Select a column and start typing. The new text is added to ALL the rows at the same time.
  3. Use Shift-Alt to mark the column using arrow keys , instead of the mouse.
  4. Select the column of text starting in any corner.

Unfortunately, these don’t work in Crystal.




Using reserved characters in formula names

Monday 9 August 2021 @ 8:03 pm

I recently heard from Gordon Portanier (from the Crystalize consulting group in Canada). He was doing something I have seen several customer do over the years. He would start certain formula names with a symbol so those formulas would sort to the top of the field explorer list. Gordon happened to use the @ symbol.

When he upgraded to CR 2020 these reports ran fine, but he found that he could not create a new formula that had an @ symbol in the name. A message told him that four characters [ @ { } ? ] were now considered reserved characters and could no longer be used anywhere within the name of a formula field.

Existing formulas, however, are not affected unless you try to rename them. So Gordon found another report that had the formula names he needed and copied them to the current report. The formulas work fine.

Up through CRv12(CR 2008) a formula name could include ANY character in any position. But when I tested this in CRv14.2 (CR 2016) I got the same warning as Gordon. My guess is that this restriction started with CRv14 (CR 2011) and so it would also affect CRv14.1 (CR 2103) and all later versions.  If any of you are using CRv14 (CR 2011) or CRv14.1 (CR 2103) you can confirm this by trying to add a formula with an @ in the name.  Let me know what happens.

An interesting point. This rule only applies to formula names. It does not affect the names of SQL expressions, parameters or running totals.

Another interesting point is that the @ (which represents formulas) and the ? ( which represents parameters) are reserved. But you can still use the % symbol (which represents SQL Expressions) and also the # (which represents running totals).




Undocumented limit on the ExtractString() function

Sunday 4 July 2021 @ 4:21 pm

I have written before about using the ExtractString function. This function is found in the “Additional Functions” of Crystal because it comes from a UFL. But this UFL has come with Crystal Reports for a long time.

Today I found out that this function has an undocumented limit -it can return a maximum of 510 characters. If you need to allow for more than that you will have to use an alternative approach. Here is the formula that I used before I discovered the ExtractString() function. It will also work if you need more than 510 characters.

Local stringVar x := {Your.Field};
Local stringVar Beg := "BeginString";
Local stringVar End := "EndString";

Local NumberVar BegPos := Instr(x,Beg );
Local NumberVar EndPos := Instr(x,End );
Local Numbervar BegLen := Length(Beg);

if BegPos > 0 and EndPos > 0 and EndPos > BegPos
then trim(x [ BegPos+BegLen to EndPos-1 ])
else ''

In the first 3 lines you put in the name of the field, and then the two strings that mark the beginning and the end of the string you want to return. You shouldn’t need to modify the other lines.

The formula will then return everything between those two strings but will not include the strings themselves.




Using HTML interpretation

Wednesday 30 June 2021 @ 2:31 pm

Sometimes database fields store their data with HTML formatting tags. When you put that field on the report it will display the raw HTML tags. However, if you format the field to use “HTML interpretation” Crystal will try to use the HTML tags to format the text. Crystal doesn’t support ALL HTML tags and properties, but there is a list of the ones that are supported on this page.

Another way to use HTML in Crystal is to include HTML tags in your formulas. For instance I could use a few HTML tags to highlight only a portion of a formula field’s output. Below is the formula for a 3-line address with the City name in bold blue text:

{Customer.Customer Name} & '<br>' &
{Customer.Address1} & "<br>" &
"<b><font color='#00559c'>" &
{Customer.City} &
'</font></b>, ' &
{Customer.Region} & ' ' &
{Customer.Postal Code}

The formula uses 4 different tags:

The tag <br> after the first 2 lines creates a new line.
The tags <b> </b> mark the beginning and end of the bold text.
The tags <font color=’#00559c’> </font> mark the beginning and end of the blue text.

You can look up other color code using a color picker site.

When you first put the formula on the report it looks like the left example below. You then use the menu options “Format > Field” and select the “Paragraph” tab to see the “Text Interpretation” option at the bottom. Select “HTML Text” and the formula will look like the right example below.




Anyone want to recompile this free dll to be 64-bit?

Friday 18 June 2021 @ 11:03 pm

Last week I mentioned the U2lwin.DLL. It is a Crystal Reports user function library (UFL) that is currently available in 32-bit but not yet in 64-bit. This means that users who have this dll and who upgrade to CR 2020 will lose some of their formula functions.

This week I checked in with the developer, Bjarke Viksoe.  He has always posted the source code for this dll on his web site. He said it is fine if someone else takes the source code and creates a 64-bit version of the dll. He doesn’t even mind hosting the upgraded file if that helps.

Of course, most of my readers are not application programmers, and neither am I. But I know that a few of you write serious code. If anyone wants to take a crack at this you can download the source code and give it a shot. The current source code uses Microsoft Visual C++ 6.0.

In the meantime, if you upgrade to CR 202o, there is another DLL that you can purchase called Cut Light by Millet Software.  It is one the UFLs in my annual comparison of UFLs. Cut light has at least twice as many functions as U2lwin with many that are the same. So it might have the functions you need, and it comes in both 32-bit and 64-bit.  It isn’t free but it also isn’t very expensive.




Improved formula for elapsed business hours

Saturday 24 April 2021 @ 9:50 am

Last summer I posted a draft of an improved formula for calculating business hours between two dates. It was meant to replace formula #13 on my formulas page, but I was waiting to do some additional real-world testing. Yesterday I got a good test case when a customer asked me to tweak the original formula to deal with start and end times outside the business day. I cleaned up a few typos and updated my formulas page.

This new version lets you separately specify a business start time and business end time for each of the 7 days of the week. It also includes additional logic to deal with events that start and/or end outside the business day (e.g. on a weekend, a holiday or after hours). The formula is now about 70 lines long. Fortunately, you only need to make changes in the first 20 lines or so. Here you specify:

  • The DateTime fields to use for the Begin and End of each event
  • The business start and end times assigned to each day of the week
  • The list of holiday dates, which you can enter for multiple years

The output is a numeric value in hours as a decimal. If you want to show the value in “HH:MM” format you can use the “Elapsed Time String” formula on my site to convert this value into that format. Remember to multiply this formula’s result by 3600 since the input for the “Elapsed Time String” formula is seconds.

If you need help implementing this formula or any of my formulas you can always call to schedule a short consult.




«« Previous Posts
Jeff-Net

Recrystallize Pro

Crystal Reports Server