Re: Question regarding positioning within "input array"
Posted in 1998
Jonathan, First, sorry in advance that I took so long replying to you and also that I got so long winded in this reply. For some reason, if I take too long to type in a reply, my ISP gets all confused and doesn't send the message. As to your question, there are basically two actions that the user is going to want to perform when within the input array: they are either going to want to accept what they have done or they are going to want to cancel it. (There may be ancillary actions that occur, depending on the application, but in general that should be the case.) If you place the input array statement within a while loop, you can basically control whatever you want to by exiting and re-entering the input array statement. I usually set up two boolean flags, which I name Interrupt and Escape, to control re-entry of the input array and any post-processing that may need to occur. You could probably do it with just one if you assigned different values instead of using booleans, but I feel booleans are easier to read. Although I am sure I made some typos, left out definitions, screwed up syntax, etc. the code would look something like this: -- Make sure we make at least one pass at the input array statement. let Interrupt = false let Escape = false while not interrupt and not escape input array p_array from s_array.* before row if DesiredRow < arr_curr() then next field next_row end if on key (accept) let Escape = true -- Get out of the input array statement and don't re-enter exit input on key (interrupt) let int_flag = 0 -- reset int_flag, since Informix doesn't do it for us. prompt "Are you sure you want to abandon your changes? " for Answer if Answer = 'Y' then let Interrupt = true -- Get out of the input array statement and don't re-enter exit input else continue input end if on key (delete) prompt "Are you sure you want to delete the current row?" for Answer if Answer = 'N' then -- The user must have fat-fingered the keyboard or changed their mind. Get out of the -- input array and re-enter it. Reposition the cursor on the current row. let DesiredRow=arr_curr() exit input end if on key (f1) prompt "What row would you like to jump to? " for Answer -- Make sure the specified row exists. if Answer < 1 or Answer > arr_count() then message "Specified row does not exist" continue input else -- It does. Tell ourselves where to go and exit the input array. Since interrupt and escape -- are both still false, we will re-enter and reposition wherever we want to go. let DesiredRow=Answer exit input end if after field ??? blah-blah-blah after input blah-blah-blah end input end while -- In reality, you can just check one flag or the other, since one or the other is set. if Interrupt then -- Don't do anything with the input since the user cancelled the input. end if if Escape then -- Do whatever is appropriate with the program array. end if I haven't seen Dynamic 4gl yet and, as such, I cannot speak to it's functionality. I hope it is everything it is billed to be. Unfortunately, every shop I have ever worked in has always espoused that they would, at some unspecified time in the distant future, move to a more user and programmer friendly language. Until that time, which unfortunately never arrived, I have been expected to deliver the desired functionality using Informix 4gl. Don't get me wrong. You can do some amazing things with 4gl if you can think in screwed up ways. It is great so long as you are dealing strictly with the database and SQL. 4gl's string handling could stand some major improvement, but it is adequate in the majority of situations. 4gl could use some additional mathematical functions, such as absolute value or square root, but the former is easy to get around and the latter is hardly ever needed. I'm sure there are others - these are the ones that came to mind. 4gl is, in my humble opinion, a piece of crap when it comes to interfacing with the outside world -- i.e. screen input/output and report output. It's not that you can't do just about anything you want to. You just have to work so darn hard at it sometimes and it is almost inevitable that you will miss something that will come back to haunt you. Before I get flamed on this, a problem for the enraged reader. Design the following report: Design a monthly sales report that sorts sale by department, with subtotals by department. Simple so far. Now, for selected departments - as specified by a control flag, summarize and sort these same sales by employee and print this on the next page(s) after the subtotal but before the next department. Gets a bit more complicated there. After the last department is printed, print a grand total of all sales. Back to simple, but hold on: The grand total needs to be on a summary page of all departments that contains only the departmental sub-total lines printed above. Oh, and I forgot to mention that you have no idea how many departments and/or employees per department you will be dealing with at any given time, so you will have to deal with this dynamically. Before you say this is a contrived example, I had to do a report that was very similar to this. It was for monthly distribution to departmental managers for budgeting purposes. They further distributed the employee summary to shift supervisors, so I guess I forgot a level of sorting in the above, and the summary page went to someone in accounting. One hint: This can be done relatively simply using a couple of report features. There is no need to use arrays, as 4gl can be forced to do all the work for you. You should be able to do this by defining only department, employee, summaryflag and sales_amount within your report. (Additional variables for the headings are likely necessary, but are not relevant to the problem definition.) Jonathan Leffler wrote: > Ken Vaughn wrote: > > OK, I was tired and in a hurry to go to bed when I posted the original > > reply. Here is a bit more sensible code fragment that will actually > > work: > > Ken, > > How do you adapt this code to go back to row 63 from row 97? Your > code works to get the first row to the specified target row, but not > (I think) for general motion within the array. > > Also, as you mention, it imposes a scrolling overhead. > > D4GL provides a function which displays a specified program array > record on a specified screen array line, without scrolling everything > in between. > > I accept that there are contorted mechanisms which can be made t