Monday, February 25, 2013

Check before jumping

I took this from the client script utilities in the Validators.

function csValidateFormExists(strValue) {
    try {
        var ids = lims.CallServer("Enterprise_Data_Providers.FormProvider.GetIds", strValue.Split("."));       
        return ids && ids.length >= 3;
    }catch(e) {
        return false;
    }
}

I find it very useful to check to make sure the form I'm about to call actually exists.  Especially when I am jumping applications.

Tuesday, February 19, 2013

TSQL function "IDENT_Current"

I find this TSQL function to be terribly useful, especially in server calls where I need to insert a record and then need its Origrec.

To use it, do an insert into a table


bSuccess := SqlExecute("INSERT INTO TABLENAME...");

then, to find out the Origrec of the row you just entered, use:

 iOrigRec := SqlExecute("SELECT IDENT_Current('TABLENAME')");


Form.isDirty

Found this one the other day.  Its a Boolean variable that flips when something changes on the form.  The problem is it seems almost everything let's it change.  Honestly I prefer to just set a variable I can control, usually as a form variable or navigator variable.  It just seems easier.



Tuesday, February 12, 2013

Excellent SQL Tips

I really love this article and thought I would share.

I noted at least half of these errors in the default code that came with Starlims' product.

Not a slam so much as to how easily they slip in.

http://www.simple-talk.com/sql/t-sql-programming/ten-common-sql-programming-mistakes/


Monday, February 11, 2013

Hiding Shell Toolbar Items

From time to time I would need to hide different shell toolbar items.  Typically I did so based on the user's permissions or by what window they were in.


   oWindow:=LimsApp("Shell");
   oToolBar:=oWindow : TOOLBAR;

   Dummy:=oToolBar : HIDEITEM(102);     /*Database Connection;
   Dummy:=oToolBar : HIDEITEM(104);     /*User Action;


Item 101 = Closed Starlims
Item 102 = Database Connection
Item 103 = Printer
Item 104 = User Action
Item 105 = NOTHING
Item 106 = Search
Item 107 = Sort
Item 108 = Change View
Item 109 = Copy to Clipboard
Item 110 = First Record
Item 111 =NOTHING
Item 112 =Previous Record
Item 113 = Next Record
Item 115 = Last Record
Item 116 = Mark All
Item 117 = Unmark All
Item 118 = Refresh
Item 119 = Reload
Item 120 = Timesheet (could be local for my system)


You can also ShowItem(), DisableItem() or EnableItem() as well using the same format as above.

Sunday, February 10, 2013

PrmCount()

It goes without saying that if you employ ExecFunction() statements in your code you are going to pass parameters.  Knowing that the parameters you expect were passed becomes important and so is the PrmCount().

Not only will it check and ensure the correct number of parameters were passed, it can be used to create stems of programming logic based off that value as well.

Usually this was something I wrapped in a Case statement.  for example:

:BEGINCASE;
     :CASE PrmCount() = 1;

     :CASE PrmCount() = 2

etc., etc.

This let me count the number of parameters passed and perform logic based on that number.  Very useful to catch errors and make sure you are using the correct passed values.

The order, by the way, is the same order you declared the parameters.  So, if PrmCount() = 1 then it matches the first parameter declared after the :PARAMETERS label.

Saturday, February 9, 2013

LIMSTime()

Like I mentioned with DOW() in a previous post, I had to figure out what day, time, and day of the week it was to send out different emails.

I used LIMSTime() to figure out time frames and then did simple checks.  For example:

SetAMPM(.T.); // this shows the AM/PM ending on time (or not) if desired.


Useful if I wanted to do things like:

time := LimsTime()
date := Today();
IF RIGHT(time,2)='AM';
     :IF LEFT(time,2) <'8';
etc., etc.

This would tell me if it was before 8 am, something very useful if I needed to fire off an email report.

or, perhaps:

:IF  LimsTime() > '4:30:00' .AND. LimsTime() < '0830:00' .AND. DOW(Today())=2;





.etc, etc.

This let me play with a time frame and say if it was before 8:30 and 4:30, do...


Friday, February 8, 2013

Playing with DOW() in V9


At one point I was called upon to determine the day of the week and fire off different emails from starlims depending on the day.  That led me to some doodling with the Dow() function that I figured I would share.

:DECLARE myary, strDate;

:BEGINCASE;
  :CASE DoW(Today())=1; /*SUNDAY;
         strDate := Today() + 1;
  :EXITCASE;
  :CASE DoW(Today())=2;
         strDate := Today() +7;
  :EXITCASE;
  :CASE DoW(Today())=3;
         strDate := Today() +6;
  :EXITCASE;
  :CASE DoW(Today())=4;
         strDate := Today() +5;
  :EXITCASE;
  :CASE DoW(Today())=5;
         strDate := Today() +4;
  :EXITCASE;
  :CASE DoW(Today())=6;
         strDate := Today() +3;
  :EXITCASE;
  :CASE DoW(Today())=7;
         strDate := Today() +2;
  :EXITCASE;
:ENDCASE;


Thursday, February 7, 2013

Str() vs. LTransform() vs. LIMSString()

Each of one of these beauties has their benefits and uses.  Knowing which one is best to use in a given situation can make the difference in your code you might be looking for.

Str() simply converts a numeric expression to a string and is very similar to LTransform(), but uses length and decimal specifications instead of mask like LTransform().  Its very useful when all you are juggling is numbers that need to be formatted as strings.  It looks like this:

Str(Numeric Expression, Length, Decimals)

I'm not going to explain what Numeric Expression means.  It should be obvious.  Length, though isth e length of the string to return, including the decimal point, digits and sign.  A value of -1 specifies that only the significant whole digits to the left of the decimal point are returned and suppresses any right padding.  Decimal places, however, are still returned as specified in Decimals.  If Length is not specified, the length returned is the actual length of the Numeric Expression.

Decimals is the number of decimal places in the return value.  A value of -1 specifies that only the significant digits to the right of the decimal point are returned.  The number of whole digits in the return value, however, are still determined by the Length argument.  If Decimals is not specified, the decimals returned is the actual decimals (if used) of the Numeric Expression.

The Str() function employs rounding.   If Length is less than the number of decimal digits required for the decimal portion of the returned string, the return value is rounded to the available number of decimal places.If Length is specified, but Decimals is omitted (no decimal places), the return value is rounded to an integer.


LTransform() is a little different.  It too can be used to just handle numbers but its more flexible than that.  It can convert any value into a formatted string.  It can format character, date, logical, and numeric values and   format the data for output to the screen or the printer.  The formatting is defined in the parameters.  It looks like this:

Ltransform(Value, Picture)

The usefulness of LTransform() is its ability to present data more cleanly or in a format without using clumsy lengths of concatenation or to perform transformations on data for presentation, like uppercasing all characters, specifying a comma position, or just enclosing negative numbers in a parenthesis.  The Picture parameter is formatted as follows:

Function string:  A picture function string that specifies formatting rules for the return value as a whole, rather than to particular character positions.  The function string consists of the @ character, followed by one or more additional characters as listed below.  If a function string is present, the @ character must be the leftmost character of the picture string, and the function string must not contain spaces.  A function string can be specified alone or with a template string.  If both are present, the function string must precede the template string, and the two must be separated by a single space.
Function                 Action
B                     Displays numbers left-justified
C                     Displays CR after positive numbers
D                     Displays date in SET DATE format
E                      Displays date in British format
R                     Non-template characters are inserted
X                     Displays DB after negative numbers
Z                     Displays zeros as blanks
(                      Encloses negative numbers in parentheses
!                      Converts alphabetic characters to uppercase

Template string:  A picture template string specifies formatting rules on a character by character basis.  The template string consists of a series of characters, some with a special meaning, as shown below.  Each position in the template string corresponds to a position in the Value.  Because Ltransform() uses a template, it can insert formatting characters such commas, dollar signs, and parentheses.Characters in the template string that have no assigned meaning are copied into the return value.  If the @R picture function is used, these characters are inserted between characters of the return value; otherwise, they overwrite the corresponding characters of the return value.  A template string can be specified alone or with a function string.  If both are present, the function string must precede the template string, and the two must be separated by a single space.

Template                     Action
A,N,X,9,#                      Displays digits for any data type
L                                    Displays logicals as "T" or "F"
Y                                   Displays logicals as "Y" or "N"
!                                     Converts an alphabetic character to uppercase
$                                    Displays a dollar sign in place of a leading space in a numeric
*                                    Displays an asterisk in place of a leading space in a numeric
.                                     Specifies a decimal point position
,                                     Specifies a comma position


LIMSString() is probably the most flexible of the three.  It can return any input except an array or object as a string.  Arrays can be handled if you break them down to values, such as Array[1] or Array[1,1].

Wednesday, February 6, 2013

Source Control Manager

So,

when the day comes that you mess up a form accidentally, please do better than I.  Instead of recreating the code in the form, go to the Source Control Manager and recover it!

I'm not sure why I forgot Starlims had that capability but it does.

The SCM is under the Utilities tab in the Console and you can compare versions, recover previous versions or create labels to attach to them.

It also lets you look at everything you have checked out in in a tree view.  Very handy if you have a lot of things checked out and need to check them back in.

You can also export items from this location as well.

Friday, February 1, 2013

LimsTransactions

Just a short note on these two short but very important pieces of code.

BeginLimsTransaction()

EndLimsTransaction()

Both of these fellow are worth their weight in gold when it comes to performing updates, inserts or deletes.  Like they sound like, they wrap your transactions to the database.

Use them!  

Even for single actions, use them!  Most especially, though, use them for anything complex or anything with dependencies.