Class to Form to TempTable to Report

Hello everyone, I have a very complicated issue that I would like help with. I’m new to AX developing so bare with me. I need to know how to do this and I will definitely need pretty clear step by step instructions to implement this.

Here is the situation. We have a form where users can pick PO’s, or TR’s, or many different things and then hit a button that calls a class. This class gets a bunch of information from a bunch of different tables and saves that info to a file. This was developed by a third party developer before I worked at this company.

I have another department that wants to print labels with just the item (and maybe a little more) on it. So basically they only need 1 little thing from all that info that is grabbed. But then they want to choose how many labels they want to print for each item chosen and ideally, what size label (2 choices).

I created a new button on that form which calls the same class as before (PurchGreenLabelsPrint) but passes in a new enum. I check for that enum and if it’s true, I copy the item from the current TempTable(WMSTmp) to my new TempTable(RecievingLabelsTmp). I then call a form(ReceivingLabels) and pass it my ReceivingLabelsTmp Table as the datasource. In the init method of that datasource, I set the TempTable and I can display the items on the form. So far, so good!

On that form, I’m hoping to have 2 more columns named Small Label and Big Label. Everything will default to 0 and the user can go through and change any item and label size to the number they want to print. They will then click a button at the top (Print Labels) and I want to send all this info to a report (or 2 reports respectively). For now please help me with just one. Let’s say the small label. So I want the user to fill out the small label column and when they hit print, it will open a report with all the item labels ready to go. EG, if item 1234 and 5678 are on the form and they choose 2 labels each, the report will open with 4 labels total (2 for each). I hope that makes sense.

My road block is getting the info from the form/temp table to the report. I created a DP(ReceivingLabelsDP) that references ReceivingLabelsTmp and a report ReceivingLabels that uses the DP as a datasource but the temptable is empty by the time I call the report. If I hardcode an item into it in the ProcessReport method of the DP, it does show up in the report, but that doesn’t help me.

Can someone please help me with what I’m trying to accomplish. If I’m going about this the wrong way, please point me in the right direction. And like I said, I’m still pretty new to the AX development screen so go easy on me :slight_smile:

As I said in email, trying to use temporary tables in this way have many problems. Firstly, it can’t work in many scenarios such as in batch. Secondly, the framework can’t easily work with it - your RDP class will be called by the report server and it can’t ever have any reference to the temporary table. I also wrote:

Therefore I think you should start with defining what should happen in such cases. Maybe you’ll have to explicitly say that your report won’t support certain standard features, such as batching (and then build a solution for the reduced problem). Maybe you’ll find that you want to convert your problem to something more usual, namely storing the data in a persistent table. Maybe something else…

As I’m reading extra details here, I think the first thing you should consider is saving the information to a normal table and serialize the selection of print options to a data contract class. This will completely get rid of your problem with temporary tables. Trying to use temporary tables would prevent you from using certain features (such as batching) and it would be more difficult, which isn’t a good thing for a newbie.

Thanks for your direction Martin, I’ve started doing what you have suggested but things are still not working perfectly yet. I made my table normal instead of temporary. I added an integer field called NumOfSmallLabels. I make it 0 when I populate the fields in the PurchGreenLabelsPrint class. When I call my form it opens with the items I have selected.
I set up the button now to call a controller class that will in turn open my report. I can get my report to open but there a few things I want changed.
When I click the Print button, it opens a prompting form where I can choose an item again but it doesn’t matter what I put in there. It still just prints the items in the table so I don’t even want that screen to show up.
I tried to put in some code to repeat the item in the table the same number of labels that is chosen but I know I’m not doing that right.
Here is my code:

class TCI_ReceivingLabelsController extends SrsReportRunController
{
}
protected void prePromptModifyContract()
{
TCI_ReceivingLabels tci_ReceivingLabels;
TCI_ReceivingLabelsContract contract;

tci_ReceivingLabels = this.parmArgs().record();
contract = this.parmReportContract().parmRdpContract() as TCI_ReceivingLabelsContract;
contract.paramItemId(tci_ReceivingLabels.ItemId);
}
public static client void main(Args args)
{
TCI_ReceivingLabelsController controller = new TCI_ReceivingLabelsController();

controller.parmReportName(ssrsReportStr(TCI_ReceivingLabels, Table));
controller.parmArgs(args);
controller.startOperation();
}

[DataContractAttribute]
public class TCI_ReceivingLabelsContract
{
ItemId itemId;
}
[DataMemberAttribute(“itemId”)]
public itemId paramItemId(ItemId _item = itemId)
{
;
itemId = _item;
return itemId;
}

[SRSReportParameterAttribute(classStr(TCI_ReceivingLabelsContract))]
public class TCI_ReceivingLabelsDP extends SRSReportDataProviderBase
{
TCI_ReceivingLabels tci_ReceivingLabels;
}
[SRSReportDataSetAttribute(tableStr(TCI_ReceivingLabels))]
public TCI_ReceivingLabels getFields()
{
select * from tci_ReceivingLabels;
return tci_ReceivingLabels;
}
public void processReport()
{
TCI_ReceivingLabelsContract contract;
ItemId itemId;
int i, j = tci_ReceivingLabels.NumOfSmallLabels;

contract = this.parmDataContract();
itemId = contract.paramItemId();

for(i=0; i<j; i+=1)
{
tci_ReceivingLabels.ItemId = itemId;
tci_ReceivingLabels.insert();
}

}

I’m guessing right now that called the parmItemId is what puts the Item dropdown box on the parameter form? Also, I’m guessing I have to loop somewhere else, not in the processReport in order to send the item over and over to the report…

What is your question? “so I don’t even want that screen to show up” would suggest that you want to hide the dialog, but in that case it’s not clear why you then switch to another topic.
I thought you would allow users to add ranges, not just select a single item, but I clearly know little about your business requirements.
I don’t understand what you’re trying to do in processReport(), so I can’t say how to fix it.

Regarding “I’m guessing right now that called the parmItemId is what puts the Item dropdown box on the parameter form”: that’s correct.

For those of you interested, I got this working how I wanted it. The key change was saving my table to a container, deleting everything in it, and then writing the items back the number of times that they chose labels to be printed. Here is the code in getFields now:

[SRSReportDataSetAttribute(tableStr(TCI_ReceivingLabels))]
public TCI_ReceivingLabels getFields()
{
container tmpContainer;
str tmpItem, tmpName, tmpLoc, tmpWhse;
int cnt, conLength, tmpSmallLabels;

while select tci_ReceivingLabels
{
tmpContainer += tci_ReceivingLabels.ItemId;
tmpContainer += tci_ReceivingLabels.Name;
tmpContainer += tci_ReceivingLabels.NumOfSmallLabels;
tmpContainer += tci_ReceivingLabels.TCI_Location;
tmpContainer += tci_ReceivingLabels.TCI_Warehouse;
}

conLength = conLen(tmpContainer);
delete_from tci_ReceivingLabels;

for (cnt = 1; cnt <= conLength; cnt++)
{
tci_ReceivingLabels.ItemId = conPeek(tmpContainer, cnt);
tmpItem = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.Name = conPeek(tmpContainer, cnt);
tmpName = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.NumOfSmallLabels = conPeek(tmpContainer, cnt);
tmpSmallLabels = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.TCI_Location = conPeek(tmpContainer, cnt);
tmpLoc = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.TCI_Warehouse = conPeek(tmpContainer, cnt);
tmpWhse = conPeek(tmpContainer, cnt);
tci_ReceivingLabels.insert();
while (tmpSmallLabels > 1)
{
tmpSmallLabels–;
tci_ReceivingLabels.ItemId = tmpItem;
tci_ReceivingLabels.Name = tmpName;
tci_ReceivingLabels.NumOfSmallLabels = tmpSmallLabels;
tci_ReceivingLabels.TCI_Location = tmpLoc;
tci_ReceivingLabels.TCI_Warehouse = tmpWhse;
tci_ReceivingLabels.insert();
}
}

return tci_ReceivingLabels;
}

I would like to add a new issue to this same topic. I got my small labels logic working but now I want to do large labels as well but I’m not sure how. My table now includes a field for large labels and is defaulting to 1. When my form opens it displays all the items and 2 other fields (Small Labels and Large Labels). I want the user to change the number of small labels and large labels and print the number they choose. I want it to open 2 reports and the user can click on Print from there.

I don’t know if I’m doing this the right way or not but here is what I have:
A report named TCI_ReceivingLabels with 2 designs - Label and LargeLabel

A form called TCI_ReceivingLabels with a print labels button that calls a controller (and opens a prompt form with Parameters Item Number which I would prefer not to have since the user will never put in a specific item. They will always just print all the items in that table.

A controller class called TCI_ReceivingLabelsController with the following code:
class TCI_ReceivingLabelsController extends SrsReportRunController
{
}
protected void prePromptModifyContract()
{
TCI_ReceivingLabelsContract contract;

contract = this.parmReportContract().parmRdpContract() as TCI_ReceivingLabelsContract;
}
public static client void main(Args args)
{
TCI_ReceivingLabelsController controller = new TCI_ReceivingLabelsController();

controller.parmReportName(ssrsReportStr(TCI_ReceivingLabels, Label));
controller.parmShowDialog(false);
controller.parmShowReportViewerParameters(false);
controller.startOperation();
}

A contract class called TCI_ReceivingLabelsContract with the following code:
[DataContractAttribute]
public class TCI_ReceivingLabelsContract
{
}

A data provider class called TCI_ReceivingLabelsDP with the following code:
[SRSReportParameterAttribute(classStr(TCI_ReceivingLabelsContract))]
public class TCI_ReceivingLabelsDP extends SRSReportDataProviderBase
{
TCI_ReceivingLabels tci_ReceivingLabels;
}
[SRSReportDataSetAttribute(tableStr(TCI_ReceivingLabels))]
public TCI_ReceivingLabels getFields()
{
container tmpContainer;
str tmpItem, tmpName, tmpLoc, tmpWhse;
int cnt, conLength, tmpSmallLabels, tmpLargeLabels;

while select tci_ReceivingLabels
{
tmpContainer += tci_ReceivingLabels.ItemId;
tmpContainer += tci_ReceivingLabels.Name;
tmpContainer += tci_ReceivingLabels.NumOfSmallLabels;
tmpContainer += tci_ReceivingLabels.NumOfLargeLabels;
tmpContainer += tci_ReceivingLabels.TCI_Location;
tmpContainer += tci_ReceivingLabels.TCI_Warehouse;
}

conLength = conLen(tmpContainer);
delete_from tci_ReceivingLabels;

for (cnt = 1; cnt <= conLength; cnt++)
{
tci_ReceivingLabels.ItemId = conPeek(tmpContainer, cnt);
tmpItem = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.Name = conPeek(tmpContainer, cnt);
tmpName = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.NumOfSmallLabels = conPeek(tmpContainer, cnt);
tmpSmallLabels = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.NumOfLargeLabels = conPeek(tmpContainer, cnt);
tmpLargeLabels = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.TCI_Location = conPeek(tmpContainer, cnt);
tmpLoc = conPeek(tmpContainer, cnt);
cnt++;
tci_ReceivingLabels.TCI_Warehouse = conPeek(tmpContainer, cnt);
tmpWhse = conPeek(tmpContainer, cnt);
tci_ReceivingLabels.insert();
while (tmpSmallLabels > 1)
{
tmpSmallLabels–;
tci_ReceivingLabels.ItemId = tmpItem;
tci_ReceivingLabels.Name = tmpName;
tci_ReceivingLabels.NumOfSmallLabels = tmpSmallLabels;
tci_ReceivingLabels.TCI_Location = tmpLoc;
tci_ReceivingLabels.TCI_Warehouse = tmpWhse;
tci_ReceivingLabels.insert();
}
}

return tci_ReceivingLabels;
}
public void processReport()
{

}

How I accomplished the small labels as you can see is saving the table to a container and then rewriting the number of items for the number of labels they chose. How can I do this same thing for large labels and send the info to the new design? For example, let’s say they have item 123 and 456 and they input on the form they want 2 small labels for each item and 3 large labels for each. I then want it to send this to the small label design of the report.
123
123
456
456
The rewrite the table maybe? and send this to the large label design of the report:
123
123
123
456
456
456

I have a feeling I’m not going about this the right way but since I have never done anything like this before, I’m just trying different things. Maybe I create a second table? A second DP but that seems redundant??? Please help!