SETSELECTIONFILTER in temporary records

FishermanFisherman Member Posts: 456
I have a form that is based on a temporary record.

In that form, I'm trying to use CurrForm.SETSELECTIONFILTER(NewRec) where NewRec is, you guessed it, a temporary record.

The reason is that these are staging records in a barcode printing application. Persistence of this information is not necessary, so I'm trying to avoid it. I'd like to allow my users to select one or more records and add new derivative UOM records (i.e., CARTON, PALLET, etc...) and print only those records that are selected.

Needless to say... it's not working. NewRec is empty after the call to SETSELECTIONFILTER()

I found this post from a while ago. Does anyone know is this was supposed to be fixed in V 5.0?

Comments

  • BeliasBelias Member Posts: 2,998
    It works, in nav 2009...unfortunately, i don't have a test environment in 5.0 up to now...i'm restoring the db...i'll let you know
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • garakgarak Member Posts: 3,263
    edited 2009-06-19
    If you use Selectionfilter, the user must ever press the CTRL Button. And some useres are very stupid ....
    So, why not using the CTRL+F1 (mark) funktion or a separate field (bool) where the user set the seleted Flag.

    Here a codesnippes with the Mark and after a codesnippes with using a separate field.
    //We fill the temp. Table Item and run after the List Form to show all temp. inserted Items
    for i := 1 to 10 do begin
      Item.init;
      Item."No." := format(i);
      Item.Description := 'sdfd' + format(i);
      Item."Base Unit of Measure" := 'STCK';
      Item."Unit Price" := i;
      Item.insert;
    end;
    
    form.runmodal(50004,Item);
    

    Now, we see the List and the user should select some recs.
    With these selected recs we will work in a other process (like printing or what else...)
    //CurrFormSelectionFilter(Rec) <- this works not on temp. Recs
    OldNo := "No."; //only to know where the "Pointer" is
    
    markedonly(true);  //we need only the selected Records -> selected with CTRL+F1
    
    if FINDset(false,false) then begin
      REPEAT
        MESSAGE("No.");
      UNTIL NEXT = 0;
    end;
    
    markedonly(false); //now, we "delete" the marked filter
    //clearmarks(); //these remove the marks
    get(OldNo); //set the pointer to the old position
    

    Also, instead of using the MARK function, u can use a Bool Field in the table. For this example, i use the field "Allow Invoice Disc.", and these field has in the form the Caption: "Select me"
    setrange("Allow Invoice Disc.",true);
    if FINDset(false,false) then begin
      REPEAT
        MESSAGE("No.");
      UNTIL NEXT = 0;
    end;
    setrange("Allow Invoice Disc.");
    

    So, it's very simple......

    Regards
    Do you make it right, it works too!
  • David_SingletonDavid_Singleton Member Posts: 5,479
    Fisherman wrote:
    I have a form that is based on a temporary record.

    In that form, I'm trying to use CurrForm.SETSELECTIONFILTER(NewRec) where NewRec is, you guessed it, a temporary record.

    The reason is that these are staging records in a barcode printing application. Persistence of this information is not necessary, so I'm trying to avoid it. I'd like to allow my users to select one or more records and add new derivative UOM records (i.e., CARTON, PALLET, etc...) and print only those records that are selected.

    Needless to say... it's not working. NewRec is empty after the call to SETSELECTIONFILTER()

    I found this post from a while ago. Does anyone know is this was supposed to be fixed in V 5.0?

    Why make it so complex :?:
    If its a temporary table just add a new boolean field "Select Line" to the table and have the user tick it.


    The Beauty Of Simplicity
    David Singleton
  • David_SingletonDavid_Singleton Member Posts: 5,479
    :mrgreen: I just looked at that thread you link to, and Rashed gives the exact same advise. Sounds like a solution to me.
    David Singleton
  • garakgarak Member Posts: 3,263
    :shock: the link in the first post i doesn't saw .....
    it's absolutly the same idea :-)
    Do you make it right, it works too!
  • FishermanFisherman Member Posts: 456
    David -

    The complexity matches both the user/interaction requirements and the storage requirements.

    Imagine this.

    A form opens with transformed data from your source records. There are functions defined at the bottom of that form that allow you to perform additional transformations to all or selected records in that form. You can also choose to perform the final action (print) for some or all of those records.

    If I were to implement a boolean flag, they'd have to check it, run the desired transformation, uncheck it, move to the next, check it, run the desired transformation, uncheck it, .... frustrating real fast

    Then they'd have to recheck the ones that they wanted to print. This is all so much more easily done by control + clicking the lines, running the transformations, and printing. There are fewer clicks, and it's more consistent with the rest of the system.

    From a storage perspective - I don't need nor want these records to be persisted. They're determined at run time, and are not needed later. Storing them, even temporarily, in the database puts additional I/O on the database that is not needed, and with NAV, I'm finding I need all I can get.

    I did see that in the previous post, and considered it, but it's not the optimal solution.
  • FishermanFisherman Member Posts: 456
    Thanks, belias.

    As much as I don't want to, I think I'm going to have to add a field to the table to uniquely identify that user's "session" with that table, Filter the records on that field, and set that filter in a separate filtergroup so that the user can only work with that "session" in that form. It means that I'll have to temporarily persist the records in the db, but I guess I'll clean them up when they exit the form.

    If you find out that it does work in 5.0 SP1, please let me know.
  • BeliasBelias Member Posts: 2,998
    Temporary tables does not generate I/O on the database, but maybe i misunderstood what you wrote here
    Storing them, even temporarily, in the database puts additional I/O on the database that is not needed
    anyway...it works in my 5.01 database (i simply created a cmdbutton with these lines)
    currform.setselectionfilter(rec);
    findfirst;
    message("no.");
    
    sourcetable is temporary and it's filled in the onopenform
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • David_SingletonDavid_Singleton Member Posts: 5,479
    edited 2009-06-19
    8><

    <deep breath count to ten 1 .. 2 .. 3 .. 4 .. 5 .. 6 .. 7 .. 8 .. 9 .. 10 ....

    relax it's not my problem anyway...>
    David Singleton
  • FishermanFisherman Member Posts: 456
    Belias -

    Yeah. I meant if I WEREN'T to use a temporary table, but instead actually inserted the record into the table temporarily and deleted it when I was finished with it. I know that Lanham does this in some of their code with scanning, but it's more applicable there - they have to persist state across calls in, from what I can tell, is a stateless protocol.
  • FishermanFisherman Member Posts: 456
    My apologies to David.

    I had read part of his post out of context, and thought that he was recommending persisting records in the database, which was against one of my design goals.

    I'm going to attempt this with a boolean field and see how it goes.

    Thanks.
  • David_SingletonDavid_Singleton Member Posts: 5,479
    No worries, just glad we got the confusion resolved.

    Keep in mind also that you can always use marks or selections to set the boolean field. Or you can even filter on the boolean, pass them to another TEMP table process them there doing what ever multiple operations are needed. You can even pass the selected lines easily back to the calling function. There are many options.

    One of my very first fixes in Financials was for something similar, the partner had created a function that inserted records into a table with he user id as primary key, processed etc then deleted afterward. It had so many problems it was not fixable. So I moved to to a temp table and they had a boolean field to select the lines they wanted to process. I have done it again many times since then, and its generally the simplest solution.
    David Singleton
  • BeliasBelias Member Posts: 2,998
    Fisherman wrote:
    Thanks, belias.

    As much as I don't want to, I think I'm going to have to add a field to the table to uniquely identify that user's "session" with that table, Filter the records on that field, and set that filter in a separate filtergroup so that the user can only work with that "session" in that form. It means that I'll have to temporarily persist the records in the db, but I guess I'll clean them up when they exit the form.

    If you find out that it does work in 5.0 SP1, please let me know.

    am i missing something, or someone miss my post? :-k
    ...i suppose the first... :oops:
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • FishermanFisherman Member Posts: 456
    I saw where you said that it worked in 2009, but you said you were "restoring the db..." and that you'd let me know. Maybe I misread.
  • BeliasBelias Member Posts: 2,998
    anyway...it works in my 5.01 database (i simply created a cmdbutton with these lines)
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • FishermanFisherman Member Posts: 456
    man... is my head gone today?

    I completely missed that with everything else that was going on.

    It did work fine when I called SETSELECTIONFILTER on Rec. I could see where it was filtered without an issue.

    What doesn't work for me is when I call it with a new record variable. So... I have a form that has the SourceTableTemporary table set to true. I have another temporary record called NewRec that is of the same table as Rec. After I call CurrForm.SETSELECTIONFILTER(NewRec), NewRec is empty.

    If I do this in a form with SourceTableTemporary = No, it works fine, and my NewRec variable contains only those records that were selected.

    Interestingly enough, I was able to use TRANSFERFIELDS to copy values from one record to another of the same table when those record variables are not temporaries, but when they are temporary, it doesn't have the same behavior.

    Oh well. I'm finding ways around.
  • BeliasBelias Member Posts: 2,998
    edited 2009-06-20
    so you're doing something like this...
    - fill the "rec" temptable
    - select some of his records with setselectionfilter
    - loop the selected records: during the loop you populate newrecvariable (with insert, obviously)
    - return the newrec somewhere else

    am i correct?if so, why don't you pass rec variable and do a rec.reset after processing?RESET clear the marks, too (setselectionfilter mark the records).

    anyway, maybe setselectionfilter does not work on newrec, because the records selected on the form belongs to rec, instead (and setselectionfilter works on the records of the form, of course)...hope to be clear...

    *edit: yesterday i noticed that the underlined text has not a lot of sense... :) i am just throwing some ideas
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • FishermanFisherman Member Posts: 456
    :-k

    You know... that just might work.

    I'll let you know what I find out.. [-o<

    Thanks.
  • DenSterDenSter Member Posts: 8,305
    Fisherman wrote:
    What doesn't work for me is when I call it with a new record variable. So... I have a form that has the SourceTableTemporary table set to true. I have another temporary record called NewRec that is of the same table as Rec. After I call CurrForm.SETSELECTIONFILTER(NewRec), NewRec is empty.
    Think about it.... really stop and think about it... you are not thinking this through all the way

    Regular record variables are looking at the actual table, so you can take the filter from one variable, copy them to another variable, and you get the same results, because the variable goes to the table and retrieves records from the physical table. No brainer right. You'd think that the same applies to temporary records right? Well that's where you are wrong, because temporary records don't have any values in them when you instantiate them, so when you fill only one of them, set filters, and copy the filters to the other one, it comes as no surprise that there are no values in there, BECAUSE IT DOESNT HAVE ANY VALUES.

    You have a temporary record variable, which is empty when it is instantiated. You fill it up. Now it has records, temporary records that only exist in this memory space that is occupied by this single record variable. Now you apply a filter on this set of records. Now you want to apply the same filter to another temporary record, but you are surprised that you don't see anything in the other one. The other one hasn't been filed yet, it is uninstantiated!!! The second variable doesn't just read from the first variable, you have to actually put the records into the variable.

    Think of a temporary record variable as a collection of objects. Rec (the temporary record variable that your form is based on) and NewRec (which is a global or local variable somewhere in your logic) are two different collections. One of them has been filled, but the other one has not been filled. The selectionfilter from Rec is properly applied to NewRec, but since there is nothing in there, you don't see anything. For someone that supposedly is well versed in C++ this should not be a new concept right :mrgreen:

    Solutions:
    1 - loop through the filtered set and copy the records one by one to the other temp record
    2 - fill both variable s with the same records to begin with, so they contain the same records. Now when you copy filters you will see the same ones.
  • BeliasBelias Member Posts: 2,998
    Belias wrote:
    so you're doing something like this...
    - fill the "rec" temptable
    - select some of his records with setselectionfilter
    - loop the selected records: during the loop you populate newrecvariable (with insert, obviously)
    - return the newrec somewhere else

    am i correct?if so, why don't you pass rec variable and do a rec.reset after processing?RESET clear the marks, too (setselectionfilter mark the records).
    [...]
    I thought he was already INSERTING the filtered records of rec in the NewRec variable... :-k
    Are you doing it, doesn't you fisherman? [-o<
    -Mirko-
    "Never memorize what you can easily find in a book".....Or Mibuso
    My Blog
  • DenSterDenSter Member Posts: 8,305
    The way I read his story is that he fills Rec (either in OnOpen or in some other object that calls the form with a temp record variable), he selects some of them in the form, and then in his button OnPush code he does SETSELECTIONFILTER on another variable called NewRec, and he expects that to be filled with the selected records automatically.
Sign In or Register to comment.