That was it! Thank you so much guys!
Ok, I’m kinda slow, so I’m might just not know what I’m looking at, but if I understand correctly, from the main MES screen, with the only requirement be the user is logged in, you scan a barcode, and the start activivty screen opens and populates? I see what you are doing to populate the fields, but how do you get the barcode to open start activity? That’s pretty cool!
You use process calling to launch the start activity menu and pass in an LFO (launch form options) object with the barcode values
Then on the receiving form you parse the LFO extract the barcode values and the code above will populate the screen for you
-Jose
So I’m noticing that when I click OK to start the activity, the MES grid view doesn’t populate with the labor activity unless I clear the screen and log back in to MES…why would the MES Menu not refresh?
Probably because when you are invoking your Process you are not notifying the adapter of the change. Invoke
this.RefreshLaborData();
That goes on a form close event right? (I’m going to need the same thing on an end activity rewrite that I’m working on.)
Well if you make the process calling Modal
lfo.IsModal = true;
Then the Form will hold execution until the other form closes. So you can write the code like
LaunchForm(); //Execution will stop here until the form closes as long as the LFO is modal.
RefreshLaborData()
I used the following line and it worked:
this.RefreshLaborData();
However, my PerformClick() on the OK button is not working. I linked the control to the GUID, is there anything else I need to do?
What are you hitting perform click for? (In the Start Production Screen?)
Just do this instead
if (oTrans.Update())
{
StartProdForm.Close();
}
That was it! Still lots of learning to do…
I’m resurrecting an old post here, but I’m wondering what the trick is for calling the “Start Production Activity” form might be. I have tried to use the following, but nothing seems to happen - no error, no UI response:
ProcessCaller.LaunchForm(this.oTrans, “Erp.UI.StartProductionActivityEntry”, lfo);
Aside from defining all of the parameters in the LaunchFormOptions object, I am not sure what I might be missing.
Just a quick glance but this looks correct. What kind of event / form are you using to base this call from?
This is where a BPM comes in really well… I bet if you ran a trace, did the function manually, you would find a BO that is triggered, and you could apply setting the values within the BPM as either a pre or post processes, and it would work very easily.
Greetings, @danbedwards / @timshuwy. Thanks for your responses.
This is being called from a customization within the MES Menu form. I’ve placed that specific line within a method that parses a barcode scan and sets that value in a container that gets passed to the LaunchFormOptions context value parameter. Afterward, the process caller is invoked. What’s weird is, I can set a message box in a line just before the process caller in order to validate the context value, but when the process caller is invoked, nothing happens - and there are no errors to reference.
@timshuwy – I think the reason I was avoiding constructing a BPM was because I thought it would be a simple custom code solution (I know… I know… ).
One small item to add:
After I performed a debug in Visual Studio, the debugger seems to be getting hung up on a missing assembly, entitled, “Erp.Adapters.Menu.dll”. However, that assembly does not seem to exist on our Epicor server, nor the client upon which I am developing.
Here’s a reference:
Seems like this assembly is required in order to invoke the ProcessCaller.LaunchForm method. Am I way off base here?
[Note - I am still on v10.1.400.14, but the customization guide for that version does reference the LaunchForm method on page 421]
You don’t need any references for using ProcessCaller. Could you post the full code?
I’m with Dan - more code would be helpful. What’s interesting is the Adapters.Menu.dll is an ICE dll, not an ERP dll.
Here is how the MES screen opens that form:
LaunchFormOptions launchObject = new LaunchFormOptions {
IsModal = true,
SuppressFormSearch = true
};
ProcessCaller.LaunchForm(oTrans, Erp.UI.StartProductionActivityEntry, launchObject);
As you can see, you appear to be doing it right.
Thanks, Chris. Since I was spinning my wheels a bit on what appears to be elementary/basic ICE functionality, I reluctantly decided to remove that aspect of automation and have our users manually log in with their MES ID , then manually select the option to “Start Production Activity”. Afterwards, a quick hand-held scan of the job traveler will place the job number, assembly number, and operation number in their proper fields on that form (there is still a small issue with tabbing out of the focused control, but this is a good start for the expressed need).
I would have preferred to automate the entire process by auto-magically opening the SPA form for our users, but I suspect the Zebra API I’m using is conflicting with basic ICE methods.
Here is the final, working code for those interested. If the correct barcode is scanned at the MES Menu main form, then Start Production Activity will launch, the fields will populate, and then close so the employee is clocked in.
The code is triggered by the hotkey “J” which is the first character of the QR code. So the barcode would read “J-JobNumber-AssemblyNumber-OperationSequence-Z”. J triggers the code, and Z tells the code to stop reading the barcode. I had to make a custom menu item in Menu Maintenance for the StartProd form (that’s what SSSM9999 is).
// Launch Start Activity from hot key
DateTime _lastKeystroke = new DateTime(0);
List<char> _barcode = new List<char>(10);
LaunchFormOptions lfo = new LaunchFormOptions();
public void MESMenu_KeyPress(object sender, KeyPressEventArgs e)
{
// Check timing (keystrokes within 100 ms)
TimeSpan elapsed = (DateTime.Now - _lastKeystroke);
if (elapsed.TotalMilliseconds > 100)
_barcode.Clear();
// Record keystroke and timestamp
_barcode.Add(e.KeyChar);
_lastKeystroke = DateTime.Now;
// Process barcode
if (e.KeyChar == (char)90 && _barcode.Count > 0)
{
string msg = new String(_barcode.ToArray());
lfo.IsModal = true;
lfo.ContextValue = msg;
_barcode.Clear();
ProcessCaller.LaunchForm(this.oTrans, "SSSM9999", lfo);
this.oTrans.RefreshLaborData();
}
}
A customization on the StartProd form pulls the barcode in and then assigns each section of the barcode to its proper field. Sections are separated by the character “-”.
// Pull barcode in from MESMenu
private void StartProdForm_Load(object sender, EventArgs e)
{
if(StartProdForm.LaunchFormOptions != null)
{
object barcodeObj = StartProdForm.LaunchFormOptions.ContextValue;
// Convert barcode (object to string)
string barcode = barcodeObj.ToString();
// Split barcode into parts
var items = barcode.Split('-');
string job = items[1];
string asm = items[2];
string opr = items[3];
// Transfer data to fields
var view = ((EpiDataView)(this.oTrans.EpiDataViews["Start"]));
if(view.Row>=0)
{
// Fill Job Number
view.dataView[view.Row].BeginEdit();
view.dataView[view.Row]["JobNum"]=job;
view.dataView[view.Row].EndEdit();
// Fill Assembly Sequence
view.dataView[view.Row].BeginEdit();
view.dataView[view.Row]["AssemblySeq"]=asm;
view.dataView[view.Row].EndEdit();
// Fill Operation Sequence
view.dataView[view.Row].BeginEdit();
view.dataView[view.Row]["OprSeq"]=opr;
view.dataView[view.Row].EndEdit();
// Close form
if (oTrans.Update())
{
StartProdForm.Close();
}
}
}
}
I hope this helps somebody!
Good information here, Fred. Thanks for sharing your approach.
I am wondering though…
Part of my strategy on this involves validation of the barcode scan and rolling back that attempt, if the user discovers that he/she doesn’t really want to start the scanned operation (in my case, from the job traveler). Might you know of a way to roll back the data view edit before it is committed?
I noticed that you are validating if the transaction has been committed, or not - and if so, you are closing the form. Here is where I might want to roll the data view update back before committing it… but I’m not sure how this might be accomplished.
I thought I might be able to do it in this manner:
string strText = "Do you want to start the following production activity?\n"
+ "--------------------------------------------------------\n"
+ "Job number\t:\t" + strJobNum + "\n"
+ "Assembly\t\t:\t" + strAsmSeq + "\n"
+ "Operation\t\t:\t" + strOprSeq;
string strTitle = "";
if (MessageBox.Show(strText, strTitle, MessageBoxButtons.YesNo) == DialogResult.Yes)
{
[Commit the data view update and close the form]
}
else
{
[Insert code to rollback the data view update and clear all form controls; allowing the user to rescan]
}
Any thoughts on this approach… or thoughts on whether a data view transaction can be rolled back?