Job work flow/barcode scanning how to?

Not enough scope defined and too many variables. It would depend a great deal on proficiency of the developer.

@DaveS I have an UBAQ that we use to do this, but I am wondering are you changing a used operation to a new team rather than having an operation per team? I wrote it with the understanding that they would set the team before starting to clock on, but I know they move stuff midstream all of the time.

I sometimes think the complexity of bar codes is overstated.

They are just a way of replicating key strokes in an image. Indeed a simple way to trouble shoot a bar code is scanning it in Notepad.

Putting bar codes on the job traveller is fairly straight forward and can save a lot of time.

I have previously had the requirement to display the job number and the operation represented as bar codes which allows the users to replicate the ‘Start Activity’ key strokes in MES.

In terms of SSRS, it is a question of working out what string you need to display and then applying the correct font. I use code 39.

1 Like

Just to get my feet wet, I created a UD## Maintenance Form customization (using Program Ice.UI.UD##Entry.dll).
I only left Key 1 Visible behavior TRUE (this is where I scan the Job Number to).
Then I created a UD## Update Pre-Processing Method Directive BPM that has the following:
Set Field 0 - Set the ttUD##.ShortChar01 field of the added row to the callContextClient.CurrentUserId expression
Set Field 1 - Set the ttUD##.Key2 field of the added row to the DateTime.Now.ToString(“MM-dd-yyyy HH:mm:ss:ff”) expression

So now when I call the form I:
Scan the Job from the Job Traveler
Press Tab
Click Yes Record Not Found. Add New? prompt
Press Save to write the row to the UD## table

At this point in a report or whatever, I could get the latest UD## table row for a job to report on the CurrentUserId.
Note: The idea is that the Job Traveler is scanned from a PC that is logged into Epicor where the userid is named the same as Prod Team ID.

Folks here are OK with me using this approach as long as I can now get rid of the clicks/kep presses (tab, Yes to Add New, Save, Close and Restart the Form) which would allow us to have this setup with Scanner/PC with no monitor, keyboard and mouse…this is a requirement.
Note: After the Save, using New or Clear shows all the keys visible which is not desired (don’t know why this is happening), so that is why I am having to Close and restart the form.

Any suggestions on how I could accomplish the click-less/kepress-less approach from where I’m at with this?

Many barcode scanners have a configuration setting that will allow you to append a suffix to the barcode payload. In some cases, it can be a tab, and the result is that the field is tabbed out of after scanning. I think some scanners have limited suffixes and, in some cases, we have had to detect the suffix in the customization and invoke a tab key stroke in code. In most cases, the tab setting work as expected.

To bypass the ‘Add New?’ dialog, try launching the form in developer mode, select your customization, create a new record and check off ‘do not show me this again’ checkbox. Then go into customization mode and save the customization. In my testing this made it so that all users no longer get the prompt when the customization is loaded.

You can automate the save by handling the AfterAdapterMethod but I don’t think this will be necessary after the above.

The issue with the keys reappearing. Sounds like you are fighting against the base logic which tries to reset the base controls. In addition to making the fields not visible, make the size and position as small as possible as well. If this doesn’t work, you probably need to handle the EpiViewNotification event or adapter method events to set the visibility back to false.

Adam, thanks for addressing each of my issues. Your Add New? tip worked. Thank you. However, the Save after was still necessary, so I’ll try your tip for that and the other tips and reply back to this post.

Adam, how/where to handle the AfterAdapterMethod? I can only get the AfterAdapterMethod to fire after I click Save. I used the Form Event Wizard.
Seems like I just need to find the right event to have something like this in…
oTrans.Update();
oTrans.NotifyAll();

Refer to this thread for a better way to hide the other keys in a persistent way

To automate the saving, there are many hooks you could use, one is the AfterExitEditMode event of the actual text box. Since it’s a native control, you need to get a reference and define the event manually:

EpiTextBox etb = (EpiTextBox)csm.GetNativeControlReference("46567b2e-6bc0-4967-be35-a0ec6843838f");
etb.AfterExitEditMode += (s, a) => {oTrans.Update();};

Verify the GUID above matches your Key1 textbox EpiGUID property, this is visible in the properties, in customization mode.

1 Like

Adam, thanks for that thread link…Also, I did get past that issue by resizing width and height of those text fields to their smallest.

What I’m not understanding is where do you define the event manually with that code to automate the saving? I can’t see where you do that.

see this post for adding an event handler to a native control.

The example in that post is for adding a Click event handler. Change all the references of Click to AfterExitEditMode

1 Like

Actually, don’t use a lamba expression as you will not have a reference to unsubscribe, which is good practice. Also declare a global reference to the text box to unsubscribe. This is equivalent but gives you a chance to remove the handler.

// Add Custom Module Level Variables Here **
EpiTextBox etb;

public void InitializeCustomCode()
{
	...
	// End Wizard Added Custom Method Calls
	etb = (EpiTextBox)csm.GetNativeControlReference("46567b2e-6bc0-4967-be35-a0ec6843838f");
	etb.AfterExitEditMode += new System.EventHandler(this.etb_AfterExitEditMode);
}

public void DestroyCustomCode()
{
	...
	// Begin Custom Code Disposal
            etb.AfterExitEditMode -= new System.EventHandler(this.etb_AfterExitEditMode);
	// End Custom Code Disposal
}

private void etb_AfterExitEditMode(object sender, System.EventArgs args)
{
	// ** Place Event Handling Code Here **
	oTrans.Update();
}

Thanks guys. I can see I’m hitting the oTrans.Update() breakpoint in the debugger, but I’m still having to click the Save button after because it’s not writing to the db otherwise. I’m thinking the timing might be too early since maybe the Add New? and my BPM hasn’t run yet.
Any ideas?
BTW I used the code from Adam.
Also, if I can’t get something working along those lines, I was wondering if a barcode scanner is out there that would support multiple suffixes to the barcode payload e.g. Tab, Save, Exit, Reload the Form. Without it saving those suffixes to the Key1 field used for Job#. Dunno if I’ll need any pauses.
I could setup hotkeys to support that. The reason I mention Exit and Reload the Form is because nothing else is working so that I can scan again, then tab, then save after the first scan e.g. New and Clear don’t work.
I know I could have a hotkey for Exit, but I wouldn’t know how to reload the form. BTW, I’m also going to need to automate starting this form when the pc is restarted.

Added a custom control that gets tabbed to after Key1 with this code and it works now.

	private void epiTextBoxC1_AfterEnterEditMode(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **
		oTrans.Update();
	}

My remaining 2 issues for completing this are:

  1. How to do get the next scan(s) after the first one to work as I’ve mentioned prior. What might work is if I can simply automatically close and reopen the form from just after the oTrans.Update() in epiTextBoxC1_AfterEnterEditMode, but I don’t know how.
  2. When the no monitor “headless” PC boots I can get it to start with the following shortcut in a sysconfig that I created by File, Send as File when the form was loaded, but go figure that it starts with the List Tab having focus. How to get it to start with the Detail tab having focus?
  <Shortcut>
    <Company>ACME</Company>
    <Plant>AcmeMfgSys</Plant>
    <AppServerURL>net.tcp://EPICOR/ERPTEST</AppServerURL>
    <DateTime>1/4/2021 8:09:51 AM</DateTime>
    <Originator>My Name</Originator>
    <Process>
      <ProcessID>UDSCANPT</ProcessID>
      <Description>Scan</Description>
    </Process>
    <RecordIDS KeyFields="Key1~Key2~Key3~Key4~Key5" KeyFieldsType="System.String~System.String~System.String~System.String~System.String" TableName="UD38" DataSourceType="UD38DataSet" />
    <Search>
      <NamedSearch>Search Name</NamedSearch>
      <SearchCriteria>Search Criteria</SearchCriteria>
    </Search>
  </Shortcut>

This might be part of the answer for my remaining Issue #1 as this works…

	{
		// ** Place Event Handling Code Here **
	if (oTrans.Update())
	    {
	        UD38Form.Close();
	    }
	
	}

Where to re load form?

So for my issue #1 (of 2 issues) the following gives me the desired functionality. However I can see in the task bar a new window shows for every scan I do. I’m thinking I’ll probably end up exhausting memory or handles over time. Any ideas?

	private void epiTextBoxC1_AfterEnterEditMode(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **

		LaunchFormOptions lfo = new LaunchFormOptions();
		lfo.IsModal = true;
		lfo.SuppressFormSearch = true;
		//lfo.ValueIn = txtEpiCustom1.Text;

		if (oTrans.Update())
		    {
	 	   ProcessCaller.LaunchForm(UD38Form, "Ice.UI.UD38Entry", lfo);
			//this.UD38Form.Close(); 
		    }
		
		}

As for issue #2, I’m still looking for the solution to get it to start from the sysconfig shortcut with the Detail tab having focus

Anyone know how to suppress the following prompt from that? “Attempting to launch Ice.UI.UD38Entry from itself is not logical. Do you want to launch a new instance?” with yes/no buttons

Not sure but @hkeric.wci and @josecgomez wrote this about using LFO:

Thanks @Mark_Wonsil, I had seen that thread before, but not sure if the info there could get me to where I needed to be.
I ended up with this that works for me.

	private void epiTextBoxC1_AfterEnterEditMode(object sender, System.EventArgs args)
	{
		// ** Place Event Handling Code Here **

		LaunchFormOptions lfo = new LaunchFormOptions();
		lfo.IsModal = false;
		lfo.SuppressFormSearch = true;
		//lfo.ValueIn = txtEpiCustom1.Text;

			if (oTrans.Update())
		    {
			Process.Start("AutoHotkey.exe", "z:\\ahkenter.ahk");
			ProcessCaller.LaunchForm(UD38Form, "Ice.UI.UD38Entry", lfo);
		    }
		
	}

In ahkenter.ahk I have (didn’t need the delay. commented for now)
;SetKeyDelay, 0
send {enter}
return

So if I scan 50 times in a day that uses about 170 MB memory. We won’t even need that many scans daily per station. We can just have windows task scheduler daily boot and run the following after on startup:
A TinyTask macro exe that recorded:
Windows Start, cmd /c “z:\scanjob” enter (I needed a place where names and locations didn’t change/move)
which is a .bat file that has start “” “C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Epicor Software\Epicor ERP10.2 Client\epicor\ERP102300TESTV2 Environment.lnk”
followed by me clicking my menu item for my UD38 customization.

Update:
I’ve found that this now works too after the ProcessCaller so no more open old windows

			// Beep at X Hz for X milliseconds
			Console.Beep(1000, 400);
			this.UD38Form.Close(); 
1 Like