Transferfields

Hi,

We had a little problem. We solved it, but I don’t understand where was the problem.

This is the code that is ok:

Mn.RESET; (Mn = 2000000006)

Mn.SETFILTER(Name, ‘company1’);

IF Mn.FIND(’-’) THEN BEGIN

Mbme.RESET;

Mbme.CHANGECOMPANY(Mn.Name);

Mbme.SETFILTER(“MWSt Produktbuchungsgruppe”, ‘HW1-19|SONST1-19’);

Mn1.RESET;

Mn1.SETFILTER(Name, ‘company2’);

IF Mbme.FIND(’-’) THEN REPEAT

IF Mn1.FIND(’-’) THEN BEGIN

Mbme1.CHANGECOMPANY(Mn1.Name);

Mbme1.TRANSFERFIELDS(Mbme); ß----------------------------------------

IF Mbme1.MODIFY THEN ;

END;

UNTIL Mbme.NEXT = 0;

END;

And this is the code that doesn’t work right:

Mn.RESET; (Mn = 2000000006)

Mn.SETFILTER(Name, ‘company1’);

IF Mn.FIND(’-’) THEN BEGIN

Mbme.RESET;

Mbme.CHANGECOMPANY(Mn.Name);

Mbme.SETFILTER(“MWSt Produktbuchungsgruppe”, ‘HW1-19|SONST1-19’);

Mn1.RESET;

Mn1.SETFILTER(Name, ‘company2’);

IF Mbme.FIND(’-’) THEN REPEAT

IF Mn1.FIND(’-’) THEN BEGIN

Mbme1.CHANGECOMPANY(Mn1.Name);

Mbme1 := Mbme; ß--------------------------------------------------------------------

IF Mbme1.MODIFY THEN ;

END;

UNTIL Mbme.NEXT = 0;

END;

What can be the reason? What is exactly the difference?

Volker

The TRANSFERFIELDS transfers fields to another record. It will NOT have the same version as the original one. So this is best used for transferring fields of different types of records (e.g. Sales Order To Sales Shipment)
The := copies the record and keeps the same version, so for the code you made it is best to use :=

I thought so too. But this was the code that doesn’t work.

It seems so that the tables are not equal but they are exactly equal.

volker

What exactly didn’t work? What went wrong?
What happens if you change the "IF …MODIFY THEN ; to a MODIFY without the IF THEN?

TRANSFERFIELDS works by copying from / to rec using the Filed No. Is Destination identical to Source?

Check the small print in the HELP for TRANSFERFIELDS.

TRANSFERFIELDS (Record)

Use this function to copy all matching fields in one record to another record.

Record.TRANSFERFIELDS(FromRecord [, InitPrimaryKeyFields])

Record

Data type: record

The record to copy the contents of the fields in FromRecord to.

FromRecord

Data type: record

The record from which to copy.

InitPrimaryKeyFields

Data type: Boolean

Default value: True

Comments

TRANSFERFIELDS copies fields based on the Field No. property of the fields. For each field in Record (the destination), the contents of the field with the same Field No. in FromRecord (the source) will be copied, if such a field exists.

The fields must have the same data type for the copying to succeed (text and code are convertible, other types are not.) There must be room for the actual length of the contents of the field to be copied in the field to which it is to be copied. If any of these conditions are not fulfilled, a run-time error will occur.

If the InitPrimaryKeyFields parameter is set to false, the TRANSFERFIELDS function will not change the timestamp or the Primary Key fields of the destination record.

If the InitPrimaryKeyFields parameter is set to true, and the records are in the same table, the TRANSFERFIELDS function will change both the timestamp and the Primary Key fields of the destination record.

If the InitPrimaryKeyFields parameter is set to true, and the records are not in the same table, the TRANSFERFIELDS function will change the Primary Key fields of the destination record (if the fields fulfill the conditions specified above) but the timestamp of the destination record will not be changed.

Hi,

the IF … THEN is without any reason.

The error-message:

Another user has changed the record …

And I haven’t any problems when I use Transferfields

volker

Now I understood.
The reason is the CHANGECOMPANY. You should put it AFTER the :=

I think you can make you code better and more efficient like this:
Mn.RESET; (Mn = 2000000006)
Mn.SETFILTER(Name, );
IF Mn.GET(‘company1’) THEN BEGIN
IF Mn1.GET(‘company2’) THEN BEGIN
// GET is better THEN FIND
// why do a Mn1.GET (or FIND) for every record of Mbme. You do it once and if it doesn’t exist, you can already stop processing
Mbme.RESET;
Mbme.CHANGECOMPANY(Mn.Name);
Mbme.SETFILTER(“MWSt Produktbuchungsgruppe”, ‘HW1-19|SONST1-19’);
IF Mbme.FIND(‘-’) THEN
REPEAT
Mbme1 := Mbme;
Mbme1.CHANGECOMPANY(Mn1.Name); // FIRST := and then CHANGECOMPANY
Mbme1.MODIFY(FALSE);
UNTIL Mbme.NEXT = 0;
END;

Hi,

it doesn’t work.

It is something else because the filter for Mn1 is

Mn1.Setfilter(‘company2…company5’);

And only for company2 it doesn’t work.

For company3…company5 it’s work.

sorry for the change in this post.

volker

Forgot 1 thing:
The way I explained it works if you are working in 1 company.
Because you are working in different companies, the records are different (even if they have all fields the same). So in reality they should be considered different tables and thus a TRANSFERFIELDS is the correct way to do it.
Sorry for the confusion I created before. [:$]

I have had this same problem and came up with this voodoo…

The theory I have is that the := copies the entire record including the database version information. If the database version is maintained per company, then there is a potential for the database version in the copy-to company to be higher then the one you are copying from. When the system goes to modify, it checks the database version and gives you the error that another user has modified the record even though no real change has happened. By using transferfields, you avoid the database versioning issue.

This is just a theory, if anyone can confirm or discredit that would be great.

Hope this helps,

Zarryn

ok.

when I use the := , it may be work but doesn’t have to.

this is the only general statement one can give. Have I get it?

and then , therefor the correct way is to use transferfields.

thanks

volker

I hereby confirm your theory. [;)]

If you work in 1 company, := is better.

If you work with CHANGECOMPANY, you need to use TRANSFERFIELDS.

You get the ‘another user has modified…’ error when one function does a MODIFY, and then another function does a MODIFY on the same record, without having the changes of the first one passed back to it.

Either pass your record into the function by reference (i.e. check the VAR checkbox in the variable declaration), or do a GET right before you MODIFY.

True,
But in this case I think we have another issue:
Eg.:
record X in company Y has version 10
record X in company Z has version 20
Now if you use := to move record X from company Y to company Z, it probably also copies the version no. (so in this case 10).
When you do a modify of record X in company Z (with version 11 now [remember it comes from company Y]) it first checks the original version (10 but in company Z it has 20) so Navision thinks that someone changed the record.