This code hangs on SAVE or Closing

Can you see anything here that would hang Panorama - it may hang on Save, it may hang on Close, after you add
//Form Variables

just above

FileGlobal fgCurrentYear, fgCurrentMonth

I’ve been able to duplicate this in three databases.

Before I pasted it below, I copied it from a database that would hang and pasted it into a brand new shinny database. Just Paste and Save. So there were no other elements but this procedure code, and the datasheet.

On my first Save, I got a notification saying something about failing to connect to a Save Panel.
I tried it a second time so I could get the message exactly, but that time - or rather “for now” - it allowed me to save.

But then it hung after I clicked the close window button.

I have run SSD tests and the Apple Diagnostics (restart and Cmd-D and the machine (24GB M2) gets a clean bill of health.

Any insights as to why this would hang? Dictionaries are new to me. I did try to follow the Help examples.

//May 9 2023

    The function this database is to hold the current
    and passed passwords to access the American Cryptogram
    Association website
/*Invalid entries
    If there is already a password for the specified issue/year
    a confirm message will ask if you want to replace it.
    If the issue month is invalid, or if the year is earlier
    than the current year or larger by more than one year an "invaild"
    dialog beep will appear and the entry cleared
/* Action
    A valid entry will add a new record with the specified
    year and issue month   

FileGlobal fgCurrentYear, fgCurrentMonth
FileGlobal fgCurrentPW, fgPrevPW
FileGlobal fgCurrentRecordMonth, fgPrevRecordMonth
FileGlobal fgFormIssue, fgFormPW
FileGlobal fgThisMonth, fgThisYear
FileGlobal fgMonthIssueDict
FileGlobal fgIssueMonthDict

//Key is month number (text), value is JF, MA, MJ, etc.
fgMonthIssueDict = initializedictionary(
//Key is issue month, value is month number (text)
initializedictionary fgIssueMonthDict(
fgIssueMonthDict = initializedictionary("JF","01","MA","02","MJ","03",

fgThisMonth = DatePattern(Today(),"MM")
fgThisYear = Datepattern(today(),"YYYY")

fgCurrentMonth = getdictionaryvalue(fgMonthIssueDict,(fgThisMonth))
fgFormIssue = fgCurrentMonth + fgThisYear
fgFormPW = ""

// Sort and sequence
Call PutInSortOrder

/* Get
    previous passwords from first
    and second records

    fgCurrentPW = ACAPassword
    fgCurrentRecordMonth = ACAIssue
IF info("records") > 1     
    fgPrevPW = ACAPassword
    fgPrevRecordMonth = ACAIssue
    fgPrevPW = fgCurrentPW
    fgPrevRecordMonth = fgCurrentRecordPW    

/* Autofill    
    If we ARE within the last week of the last issue
    Fill fgFormIssue with the next Issue ID and move to fgFormPW

Okay - it did look indented when I pasted it into the forum message box. I’ll review past posts on how to maintain the indenting for easier reading. Consider me admonished. :disappointed_relieved:

I was able to duplicate this problem. Fortunately, the Xcode debugger gave me a clue.

The problem is this code here.

You started writing an initializedictionary statement. But then you lost the plot in the middle of the line, and started over again on the next line using the initializedictionary( function. However, you left the line before in an incomplete state. This left the Panorama compiler completely confused, and caused the hang (of course this is a bug, it should have just caused a syntax error).

Removing the incomplete line

initializedictionary fgIssueMonthDict(

completely fixed everything.

Jim, Thank you for the second pair of eyes. Because the dictionary was defined correctly in the second line, it worked great when I accessed it. And, as you noted, I did look at the bottom of the Initialize procedure window (status) and it was happy as a lark.

Yes, it was one foot in the function boat and one foot on the statement dock. I started with a statement, then got befuddled about how the dictionary gets assigned to a variable in that form and switched over to a function.

From what I see below Creating a Data Dictionary, it appears that the first parameter of the Initializedictionary statement would be the dictionary variable; mailingaddress in the Help example?

The following is a guess … So a statement example would be

local mailingaddress,
initializedictionary mailing address, "Address","3987 Olive Court", "City","Tustin", "State","CA","Zip","92841"

At first glance in the help, I didn’t see how the statement style could assign the values to a variable unless that variable were on the left-hand side, which would make it a function.

Okay, onward and upward. :smiley:

As is the case with all operations that may be carried out using both a statement and a function, there is a separate Help entry for each, in this case the statement initializedictionary and the function initializedictionary( (all function names include the opening parenthesis), each of which states the appropriate syntax.

I don’t see how that could be, because that code wouldn’t even compile. As written, you could not run that procedure at all.

There are many, many, many statements that assign values to a variable (or field).

BTW, I think a dictionary might be overkill for this application. Perhaps a simpler method would be to do this:

fgCurrentMonth = switchmatch(fgThisMonth,"01","JF","02","JF","03","MA", ,,, ,"12","ND")


It is a puzzle but not worth pursuing. My data definitely shows that at least one time, the dictionary action pulled the correct values to calculate a “sort order” number. As the function part is correct, I can’t imagine trying to add the statement later. Perhaps I put that action in a separate, short lived, test file just to isolate the dictionary action.

Thank you for the switchmatch suggestion. I’ll look into it. At first I was just going going use an array, but then I thought it would a handy exercise in learning about dictionaries.

The whole little project, one form and database with only two records - the result of which which could be handled in my next “pull this text from website” project with permanent variables and a message box - is more an exercise in starting to get the lay of a very big land. It’s sort of like - animal rights activists hide your eyes - walking into a room with dozens of skinned cats.

Using a dictionary here is really a pretty good idea. To be honest, it could be slightly faster than using switchmatch(, I’m not sure without testing it (and it would also depend on how many items were in the list). For this particular application, really either of these approaches is good. I probably should have said that switchmatch( was an “alternate” method rather than saying that a dictionary was “overkill”. Dictionaries are a great feature and your impulse to learn more about them is a good one.