Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 277
  • Last Modified:

I'm having trouble with an @Formula (I hate @Formula!) - can anyone help me to make it do what I want it to do? I'm using R6.5.

The Formula lives in an Action on a Form, & is labelled "Update Item...". When pressed, it prompts the user to select one from a list of Items (Response documents). Next, it prompts them to select a new Status for the Item, showing the previous Item Status in the dialog box. If the user selects a status of "Error", then they should additionally be prompted for a Description of the Error. Alas, this part never happens, even when Error is selected.

Here's the formula:

tmpTDF := @PickList([Custom] : [Single]; ""; "(TDFsByParentID)"; "Update Item"; "Please select the Item you wish to Update:"; 3; @Text(@DocumentUniqueID));
@If(tmpTDF = ""; @Return(""); "");
tmpItemID := @GetDocField(tmpTDF; "TDFComponentID");
tmpNewStatus := @Prompt([OkCancelList] : [NoSort]; "Update " + tmpItemID; "Please select the New Status for the Item you selected"; @GetDocField(tmpTDF; "TDFStatus"); "Waiting" : "In Pre-Press" : "In Production" : "Complete" : "Error");
tmpError := "";

@If(tmpNewStatus = "Error";
  @Do(
    @Set("tmpError"; @Prompt([OkCancelEdit]; "Error Type"; "Please enter a description for the Error on " + tmpItemID + ":"));
    @If(tmpError = "";
      @Return("You must enter a description for the Error");
      @Do(@SetField("Error"; tmpError); @SetField("Async"; "1")))); "");

@SetDocField(tmpTDF; "TDFStatus"; tmpNewStatus);
@Command([FileSave]);
@Command([FileCloseWindow]);
@PostedCommand([OpenDocument]; 1; @DocumentUniqueID);
@All

I originally had 'tmpError := @Prompt...' rather than the current '@Set("tmpError"; @Prompt...', but read that @Set is like @SetField in that it must be used inside another formula. I also read that since R6, you no longer need an assignment statement before the first @Set, although as you can see, I've put one in anyway, but it still doesn't work. Why does it miss the whole '@If(tmpNewStatus = "Error"; ' section?

Thanks.
0
PaulCutcliffe
Asked:
PaulCutcliffe
  • 16
  • 9
  • 7
  • +1
1 Solution
 
SysExpertCommented:
If this is an action, why not convert it to Lotus Script ?

I hope this helps !


0
 
marilyngCommented:
Paul:  The nasty thing about formula language is that if ANY part throws an error, it's just exits, or skips over it.  So, the only way to troubleshoot is to put @Prompt's everyplace.  I'm not entirely sure why you want to close and reopen the same form, unless you're updating a rich text field, but I do know that it doesn't work in this context, once you issue the fileclosewindow, the form closes and your script loses focus.  

Near as I could tell, each of the little sections were throwing their own little errors that you have to trap before it can move to the next one.
-----------------------------

tmpTDF:= @PickList( [Custom] : [Single] ; @DbName;""(TDFsByParentID)"; "Title"; "Select" ;3);
    @If(tmpTDF=""; @Return(@Prompt([Ok];"Nothing Selected";"You didn't select anything"));"");

tmpItemID2:= @GetDocField(tmpTDF; "TDFComponentID");
    tmpItemID:=@If(tmpItemID2=""|@IsError(tempITemID2);"Missing Component";tmpItemID2);

tmpStatus2:= @GetDocField(tmpTDF; "TDFStatus");
  tmpStatus:=@If(@IsError(tmpStatus2)|tmpStatus2="";"Missing Status";tmpStatus2);

tmpNewStatus:= @Prompt([OkCancelList] : [NoSort]; "Update " + tmpItemID; "Please select the New Status for the Item you selected"; tmpStatus; "Waiting" : "In Pre-Press" : "In Production" : "Complete" : "Error");

tmpError:=@If(tmpNewStatus="Error";@Prompt([OkCancelEdit];"Error Type"; "Please enter a description for the Error on " + tmpItemID + ":";"");"");
          @If(tmpNewStatus="Error" & tmpError="";
            @Return(@Prompt([Ok];"Description Required";"You must enter a description for an Error Status"));"");

@SetField("Error"; tmpError);
@SetField("Async"; "1");
@SetDocField(tmpTDF; "TDFStatus"; tmpNewStatus);

@If(@Command([FileSave]);      
              @Command([FileCloseWindow]);"")

----------------

Ok, now before the other ee's start adding to this saying, why didn't I stack these two things, or you can do this in ONE statement.....
I did it this way so you can READ it, and follow the logic.

Also, I could not get the:  @set("tmpError";@Prompt([OKCANCELEDIT]; etc, nested in the @Do() to work, not nested, not by itself.
------
How I debugged this was to put each statement under a button by itself.  Then added it to the overall formula.
0
 
PaulCutcliffeAuthor Commented:
marilyng: Just had a quick scan through your post, & I'm now kicking myself!

Mine
====
@If(tmpNewStatus = "Error";
  @Do(
    @Set("tmpError"; ...

This is BAD!

Yours
====
tmpError:=@If(tmpNewStatus="Error"; ...

This is GOOD!

Although @Formula code is a little quirky, this is one of its main quirks, so I should have got this one!

I shall try it that way around.

Thanks.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
marilyngCommented:
Paul, yeah, it was skipping over this because it hit error.. :)   Which is why it didn't query you or exit like it was supposed to.


Hey this stuff happens. :)
0
 
PaulCutcliffeAuthor Commented:
By the way, the reason I close & re-open the document is that there is some LotusScript that runs on opening that updates the main document's status, based on the combined stati of all the Response documents. And this works beautifully.
0
 
PaulCutcliffeAuthor Commented:
No luck.

I now have this:

tmpTDF := @PickList([Custom] : [Single]; ""; "(TDFsByParentID)"; "Update Item"; "Please select the Item you wish to Update:"; 3; @Text(@DocumentUniqueID));
@If(tmpTDF = ""; @Return(""); "");
tmpItemID := @GetDocField(tmpTDF; "TDFComponentID");
tmpNewStatus := @Prompt([OkCancelList] : [NoSort]; "Update " + tmpItemID; "Please select the New Status for the Item you selected"; @GetDocField(tmpTDF; "TDFStatus"); "Waiting" : "In Pre-Press" : "In Production" : "Complete" : "Error");
tmpError := @If(tmpNewStatus = "Error"; @Prompt([OkCancelEdit]; "Error Type"; "Please enter a description for the Error on " + tmpItemID + ":"); "");
@If(tmpNewStatus = "Error" & tmpError = ""; @Return("You must enter a description of the Error"); "");
@SetField("Async"; "1");
@SetField("Error"; tmpError);
@Command([FileSave]);
@SetDocField(tmpTDF; "Error"; tmpError);
@SetDocField(tmpTDF; "TDFStatus"; tmpNewStatus);
@Command([FileSave]);
@Command([FileCloseWindow]);
@PostedCommand([OpenDocument]; 1; @DocumentUniqueID);
@All

So I am now assigning tmpError to the result of an @If, rather than only assigning it in the result of the @If, if you see what I mean. Sadly, it still doesn't prompt you for tmpError!

I've also tried this with a few Debug @Prompts:

tmpTDF := @PickList([Custom] : [Single]; ""; "(TDFsByParentID)"; "Update Item"; "Please select the Item you wish to Update:"; 3; @Text(@DocumentUniqueID));
@Prompt([OK]; "Debug1: tmpTDF"; tmpTDF);
@If(tmpTDF = ""; @Return(""); "");
tmpItemID := @GetDocField(tmpTDF; "TDFComponentID");
tmpNewStatus := @Prompt([OkCancelList] : [NoSort]; "Update " + tmpItemID; "Please select the New Status for the Item you selected"; @GetDocField(tmpTDF; "TDFStatus"); "Waiting" : "In Pre-Press" : "In Production" : "Complete" : "Error");
@Prompt([OK]; "Debug2: tmpNewStatus"; tmpNewStatus);
tmpError := @If(tmpNewStatus = "Error"; @Prompt([OkCancelEdit]; "Error Type"; "Please enter a description for the Error on " + tmpItemID + ":"); "");
@Prompt([OK]; "Debug3: tmpError"; tmpError);
@If(tmpNewStatus = "Error" & tmpError = ""; @Return("You must enter a description of the Error"); "");
@SetField("Async"; "1");
@SetField("Error"; tmpError);
@Command([FileSave]);
@SetDocField(tmpTDF; "Error"; tmpError);
@SetDocField(tmpTDF; "TDFStatus"; tmpNewStatus);
@Command([FileSave]);
@Command([FileCloseWindow]);
@PostedCommand([OpenDocument]; 1; @DocumentUniqueID);
@All

Now, I get asked if I would like to Save the document (which is caused by the @Return when tmpNewStatus = "Error" and tmpError = "") BEFORE being prompted for tmpError, which never happens.

Why is this? Can anyone see what is wrong?

Thanks.
0
 
Sjef BosmanGroupware ConsultantCommented:
Wouldn't it be a swell idea not to do this with a lot of badly maintainable Formula code, but with a nice DialogBox that you call for the response document? With all the logic in the (sub)form used in the DialogBox?
0
 
PaulCutcliffeAuthor Commented:
Just seen this: http://searchdomino.techtarget.com/tip/1,289483,sid4_gci917915,00.html?bucket=ETA - it suggests that you compute the Computed Subform using an environment variable, but I've tried that to, to no avail. :-(

sjef_bosman: I hate @Formula language, mainly because it always seems to cumbersome compared to LotusScript, so for me to try something in @Formula language first, there's normally a good reason. On this occassion, it is because of the ease with which you can offer choices, as I have done with the @PickList etc. However, I will have a think about your suggestion & come back to you...
0
 
PaulCutcliffeAuthor Commented:
SysExpert: Sorry, just noticed you made a similar suggestion earlier on.
0
 
PaulCutcliffeAuthor Commented:
Sorry, that comment: "Just seen this..." was actually meant for another question altogether - Q_21868869.
0
 
PaulCutcliffeAuthor Commented:
Oh deary me.

I've just found that the Response document had 'Incorrect Number of Arguments for @Function' or whatever the exact wording is in the Error field. This came from the tmpError variable, which got it from the @Prompt function, which was missing the Default Argument!
0
 
marilyngCommented:
Paul, the rule of thumb for formula is if it's over 15 lines, write it in script.  

Had you asked, I would have spent the three hours redoing in script, rather than debugging in formula. :)
So, not that I mind sjef or sysexpert's suggestions, but your original question was to correct the formula. :)


You made the same mistake last time:>>tmpItemID + ":"); <<< this is wrong.
NO:
tmpError := @If(tmpNewStatus = "Error"; @Prompt([OkCancelEdit]; "Error Type"; "Please enter a description for the Error on " + tmpItemID + ":"); "");

Correct:
tmpError := @If(tmpNewStatus = "Error"; @Prompt([OkCancelEdit]; "Error Type"; "Please enter a description for the Error on " + tmpItemID + ":";"");"");


YOu keep leaving off the default value for tmpError.
0
 
PaulCutcliffeAuthor Commented:
Hey, are you saying that when you posted at 05/31/2006 01:28PM BST, you knew I had missed off the Default value? Surely you'd have pointed that out then, rather than just stating "Paul, yeah, it was skipping over this because it hit error.. :)   ", wouldn't you?
0
 
marilyngCommented:
you knew I had missed off the Default value<< it was corrected in my first post at 12:31 AM.

tmpError:=@If(tmpNewStatus="Error";@Prompt([OkCancelEdit];"Error Type"; "Please enter a description for the Error on " + tmpItemID + ":";"");""); <<SEE??

at 1:28, I didn't look over your code until  just now when you posted the error problem.  I noticed you made the same error on the original post.   But, it's an easy mistake, and I actually made the same one before I posted the solution.

So, let's go back to does the original posted solution work.  Let's test that before we start embellishing.
0
 
Sjef BosmanGroupware ConsultantCommented:
THREE whole hours?? ROTFL

And I like Formula, because you are forced to twist and turn your braincells in a totally different way. LS is VB is C is Pascal is Algol is easy.
0
 
marilyngCommented:
Actually, that's why I hate formula.  I like some of the things that it does, but trying to debug is a pain in the butt.  Also, I love writing it, but hate having to take it apart to figure out nesting :)

I go by the rule, if it's longer than 15 lines, then write it in script.

Although, I have seen some people do entire applications in formula, and now that you can loop,  I imagine that must be heaven for the formula-pushers.
0
 
Sjef BosmanGroupware ConsultantCommented:
Looping in Formula is just cheating. The real art is to get a list to do the looping for you. Theoretically speaking of course...

Nesting is sometimes terrible, and Formula can get too LISPy: you can't see the code for the parentheses.
0
 
PaulCutcliffeAuthor Commented:
marilyng: Okay, fair enough. I didn't spot the difference in your original post either. Never mind, I've found it now.

"So, let's go back to does the original posted solution work.  Let's test that before we start embellishing." - yes, quite.

Well it works just perfectly now, with one small exception. Here's the formula as it stands now:

tmpTDF := @PickList([Custom] : [Single]; ""; "(TDFsByParentID)"; "Update Item"; "Please select the Item you wish to Update:"; 3; @Text(@DocumentUniqueID));
@If(tmpTDF = ""; @Return(""); "");
tmpItemID := @GetDocField(tmpTDF; "TDFComponentID");
tmpNewStatus := @Prompt([OkCancelList] : [NoSort]; "Update " + tmpItemID; "Please select the New Status for the Item you selected"; @GetDocField(tmpTDF; "TDFStatus"); "Waiting" : "In Pre-Press" : "In Production" : "Complete" : "Error");
tmpError := @If(tmpNewStatus = "Error"; @Prompt([OkCancelEdit]; "Error Type"; "Please enter a description for the Error on " + tmpItemID + ":"; @GetDocField(tmpTDF; "Error")); "");
@If((tmpNewStatus = "Error") & (tmpError = ""); @Return("No description given for the Error"); "");
@If((tmpNewStatus = "Error") & (tmpError != ""); @Do(@SetField("Async"; "1"); @Command([FileSave])); "");
@SetDocField(tmpTDF; "Error"; tmpError);
@SetDocField(tmpTDF; "TDFStatus"; tmpNewStatus);
@Command([FileSave]);
@Command([FileCloseWindow]);
@PostedCommand([OpenDocument]; 1; @DocumentUniqueID)

The part that doesn't seem to work is the line that says:

@If((tmpNewStatus = "Error") & (tmpError != ""); @Do(@SetField("Async"; "1"); @Command([FileSave])); "");

The first time (not sure why only the first time) you select "Error", you are prompted halfway through "Do you want to save your changes?", even though the first part of the @Do statement does get executed.

For some reason, each subsequent time you change status, even if you change to "Error", doesn't prompt you to save changes. No idea why.

Anyone see what's going wrong?
0
 
PaulCutcliffeAuthor Commented:
By the way, I don't like the 15 line rule. Sometimes, LotusScript does the job beautifully in just a few lines (admittedly not very often, but sometimes), whereas other times a long @Formula is still easier. Surely it's about what it has to do, not how long it is?
0
 
Sjef BosmanGroupware ConsultantCommented:
Just some alternative code:
    @If((tmpNewStatus = "Error") & (tmpError = ""); @Return("No description given for the Error"); "");
    @If((tmpNewStatus = "Error") & (tmpError != ""); @Do(@SetField("Async"; "1"); @Command([FileSave])); "");

change into

    @If(tmpNewStatus!="Error"; "";
         tmpError = ""; @Return("No description given for the Error");
        @Do(
            @SetField("Async"; "1");
            @Command([FileSave])
        )
    );

A @Command([FileSave]) will always ask to save changes, unless you set SaveOptions to "1" (but then it will remain "1" for the next time, unless you remove the field whenever you open the document again). Probably it will not be called again because there are no real changes? Async has been set to "1" already. I guess...
0
 
PaulCutcliffeAuthor Commented:
Thanks for the suggested improvement - I agree that is better.

But you say "A @Command([FileSave]) will always ask to save changes" - surely this isn't right? @Command([FileSave]) prevents you from being asked, doesn't it? @Command([FileCloseWindow]) will of course prompt you to save changes if there are any, if you haven't called @Command([FileSave]) first, but not @Command([FileSave]), surely?
0
 
Sjef BosmanGroupware ConsultantCommented:
Hm, you could be right. I dug this up from the Designer Help db:

When you follow this command with the FileCloseWindow @command, by default Notes displays a dialog box prompting users to save the document they are closing. The document will be saved even if a user clicks "No" in the dialog box. To prevent this dialog box from displaying, add a hidden field to the form named "SaveOptions" and set its value to zero ("0"). You do not need to add the SaveOptions field if you follow this command with the CloseWindow @command instead of FileCloseWindow.
0
 
PaulCutcliffeAuthor Commented:
Interesting - when it says 'this command', does it mean @Comment([FileSave])? Is this from R7? I didn't even know there was an @Command([CloseWindow])!
0
 
PaulCutcliffeAuthor Commented:
I've just had a look, & seen it was new in R6. Must have missed that one.
0
 
marilyngCommented:
Glad sjef was able to help you with the:

@If((tmpNewStatus = "Error") & (tmpError != ""); @Do(@SetField("Async"; "1"); @Command([FileSave])); "");

I basically took out the @Do( stuff to debug.  :)


But you can certainly put it back in.. the 15 line rule is mine.. :)  If it becomes to laborious to read and if it's in an agent that modifies mission critical stuff, I do script, because I can track and capture errors.
0
 
PaulCutcliffeAuthor Commented:
I feel that I found the error myself, although marilyng appears to have found it too.

It still prompts "Would you like to Save" halfway through, for no apparent reason though.
0
 
Sjef BosmanGroupware ConsultantCommented:
But is your original question
    Why does it miss the whole '@If(tmpNewStatus = "Error"; ' section?
solved?

Isn't the saving-question another issue?
0
 
PaulCutcliffeAuthor Commented:
Yes, you are right about the Saving thing being a separate issue, but the original error in my code was that the @Prompt([OkCancelEdit]) command was missing its Default Value parameter, & so was returning an Error (wrong number of arguments for @Function) instead of prompting the user. This error I found myself, although it also seems that marilyng found it too - she just forgot to point it out, so I didn't know till much later.
0
 
marilyngCommented:
Paul,  please note the time I posted your answer: 05/31/2006 12:01AM EST.  That was an hour and some past my bedtime.

At that hour, I didn't occur to me to point out typo's since I posted the corrected code.

Silly me, I assumed that when I take the time to set up a test environment, test and rewrite the code and subsequently paste  the corrected code into an answer, that the user would copy and paste the code into a button.

I have no idea why you didn't do this, but , hey if you want to blame me for the code not jumping off the webpage and into your application correctly, fair enough.   But, I frankly can't think of any other way to test the code I posted other than for you to copy and paste it into your application.
---------------------------------
The save problem wasn't part of the original question, and the rules ask that you open a new question, and not piggy back subsequent questions onto the first one.  However, we were nice enough to answer that one and tell you how to resolve it.
But since you were already miffed because I didn't point out your typo's, I imagine not devining you needed a second solution only exacerbated your displeasure with me.

------------
Offhand, you aren't the first person to futz with a solution before you test the original to see if, how and why it works, and then report back in indignation that "it doesn't work!!!"  
-----------------
In order to have Customer Service consider refunding your points, you must post your entire solution and the explanation.  I have asked  the moderators  to intercede in this question.

Regards.



0
 
marilyngCommented:
Oops, correction.  The saveOptions problem is not addressed here.  I confused this with another  similar question.
0
 
Sjef BosmanGroupware ConsultantCommented:
C'mon guys, peace... I know The Netherlands lost yesterday, but that's no reason not to be friendly to everyone. Some diplomacy please...

About futzing: it's never right, isn't it? Maybe that's why I don't post full solutions, but only comments. It's strange, one can post well-meant hints and comments in one question, and the asker expects a full working solution. The next question, a complete solution is posted and the asker starts unravelling it. Life is tough...

0
 
marilyngCommented:
Of course, you're right, sjef.

I extend apologies if I offended.

Paul, I am not in the least upset with you, and you certainly have a right to your opinion.

If you want your points refunded, please place a request with Customer service.

Again, I have asked the moderators to intercede.

Marilyn
0
 
PaulCutcliffeAuthor Commented:
Oh deary me, I've been off working on site for a few days, and have just come back to see that I seem to have caused quite a storm - I certainly didn't mean to. I will happily award marilyng the points for 'finding' the problem in my formula, and I certainly didn't mean to upset her.

I just feel that if marilyng had said "Hey Paul, you know you missed the Default Value parameter from the @Prompt() function in the middle of your formula, don't you", I'd have said "Hey you're right, that's why it isn't working! Thanks for that!" and the whole thing would have been over much quicker. It was much later that I noticed the missing Default Value parameter myself, only to find when I posted that here that marilyng had already noticed that in my original posting.

I guess the lesson is to point out even what is obvious to you, as quite often someone's having missed the obvious may well be the reason they are looking for your help. :-)

I do, however, appreciate all contributions to problems I post here, & have a great deal of respect for this forum, and all who post in her.

Keep up the good work!
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 16
  • 9
  • 7
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now