I need to create a copy of a record to a separate table before changing the Revision value and deleting the contents of several fields. I've got the update to the Revision value working, and how to delete the field contents - now I need to figure out how to copy the record before making these changes. Unfortunately, there doesn't seem to be an APICopy action.
No, if you have looping relationships form the Parent down to children / grandchildren it will not work.
I had thought that you felt that if you did the copy parent child at the parent level that it might work. And then you would figure out how to add the grand parent manually.
Yes, that's the idea - I know I can create a master detail button on the parent level, but I'm just not sure how to format that code. I asked the looping question because I had been under the impression that if I had any looping relationships AT ALL in the app that it wouldn't work, I didn't realize it was just the relationships directly related to the tables I'm trying to manipulate.
When you run an API, when it fails it will spew back on the screen error messages and when it succeeds, it will also spew back on the screen with a success message.
So once you get it working, then you will need to have what is called a redirect to land the user somewhere or else the user will be exposed to the success message which they will think is an error message.
The format for that is
$CopyMasterDetail & "&rdr=" & URLEncode(urlroot() & "db/" & .... the rest of the URL where you want to land the user).
Okay thank you! I will work on that and let you know when I have it working. I was looking at the API guide a bit earlier and trying to learn about how it works.
Thanks! I got it working - it is successfully making duplicates of the parent and grandchild records.
Is there a way I can specify the value of a certain field with this API call? I know then you use API to create a new record you can specify the value of fields, can you do the same with API_CopyMasterDetail?
So when you use the Copy Master detail it will copy every field, like it or not. So what I used to do do when I have fields to clear out or fields to change, like say a [Status] field would be to have a formula URL field which would detect that the record name now begins with "Copy of", and and make the users push a big red button for Copy Step 2. That would clear certain fields.
Another probably better option now with less code is to use an Automation to do this. Especially if you are not landing the user immediately on the Parent record you just created, then the Automation will have the split second it needs to run and do the updates before the user sees the record.
However, you can write your own recursive script that executes in the browser using other API methods and JavaScript. The fact that the script is recursive is not really a difficulty as using a feature in JavaScript called async generators you can easily iterate through the relationship tree and at each node (ie record) of the tree perform the appropriate copy or initialization of a field. In fact, it is possible to iterate over the tree in Depth First (Inorder, PreOrder, PostOrder) or Breadth First (Level Order) order:
Here is a quick script that recursively iterates over a table which is self-related:
async function* generator(dbid, rid, clist, relatedFid) { let clistArray = clist.split("."); let queue = [rid]; while (queue.length) { let recordID = queue.shift(); yield recordID; let xml = await Promise.resolve( $.get(dbid, { act: "API_DoQuery", query: '{${relatedFid}.EX.${recordID}', clist: clist, fmt: "structured", includeRids: "1" }) ); let childRids = $("record", xml).map(function() { let data = []; clistArray.forEach(fid) { data.push($('f[id=${fid}]').text()); } return data; }).get(); queue.push(...childRids); } }
This script does not do anything other than visit each node/record in the relationship tree and yields the [Record ID#] but it could easily be adapted to any specific task such as copying or initializing fields from the records that are visited.
Scripts like this are useful in a variety of other contexts other than recursively copying records. For example, you can easily calculate total weight or cost for a hierarchical assembly modeled using a table related to itself. Or you could perform various queries on an organization chart again modeled using a table related to itself.
If you need functionality similar to this feel free to contact me off-world using the information in my profile:
Thank you both very much!!! I actually wound up figuring out a way to get QB to natively copymasterdetail for my grandparent table by turning off recurse and only including one additional child table, and then setting up an action to create a child record in the other related table I need (the one causing looping relationship issues). So now I'm working on creating an automation to clear out a couple of status fields in that grandparent record when a record with "copy" in the title is added - what do you use as filter criteria for automations when you're asking it to edit itself?