I've got a file with data (VB(218)), it has grown over the years to include various attributes, but rather than actually including these as new columns, they have been added as alternate "punctuation" in various time fields, i.e. the default hh.mm format has been changed into one of

hh:mm

hhxmm

to indicate special conditions, like a delay that was caused by specific reasons. We're now discussing adding two more variations,

hh-mm (moving west)

hh+mm (moving east)

For those occasions where a timezone has been crossed. The current programs use country data to detect these crossings, but we currently have a growing number of border crossings where the crossing times are such that we have to change auto-detections thresholds again and again, and at some stage changing them may no longer be possible...

So, given that the actual data in the file never exceeds column 192 (aka we have 26 spare columns), it would seem rather a lot more logical to actually expand an already existing flag field and use that, which would have the added advantage that we can use times in ISO8601 (hh:mm) format which would make it easier to exchange the data with spreadsheets on the PC.

I've already done a trial conversion using the ISPF editor, using a combination of excluding, hiding, cutting and pasting, but ideally we need something one-pass using DFSORT/ICETOOL, an edit macro in batch seems to be using an awful lot of CPU, so that we can run the old and new programs parallel for a while while testing. I've got no trouble doing it in multi-pass mode, by first expanding the existing flag field, to fill that on subsequent passes with translated current "alternate" punctuation characters, but can this be done in a single pass, even when some current records use two of these "alternate" punctuation characters?

As for positions, the current flag field occupies column 66, and

a ':' in column 61 should result in an 'F' in column 67

a ':' in column 71 should result in an 'Q' in column 68

an 'x' in column 71 should result in an 'x' in column 69

a '+' in column 78 should result in a '+' in column 70

a '-' in column 78 should result in a '-' in column 70

Only the ':' in column 71 and '+' (or '-') in column 78 can appear together, which may, and this has already been suggested, make it possible to actually combine columns 67-69 (so that we can have another conversion in a couple of years...)

The only other condition is that records starting with '{' in column 1 should be returned unchanged.

The first IFTHEN is to get rid of the test for { from within the other WHEN=(logicalexpressions). If you have lots of those lines, it may be more efficient to use AND and NE for it in the others.

The only issue is where you can have more than one test being true on the same record. This can happed with the 71 equal to ":", so that must have HIT=NEXT to continue the IFTHEN processing for that record. By default it stops when a WHEN=(logicalexpression) is true.

You only need the one HIT=NEXT, as the other conditions are mutually exclusive. You can rearrange the IFTHENs (into order of frequency of occurence in the data) as long as the first WHEN=(logicalexpression) that can also have a second truth on the same record has the HIT=NEXT. If you put the "signs" checks first, both would require HIT=NEXT.

The HIT=NEXT simply says "carry on the IFTHEN processing until true, or no more IFTHENs". If you want to carry on after the second hit, you'd need HIT=NEXT on that IFTHEN as well.

*INREC if the error is associated with an INREC statement. *OUTREC if the error is associated with an OUTREC statement. ddname if the error is associated with an OUTFIL statement.

rsn: The reason code associated with the error. The reason code (listed later in this section) helps you determine the specific cause of the error.

n: 0 if the error is not associated with an IFTHEN clause. Otherwise, n identifies the number of the IFTHEN clause associated with the error (starting
at 1 for the first IFTHEN clause).

If you use BUILD, you have to specify everything, and for fixed-length records all the output has to be the same length. OVERLAY is better for this, and can also be used to extend the records. You only need to specify the data that changes/is new.

You can consider IFOUTLEN for getting your records the same length, or ensure that in the OVERLAY, finishing with ,223:X), which says put a blank in column 223 (note, I may not have counted correctly) and fill any intervening positions (between the last byte of data and this column) with space.

No, for fixed-length records you have to know the length if you are extending (and in some other cases, like making a REFORMAT record).

For fixed-length records you can't say ,68)) to mean "from position 68 to the end of the record". That is only possible for variable-length records.

and although this should work, I still have '-' and '+''es left at position 84 of some records, with those records still containing blanks at position 72, despite adding a HIT=NEXT to everything. No error messages to help me this time...

And while posting this I realize why - no Q records, so no reformat yet...

That's because there is no "no-op", so you make one up - "let column one be the value of position one for a length of one".

There is no possibility of a false hit for a blank line, so ditch that.

Use OVERLAY instead of BUILD. If all the columns and data in an OVERLAY are within the current copy of the record, the current copy of the record is simply updated. With BUILD, a new copy of the record is made.

You don't need to set a flag in one WHEN= and then test it and take some action in the next (if that flag has no value in it in the input record). Just clobber the position tested with OVERLAY (as you have done in one case).

You only need HIT=NEXT when testing the 71 for :, at least if it is as you stated earlier and that is the only time there can be multiple codes of interest on the same record (multiple here is two, the : and either + or - (of significance).

You don't need a single BUILD in this code. You just OVERLAY the literal values, at the correct positions. You have the IFOUTLEN ensuring everything is 218, but if the input is 218 (implied by your BUILDs) then you don't even need that, as none of your OVERLAYs go outside the current record.

If you change the BUILDs to OVERLAYs, and remove the IFOUTLEN, then there is no dependency on knowing the record-length. If you need to extend the records, then yes, the IFOUTLEN is the way to go.

A comma has emerged that wasn't mentioned before.

For the +/- which remain in 84 with no other markers, I'd say you have blanks in the first four bytes, and you have no HIT=NEXT for that. I'm not suggesting you add HIT=NEXT, I'm saying that line is redundant, just not as redundant as I thought earlier, only more so. To put it another way, it is the source of your problem.

Your are clobbering 71 with your long literals. If you want to ensure that everything is space to start with (if that is necessary) you can use an IFTHEN=(WHEN=INIT to OVERLAY an appropriate amount of space (and a comma if now needed) into your flags.

I just had a go at updating my sample with what you seem to want, but from your current code I no longer know enough about your data to do that, eg:

That tests 71 for x, then places an x in 71, along with some blanks and a comma around about. Then tests 71 for x again, and despite the comment drops a dot in 77.

I'd have updated mine to do the clearing the indicators back to what they were originally (before reused) in the OVERLAYs that were there. If a comma is needed on those records as well, that is easy to also include in the OVERLAYs.

With repeated use of the same position and values indicating things I'd also code the whole thing using SYMNAMES, which basically can obviate your comments (which can potentially be wrong and misleading) with code which tells its own story (and can still be wrong, but refelect 100% what is documented).

Originally I used this in my 80-byte test-data:

Code:

{
:
:
x
+
-
: +
: -

You could annotate those lines, say starting at column 10, with what should happen, extending as necessary. Explain the new output, and if you can't get completely there yourself, I'll have something to test on.

If you have superfluous HIT=NEXT it will affect processing time. Whether you would notice on not depends on the amount of data. As important, it affects the understanding of the code/data. If you're happy, I'm happy.

Definitely affecting resources more are the redundant BUILDs, and the BUILDs which can still be replaced by OVERLAY.

If you have superfluous HIT=NEXT it will affect processing time. Whether you would notice on not depends on the amount of data. As important, it affects the understanding of the code/data. If you're happy, I'm happy.

Given that this is only needed for a short while, in order to run the old and new versions of the program next to each other, simplicity is preferred over anything else. Still no decision on keeping old/introducing new format, usual "It's been working like this for ages, why risk breaking it..."

If you are selectively inserting data, the later columns are not going to be aligned across the whole file. I had thought you were reusing an area which was already only blank, and didn't check back to anything from earlier.

I'll dive into the manuals to see what "CHANGE" is doing. In the meantime it's come to the attention that end-users have all kinds of scrips to work on the current file with all its idiosyncrasies, and needlessly to say plenty of these scripts no longer have an owner, "it just works...".

I still want to go for explicit flags, and have created another set of sort control cards to convert the data back to the old format, sigh...