Empty Select selects all

That’s not possible because as I stated, what you want to do is not possible in the current version of Panorama X. You’ll have to wait for the next version to get this working properly.

It’s not possible for me to do anything using the new selection options you’ve added, but it’s certainly possible to every other degree discussed here: startdatabasechange, checkemptyselection, etc.

If I keep my fingers off the mouse and keyboard, those currently work even as I wait for the next release. Touch the mouse or keyboard and I have errors that I have no reason to believe will or will not be repeated with the upcoming SafeSelect and SafeSelectWihtin statements.

I’d rather report the issue now rather than later. If it’s covered by your changes, fine. If it’s not, I wanted to make you aware of it.

CheckEmptySelection was where you started at the top of this. Looking over the posts in this thread, I don’t think I ever suggested that. If I did, I retract it. However, I of course have to take responsibility for creating that statement, which I now think was a mistake. I suspect that the undo operation performed in checkemptyselection may be the source of your “don’t touch it” problem.

I’m going to change the documentation for checkemptyselection to indicate that it should be avoided going forward, in favor of safeselect.

I’m getting a little befuddled (easy to do) following this. For a vote, if the records are in a certain “selected” state, and I do another selection, “within” or straight “select” and there is no match, I’d expect the select status to be whatever it was in prior to the empty select and NOT return to a SelectAll state.

In my thinking, SelectAll is an action, and I didn’t request that action. If that’s how it works, it’s like a game of Chutes and Ladders - land on an empty select; go back to the beginning.

Maybe, once the dust has settled, there will be a tutorial showing the effects of these different select choices. I thought Select, SelectWithin, SelectAdditional were pretty simple but apparently hit an empty select and worms come crawling out of the can.

With all due respect, and believe me that there is a lot of it, I’m dismayed to realize that I have to review, and possibly modify, literally hundreds of Select, SelectWithin, and SelectAdditional uses. Most are probably okay, but I can’t assume that based on what we’ve discussed here over the past few days.

This result of selecting all for empty selections is not the way it worked in Panorama 6 and not the way it was documented in Panorama X until a couple of days ago. (See the notes on empty sections in the Pan 6 documentation below) I tend to read documentation and have especially appreciated the Help system in Pan X.

I’ve understood the fact that Panorama would stop taking certain actions following an empty selection. Possibly I’ve always misunderstood into(“Empty”) as allowing me to override that and have Panorama resume running all of my subsequent code.

As for how I ended up using CheckEmptySelection, that came from a previous thread here as well as from the Pan X documentation.

From SelectWithin

and from CheckEmptySelection

In the meantime, my verification process has had almost every selection removed. Instead I’m building arrays based on the selection formulas to test the data and then select what I know will result in success. It’s proving to be faster than what I was ending up with and is reliable:

Let lvTest = ""
ArraySelectedBuild lvTest,cr(),"Invoices",?(Balance ≠ 0,CustomerID,"")
If strip(lvTest) ≠ ""
    SelectWithin ArrayContains(lvTest, CustomerID,cr()) = -1
...

Aside from the attached Pan 6 documentation below, I’ll close by saying we’re all human. Errors in documentation and coding happen and none is expected to be free of errors. I have no desire to beat up on anyone and remain one of the biggest fans of Panorama. But as I’ve done for many years, I’ll make a fuss when I don’t think things are right. I’d like to think that those of us who do have made our own contributions to making it that much better for all.

From Panorama 6 Documentation:

If I haven’t made it clear before, let me say it explicitly now – this was a documentation error on my part. The behavior of selection changed, but I didn’t recognize that when copied old Panorama 6 documentation and revised it for Panorama X.

I could change select and selectwithin so that they always retain the previous selection, in other words, turn them into safeselect and safeselectwithin. I’m pretty sure that is what you are advocating for here.

However, that would impose a tremendous performance penalty on every single select, as much as doubling the time taken for each select operation. For small databases this isn’t too important, but for larger databases, the performance of searching is already a significant issue.

If I had to do it all over again, the one change I would make would be to document this properly back in 2015, or whenever the Panorama X select documentation was written. I also would have added the safeselect and safeselectwithin statements at that time. That gives you a choice if retaining the previous selection is more important than speed.

Perfect! You have essentially implemented the safeselectwithin statement. However, you can do the same thing a bit faster by using superlookup( instead of arraybuild(, like this:

if superlookup("",{Balance ≠ 0},{true()},"default",false(),"selected",true())
    selectwithin Balance ≠ 0
    ...

Why is this faster? Both arrayselectedbuild( and superlookup( scan the database. However, superlookup( will stop scanning as soon as it finds a match. That could be the first record, in which case it would be extremely fast. In the worst case, there would be no record with a non-zero balance until the end, in which case both approaches would have the same performance. But on average, superlookup( will be quite a bit faster, since we don’t care how many matches there are, just that there is at least one match.

Even if you wanted to continue to use arrayselectedbuild to do the “pre-flight”, I would change to select Balance ≠ 0 instead of using arraycontains(, it’s going to be much faster.

Well, you definitely don’t have to review any use of selectadditional. That statement cannot fail, so this discussion doesn’t apply.

I also think it would be very surprising if this problem would occur with the select statement. In that case, you are starting with an unknown set of selected records. After the select statement, why would program code ever need to have the same unknown set of records? Sure, I can see that when manually doing selections, that’s what Undo is for. But I can’t imagine any reason why program code would rely on having the same “random” set of records after the selection.

Here’s an example of how I suppose you could use this:

select State = "AZ"
select State = "NV"

In Panorama 6, if the database had no records in Nevada, this would wind up with Arizona selected (assuming there are records in Arizona). I certainly would never write code like this, instead I always would have written it this way:

select State = "NV"
if info("empty")
   select State = "AZ"
endif

If you think you’ve written code like the first example, then yes, that won’t work in Panorama X. Personally, I think code like that should be rewritten anyway, I would call that “trick” code.

So, I think you only have to review any selectwithin statements you are using. I doubt there are hundreds of those. You should be able to use View Search to find them very quickly. Once the next release comes out, you can simply add the prefix safe to any that need it, or right now you can use either arrayselect( or superlookup( to solve this, which of course is quite a bit more work.

Once again, my apologies for this error on my part. As you pointed out, it is pretty much impossible to completely rewrite a half million lines of code, and 9,000 pages of documentation, without making some errors along the way.

So noted. I’ll do that.

Understood, but my example was simplified a bit and had a more complex formula so for now I’ll stick to aryraycontains(

Otherwise, 'nuf said.

In that case, you can’t use superlookup(, because you need that array. Also in that case, you should make a slight change to your code for performance.

arrayselectedbuild lvTest,...
arraystrip lvTest,cr()
if lvTest≠""
    ...

The strip( function only removes whitespace at the beginning and end of the text, it does not remove empty elements within the array. It will take the arraycontains( function extra time to process the empty elements.

Also, let me go back and re-propose my original solution from a few days ago. This allows you to type in your complicated formula once, even though it is used twice.

let _qformula = {somefield = somevalue} <-- put your formula here
if superlookup("",_qformula,{true()},"default",false(),"selected",true())
    executelocal {selectwithin }+_qformula
    // selectwithin succeeded
else
    // selectwithin failed, but previous selection is untouched
endif

This is the same logic that will be used in the new safeselectwithin statement.