Formulas & Programming pdf

In looking for info about the Record ID attribute, I ran across a mention of the pdf book Formulas & Programming. Is this available anymore? I’m using PanoramaX. Thanks!

The old Panorama 6 documentation is included with the Panorama 6 installation. You can get the Pan 6 installer at:

Once you have downloaded the file you can open the .dmg file and it will have the Panorama 6 Installer as well as another folder called Documentation. The folder contains all the Pan 6 PDF files including the Formulas & Programming.pdf file you are asking about. The entire Documentation folder is 150 MB while the single PDF you want is just under 16 MB. You can copy just the file you want or the entire folder to your hard drive.

Note that much of what is in these files still applies to Panorama X so I still find them useful as an additional resource along with the Panorama X Help file and the available videos.

Can you tell me where you found this mention? It should be removed.

Gary is correct that you can get this PDF file by downloading and installing Panorama 6, but that installation can be difficult on recent versions of macOS. Actually, reading Gary’s post he does describe a way to get the docs out the installer without actually running the installer. Anyway, no special technique is needed, the PDF files are still available as separate downloads. Go to this page:

and look for Where can I download Panorama 6 Documentation? You’ll find direct links to all of the PDF files that were included with Panorama 6, without having to actually download the entire Panorama 6 installer.

Now that I’ve told you how to get these PDF files, I would suggest being quite cautious with them. As Gary mentioned, a lot of the material in these files still applies to Panorama X, but there’s also quite a bit that has changed. So you might find them a bit frustrating – but at least you will be able to more fully appreciate how far forward Panorama has come in the past decade!

Thanks for the answers guys. I saw the mention in this post on the forum, it’s quite old I think

and I’m thinking it’s deprecated and maybe I’ll leave it alone. I was looking for the language to have a field in the database that displays the recordID of that record, because I want to be able to “save states” of the data.

Longer explanation is the elements of my dafabase are simple text strings, short paragraphs. For project A i want to select a subset as active, and export that; while project B my selection set might be different. I thought If I were to create a project record that included the recordIDs (or perhaps a programmatically-assigned serial numberl) of each chosen paragraph, then I could recall the state of the database for the various projects. As a learning noob, I kind of wish there was a place (maybe this is it??) where Design approach can be discussed as opposed to getting cogs and wheels questions answered. Like, a musician wanting to learn about theory before learning hot licks…

This is definitely the place for that! :grinning:

Are you saying you want to export the data along with the record ID’s, and then later restore the database to the same selection that was in place when the data was exported? You could potentially do that, but it would be pretty complicated, and doing the restore might be on the slow side, depending on how many records were in the selection.

If you are just going to have two projects, A and B, a fast and easy method might be to create two additional fields, one for each project. When you export the data, you could fill the field for the current project with a particular value. Later you could simply select for that value to restore the same selection.

Sadly, what I am after would have more than two manifestations.

The application is for writing simple specifications for small architecture projects. There are commercial products available for large complex projects but nothing useful available for smaller work, which is what I do.

A typical spec might consist of 4 to say 10 pages of text when exported, each section is a short, numbered paragraph, probably half of which are standard boilerplate, most of the rest are lightly-edited boilerplate, with a few relatively custom items tailored for the particular project.

What is common to do currently is to use the text of a similar project and edit that. This has the disadvantage that paragraphs that were deleted when editing that previous spec are not available for review. So you spend a lot of time searching through a bunch of old projects to get everything (when did we do helical piles last?)

I thought it might be useful to me to have a database that consisted of a masterfile that I would make, so that for example lets take gutters. I might have a paragraph for aluminum gutters, one for copper gutters, and one for built-in gutters. Now when I am preparing a new project spec, I can either choose to include one of those sections as-written, or, I can write an entirely new paragraph and add it to the database and include that, or, I can clone one of the sections and edit it, and include that. Always adding to the masterfile and improving the resource.

So, my office might do, let’s say, two projects a month, call it 25 a year. A spec for a small addition might have 35 to 50 paragraphs, rarely more than a hundred. Each paragraph is from one to maybe ten sentences, to give you the order of magnitude of the size of the dataset.

So it would be nice to save setups from projects (to use a starting point for similar work) but the exported text is the actual project archive. The other way I could do it, would be every time a project is finalized (upon export), add a field indicating such to each of the included records, so that to recall a previous final configuration, instead of looking to the project record for a list of the sections to be included, but rather to ask the included sections to raise their hands, given the project name. so each paragraph used on the Smith project would have a field added (when the final export is done) ID’ing that it was used there. And other than a list of projects, everything in the database would be tied to the individual paragraphs themselves. This seems like a much more oop-y solution, does that sound like a more robust approach?

The rest of the application is formatting the numbering of the spec sections when exported, to handle that tediousness, a fun little outline number-er that might have multiple formatting options to prettify the printing.

Thank you for listening, any recommendations are welcome.

Have a field in your master database named RecordID. Have a .CurrentRecord procedure with RecordID=info(“serverrecordid”) included in the code. In your project database have a field named something like SpecIDs and enter each RecordID number from the master database that is used in the project with each one separated by anything you want - say a comma. Now to get the selection in the master database to show all the ID’s used in any project you would have a procedure that gets the list from the project file and selects those items in the master file. Something like this would be run from the project file:

let recordIDlist=SpecIDs
opendatabase "Master Specs"
select arraycontains(recordIDlist,RecordID,",")

This will open or bring forward the Master Specs file and select only those specification records that were used in the current record in the project file.

Note: I am very familiar with this subject in that I owned and ran a Reprographics business (actually a Blueprint shop in the old days) for many, many years. Back in the day we would get the specs from the architect all typed on parchment with paragraphs taped together, areas cut out and overwritten and a combination of old tattered sheets along with some brand new pages. It was a nightmare for the architect and an even worse one for the printer. Some of the more common pages were used for thousands and thousands of copies and almost worn to shreds. I do not miss those days.:relieved:

The scheme I suggested above makes me wonder if maybe a couple of new statements could be developed to save the current record selection states for later reselecting. I made a couple of examples to get and set the selection state:

GetCurrentSelection variable
let theCurrentSelection=arraybuild(¶, “”,{info(“serverrecordid”)},{info(“visible”)})
setparameter 1, theCurrentSelection

SetSavedSelection variable
let theCurrentSelection=parameter(1)
select arraycontains(theCurrentSelection,info(“serverrecordid”),¶)

These might be handy for various situations were a simple Undo is not realistic and allow for the ability to restore historic selection states.

I’m wondering why you are suggesting making a copy of the record id into an actual database field. The record id can be accessed at any time with the info(“serverrecordid”) function, there’s no reason to duplicate that number into a field. All that does is take up extra space and leave the possibility that someone might edit that field and break things. Unless I am missing something. So Gary’s code would change slightly to:

let recordIDlist=SpecIDs
opendatabase "Master Speces"
select arraycontains(recordIDList,info("serverrecordid"),",")

The .CurrentRecord procedure would not be needed at all.

I think your scheme is probably ok for Matt’s proposed application, where each selection is going to have 25-100 records in it. But I don’t think it’s a good idea for a general Panorama feature. What if the selection contained 5,000 visible records, or 50,000. Your theCurrentSelection array is going to be gigantic and performance of restoring the selection is going to be abysmal. I don’t really want to put something with a performance profile like that into an official Panorama statement.

I think Matt has a somewhat unusual application where actually saving a list of selected records makes sense. In most applications, it makes a lot more sense to save the criteria that were used for the selection, not the actual list of selected records.

This thread did give me an idea for a new statement that could be a nice minor enhancement to Panorama. I’m not going to post it here since it turns out it really doesn’t apply to Matt’s problem, but Gary I did write it up on Bitbucket if you are curious.

My interpretation of Matt’s usage was that he was picking and choosing as he built his specifications and not selecting them all at once so they may never be simultaneously selected until some time in the future.

I’m still not understanding why a copy of the record id number would be helpful.

Perhaps I could see a procedure where he actually selects an item by copying the id into a field in a different database, but that would be copying the id into a different database, and wouldn’t involve the .CurrentRecord procedure.

On further thought, please note this tip from the info(“serverrecordid”) function.

Note: The ID number is guaranteed to be unique, but is not guaranteed to be unchanging for all time. For example performing a new sharing generation will assign a new ID number to every record in the database.

I think it’s probably not a great idea to use this ID as a long term way of saving selection state. If you need to do that, you should probably make your own unique ID for each record, probably using the .NewRecord procedure and perhaps using something like the timestampstr( function or the info(“guid”) function, or simply using an auto-incrementing counter (field default value of +1).

Gary! thank you for bringing back those memories of ammonia and leroy sets and even kroy lettering; thanks also for the ideas.

From what Jim says below I think I will have to create and store my own serial numbers for each element, playing with the recordID can give unexpected results, it seems. I am also not going to rely on the selection state of the elements, rather I will make a status field that can be set to Exclude, Pending Review, Draft and Final for each item, and basing the font color of the text on that status, to give immediate visual feedback of the progress of the document.

When the editing is complete and I am ready to export I will make the selection of all Final elements and Export selected. I think it will have to be implemented so that there is always a single active project, and switching projects forces a save-state onto the project record, so I can switch back and the circumstances of the previous project would be restored. This means that every project will have to store the status of anything that is not excluded. Any new sections added to the database will be assigned pending review status by default.

Thank you for helping me clarify this.

That is a very key piece of information, Jim, thank you. a roll-my-own Serial Number is definitely the way to go in this situation. RecordIDs are for something else, clearly. As I said above, I am also going to stay away from using the selection state as a flag for the in-or-out-ness of each paragraph, I will set a status flag and examine that. For example I might be working on three projects simultaneously, so the selection state isn’t gonna do the job.

It seems when I open the file to work on, I will choose the project, and then do the selecting and editing within the project. I will have a master project which is all the sections, and then my work projects will each be different subsets of them. If that doesn’t wave any red flags here, then I think I have what I need to begin setting up the databases and code. I’ll likely be poking my head up as I bump into walls in the dark, and I can’t tell you how helpful this is. Thanks!

A bit of followup on this topic, there is a way to save the current selection state into a field. Matt, I don’t think this will help you as you are going a different way, but it might be useful to someone in the future so I will post it. Suppose you have a text field named SavedSelection. Then this 3 line program will put the word YES in that field for every record that is selected, while clearing all other cells in this field.

field SavedSelection
formulafill ?(info("visible"),"YES","")

You may not be familiar with the fillall statement, in fact, I forgot about it myself and just ran across it accidentally tonight while working on something else. It’s new in Panorama X. This statement modifies the following formulafill so that it will process ALL records, not just the selected ones. This allows the formulafill to clear out the unselected cells, which normally it couldn’t touch.

As I’ve written it this technique can only save one selection. If you treated the SavedSelection field as a text array, you could store multiple named selections. For example, this would save the current selection as Bob’s Selection.

field SavedSelection
formulafill ?(info("visible"),sandwich("",«»,",")+"Bob's Selection",«»)

Later, you could restore this selection like this:

select arraycontains(SavedSelection,"Bob's Selection",",")

You could save as many different selections as you want. I’m using commas as delimiters, but you could use any character (or characters) that you want.

If later you wanted to forget about Bob’s Selection, you could do this:

field SavedSelection
formulafill arraydeletevalue(«»,"Bob's Selection",",")

Of course you would probably want to use a variable for the selection name instead of hard coding it as I have done in this example.

Some of you may not be familiar with «», that simply is a shortcut for “the current field”.

If you wanted a list of all of the saved selections, this formula will get you that.


Caveat – I haven’t tested any of this code, so there could be syntax errors, mismatched parentheses, etc. But the technique will definitely work.


Fillall and your method of using SavedSelection field as a text array looks very useful. Checking the Help page on Fillall I’m surprised to see it’s listed for use prefacing FormulaFill but not simple Fill statements.

…Could be syntex errors… Methinks the last line of your code for forgetting Bob’s Selection should be:

formulafill arraydeletevalue(«»,"Bob's Selection",",")

Thanks, you are right, so I went back and edited the original post to make the correction.

I think I understand your method, but I’d like to restate it as I get it, in case I am missing something.

To save a configuration of records (such as the set of all selected records) in a database, each record has a simple text field devoted to the task. When the user wants to commit and save the state, they would take an action, such as pressing a button. The sample code above would then append an identifying text label and a delimiter to the text already in that field. You also listed code that would provide, in list form, all the saved states for a given record, and a way of deleting a specific saved state from all the records in the database.

That text field could grow to be lengthy, but that is not a concern on the scale of this particular project.

I think I will be making two databases that interact, one for the project data and one for the specification content; from a design standpoint, which of those databases would be the preferred location. I imagine that a given record might get deleted at some point, although I suppose I could simply ‘obsolete’ it and not delete it. My experience is that the less housekeeping I have to do the better. But this is a new realm for me.

Thanks much

I think you’ve got the idea.

The text field could indeed grow to be lengthly, but as you say, for the number of records you are envisioning that is not going to be a problem.

If a record gets deleted, it would automatically get deleted from the saved state. In fact, I’d say that was an advantage of this scheme.