Is it possible to do a Deep Assignment from a TPS file to a Queue

Hi,

To make my processing faster I want to switch from TPS to TPS to TPS to Queue.

I used to use His:Record :=: Inv:Record for the TPS files.

I now want to assign the TPS records to a Queue

I have already created the Queue: same field names and sizes.
I know I can assign each field in the Queue to the field value in the TPS file.
But looking at assigning it faster with less coding.
The TPS file have ± 150 fields so assigning each field is lots of coding.
In this one procedure I have 16 files for which I need to create Queue assignments.

Is there something like this for Queue: QHis:Record :=: Inv:Record

Regards

Johan de Klerk

exactly the same for Queue.

From the help:

destination :=: source

destination
The label of a GROUP, RECORD, or QUEUE data structure, or an array.

source
The label of a GROUP, RECORD, or QUEUE data structure, or a numeric or string constant, variable, procedure, or expression.

Hi,

Thank you very much.
Your comment put me on the right track

I was trying to do it the same as with TPS files: His:Record :=: Inv:Record

I had my assignment to Queue as:
MQPreFix:Record :=: Inv:Record
Add(MyQueue)

It should be:
MyQueue :=: Inv:Record
Add(MyQueue)

Regards

Johan de Klerk

yes, like this. …

Yes you can use a deep assign between any two groups ( a file record is a group, a queue buffer is a group).

However, when the two groups are identical (or even when one is shorter than the other, and they are identical up to the end of the shorter one) then you WANT to use a regular assign instead of a deep assign

Hi Mark,

Thanks for your reply.

Now you have totally lost me.

Please explain a bit more in detail what you mean.

Regards

Johan de Klerk

OK, so a deep assign the X :=: Y is a special assign which loops over the two groups, looking for matches of label names (prefixes excluded). If you were to code this yourself, you’d use the WHO(group, n) command. Once a match is found there is a simple assign of the field Y to X ( x.yada = y.yada), which might include a data type conversion. Just because the labels match, doesn’t mean the data type matches.

On the other hand, a simple assign X = Y of groups, looks at the number of bytes in each group, and copies the smaller number bytes from Y to X. A simple movemem api call. (Again, in this context a group is a group, file:record or a queue buffer.)

As you can imagine there is a quite a bit more overhead to the deep assign than the simple assign.

So if you have matching structures, then just use the simple assign.

Does that help ?

Hi Mark,

Thanks for the detailed explanation, I think I understand.

So instead of doing: MyQueue :=: Inv:Record
I would do MyQueue = Inv:Record

Regards

Johan de Klerk

Yes, you want: MyQueue = Inv:Record

FYI: You can declare MyQueue as

MyQueue  QUEUE(INV:Record)
         END

What’s nice about the above declaration, is that MyQueue automatically changes as the INV:Record changes.

However when working in an APP,
I think the derived fields inside of MyQueue do NOT show in the datapad.
Which can be an issue depending on how you’re using MyQueue.
Disclaimer - I don’t use APPs, and avoid the IDE in general.

Only when the structures are exactly identical. If they’re not, then deep assignment (or individual field assignment) is better. There are exceptions to this, but…

So instead of doing: MyQueue :=: Inv:Record

I agree with the simple assignment. But, I think memo field(s) (if any), may not work with either of this approach.

Thanks

Hi Mark,

Thank you very much and thanks to everyone that replied.

Mark you have actually already answered a question that I wanted to ask with this:

Now I don’t have to worry about manually keeping the Queue declaration in sync with the TPS file.
This is a very nice tip.
I was able to remove ± 2000 lines of hand code for creating my 16 Queues and manually declaring each field in the Queue.

The only thing I added was a Prefix for the Queue:
MyQueue QUEUE(INV:Record), PRE(TmpMyQueue)
END
else it gives me Duplicate Errors on each field in the TPS file.

Man you guys rocks.

Regards

Johan de Klerk

1 Like

Agreed, since memos and blobs are declared outside of the record you’d need to declare and copy them separately.

Will this also work for a SQL file instead of a TPS file?

The conversation about simple assigns ‘=’ vs. deep assigns ‘:=:’
applies to all groups (and a record structure is a group).
Same goes for queue/group derivation as well as LIKE(x) notations.

We declare file structures (pretty much) the same way for all file drivers
So, yes it would apply to SQL files as well as TPS.

Seems like a very good technique to know. Thanks Mark…

If i want to assign all the data from tps file to a queue then can we do it using deep assignment?? i don’t want to loop through each record in the tps file. I just want to direct assign all the records

No you can’t do that.

No. As Mark says, that’s not possible.
All this is Field assignment only.
Queues and files require row by row attention.

This requires jFiles from Capesoft, but you can transfer rows from a TPS file to a Queue.

MyRecords JSONClass
  CODE
  MyRecords.Start()
  MyRecords.SetTagCase(jf:CaseAny)
  MyRecords.Save(MyTPSTable)
  MyRecords.Load(MyQueue)

This will save all columns in the TPS file to the Queue that have the same name.
Additionaly, you can use a VIEW on the TPS file and use the VIEW with jFiles instead. This allows you to set a filter on the VIEW if you want to control which rows from the file are included.

2 Likes