EDGEBIC Platform

How EDGEBIC Imports Routings in Two Passes

User Solutions TeamUser Solutions Team
|
10 min read

A routing import runs in two passes because a step cannot point at the next step until the next step exists. The first pass reads and validates every row and buffers it. The second pass inserts each product's steps in sequence order and then writes the links between them. Understanding that split explains almost every behaviour of a routing import that surprises people, including the one where a second run deletes what the first run created.

This post is the mechanism. For building the mask in the first place, see how to build an import mask; for the wider import system, import masks explained.

Why One Pass Cannot Work

A routing is a chain. In EDGEBIC by User Solutions the execution order comes from a link on each step pointing at its successor, not from the sequence number. Those links are what the scheduler actually reads.

Now try to import a five-step routing row by row. Row one is the saw step, and it must point at the lathe step. The lathe step does not exist yet, and will not until row two is processed, and even then it has no identity the saw step can reference until it has been written.

Every ordering trick fails. Process the file backwards and the last step has to point at the end product, which is fine, but a routing that branches has no single reverse order. Guess at identities and any failure mid-file leaves a chain pointing at records that were never created.

The two-pass design sidesteps all of it. Nothing is linked until everything exists.

Pass One: Read, Resolve, Buffer

For each row, the first pass does four things.

Validates the row. The end product and the step must both be present. A row missing either fails with a recorded reason, and by default the run continues so one typo does not block the rest of the file.

Resolves or creates the end product. The finished-good name is looked up and, when automatic creation is on, created if missing. Names are cached during the run, so a hundred rows naming the same product cost one lookup.

Resolves or creates the step's target. This is where the operation flag earns its place in the file. When the flag says the row is an operation, the step's name is treated as a work center and resolved or created as one, optionally assigned to a department from another column. When the flag says the row is not an operation, the name is treated as a component product instead. One column decides whether a row becomes a machine step or a material step.

Wipes the end product's existing steps. On first reference to each end product within the run, the product's existing routing steps are deleted. It happens once per product per run, and the reason is in the next section.

Then the row is buffered. Nothing about the routing structure has been written yet, which is why these rows are bookkeeping in the result grid rather than outcomes worth reviewing. The log file keeps the full record regardless.

Pass Two: Insert, Then Wire

When the last row has been read, the second pass runs.

group buffered rows by end product
  sort each group by sequence number
  insert the steps in that order, collecting their identities
  wire the links:
      if the row named a next step, link to that step
      else if automatic chaining is on, link step N to step N+1
      link the final step to the end product itself
  attach parallel and alternate children to their named parent step
  recompute routing levels for the product

Three details in that sequence matter in practice.

Automatic chaining uses the sequence number. Leave the next-step column out of your file entirely, give every row a sequence number, and the import links them in ascending order. This is the normal arrangement for an ERP export that carries operation numbers but no explicit successor column.

The terminal step gets the end-product link. The last ordered step is pointed at the finished product itself. Without that link no step reaches the end product, the routing renders on the design canvas as steps floating unattached, and the level calculation has no anchor. It is stamped automatically when chaining is on, which is one more reason to leave that option alone.

Parallel and alternate children attach after insertion. A row naming a parent step, plus a type telling the import whether the relationship is an independent parallel machine, a dependent mirror, or a true alternative, becomes a child of that step. The three modes behave very differently at scheduling time, and the difference is covered in parallel and alternate work centers.

Finally the routing levels are recomputed, which is what gives each step its depth relative to the end product.

A Worked Import

A five-step routing for a product called Shaft-100, exported from another system as comma-delimited text with setup times in minutes.

End_Product,Step_Name,Is_Operation,Seq,Hours,Setup_Min,Queue
Shaft-100,Saw-Cut,true,10,0.5,15,0
Shaft-100,Lathe-1,true,20,2.0,30,0.5
Shaft-100,Mill-1,true,30,1.5,20,0.5
Shaft-100,Grind-1,true,40,1.0,10,0.25
Shaft-100,QC-Inspect,true,50,0.25,0,0

The mask maps seven columns and puts a conversion factor of 0.016667 on the minutes column. Automatic creation of missing products and work centers is on, and so is automatic chaining.

Pass one buffers five rows. Shaft-100 is created and cached. Saw-Cut, Lathe-1, Mill-1, Grind-1 and QC-Inspect are created as work centers and cached. Shaft-100's existing steps, if any, are wiped once.

Pass two sorts by sequence, inserts the five steps, and wires:

Saw-Cut     -> Lathe-1
Lathe-1     -> Mill-1
Mill-1      -> Grind-1
Grind-1     -> QC-Inspect
QC-Inspect  -> Shaft-100 (the end product)

Setup values after conversion: 0.25, 0.50, 0.33, 0.17 and 0.00 hours. The result reads five created rows, and the design canvas shows the routing chained and connected to the product node.

Leave the conversion factor off and those setup values arrive as 15, 30, 20, 10 and 0 hours. Every row is structurally valid, the import reports complete success, and the routing is nonsense. That is the single strongest argument for running a diagnostics sweep after every import, described in how to run and read the anomaly report.

Why Re-Import Wipes and Recreates

A routing re-import deletes each end product's existing steps and rebuilds them from the file, once per product per run.

The alternative would be to match incoming rows against existing steps and update them in place, and it fails on the case that matters: a routing whose shape changed. Delete an operation in the source system, re-import, and a matching strategy leaves the deleted step in place forever. Renumber the operations and matching produces duplicates. Insert a step in the middle and the links have to be rewritten anyway.

Wipe and recreate makes re-running the same file idempotent. Steps never accumulate. A corrected file simply replaces the bad steps, with nothing to unwind. It also mirrors what the manual routing editor already allows, which is to rebuild a routing's steps even when jobs are scheduled.

That design has one hard consequence, and it is the most expensive routing-import mistake there is: all steps for one product must be in one file. Split steps ten to thirty into file A and forty to fifty into file B, import them in two separate runs, and the second run's wipe removes the first run's steps before inserting its own. You end up with only the second file's steps, and the result dialog reports complete success both times.

What Re-Import Does to Scheduled Jobs

Nothing, directly, and that is worth stating precisely.

Every scheduled job carries its own frozen copy of the routing it was planned with. A routing re-import does not reach into that copy, so work in progress is unaffected and shop-floor paperwork stays valid.

What the rebuild does change is the live routing's step identities. They are regenerated, exactly as they would be after a manual rebuild in the editor. A job you later choose to reschedule against the current standard routing picks up the recreated steps and their current timings, which is normally what you want and is always a deliberate choice. That relationship is covered in editing a live job's routing.

Upsert Outcomes on Single-Pass Types

Routings are the only two-pass type. Every other entity follows one pattern, and it is worth knowing because the outcome vocabulary is what the result dialog reports.

look the record up by its natural key, case-insensitively
  no match                        -> Created
  match, updates enabled          -> Updated
  match, updates disabled         -> Reused (nothing written)
  key missing or invalid          -> Failed (reason recorded)

Three properties of that flow:

Case-insensitive matching, no renaming. A row reading WIDGET-A finds Widget-A and does not rename it. The stored name is whatever arrived first.

Blank cells preserve on update. A blank in the file falls back to the value already stored rather than wiping it, so a partial export cannot erase planner-set values. Zeros are not blanks: a column of zeros is a real value and will be written.

Blank cells do not preserve on create. A brand-new record has no prior value to fall back on, so a blank cost column creates a record with a cost of zero. That asymmetry is intentional and it is a good reason to check a sample after a first bulk load.

The Practical Checklist

Before you run a routing import:

  • All steps for each end product are in one file.
  • Every row has a sequence number, ideally in tens.
  • The operation flag correctly distinguishes machine steps from component rows.
  • Any minutes column carries a conversion factor of 0.016667.
  • Automatic chaining is on unless you are supplying explicit next-step values.

After you run it:

  • Open the routing and check the header totals: estimated hours per unit and setup time are live sums and expose a unit error immediately.
  • Confirm the design canvas shows the routing connected to the product node.
  • Run a plant-wide diagnostics sweep before scheduling anything against the new data.

The failures worth pre-empting are collected in import mask mistakes, and the routing-side errors in routing setup mistakes. For per-ERP export shapes, the ERP integration hub and posts such as the JobBOSS data mapping reference show what a real file looks like. The category view of moving off spreadsheets is from Excel to APS.

Full platform map: the complete EDGEBIC guide and the EDGEBIC hub.

Send US a routing export and we will import it live on a demo. Contact US.

Because each step has to point at the step that follows it, and that link cannot be written until the following step exists and has an identity. The first pass validates every row, resolves or creates the products and work centers it names, and buffers the row. The second pass inserts all steps for a product in sequence order, then writes the links between them now that every target exists.

The existing steps are deleted and rebuilt from the file. This happens once per end product per run, on first reference, which makes re-running the same file idempotent: steps never accumulate or duplicate. It also means all steps for one product must be in one file, because a second run's wipe removes the first run's steps before inserting its own.

No. Every scheduled job carries a frozen copy of the routing it was planned with, so running work is unaffected by a re-import. What does change is the live routing's step identities, which are regenerated by the rebuild. A job you later choose to reschedule against the current standard routing picks up the recreated steps and their current timings.

It looks the record up by its natural business key, case-insensitively. If nothing matches, it creates. If something matches and updates are enabled, it updates, with blank cells falling back to the existing value. If something matches and updates are off, which is the default, it reports the row as Reused and writes nothing. The four outcomes are Created, Updated, Reused and Failed.

Expert Q&A: Deep Dive

Q: Our routing export has one row per operation but no next-step column. Will the import chain them correctly?

A: Yes, provided the rows carry a sequence number and automatic chaining is left on, which is the default. The second pass sorts each product's steps by sequence number and links step ten to twenty, twenty to thirty, and so on, then points the final step at the end product itself so the routing renders connected on the design canvas. That last link is easy to overlook and is the reason a routing sometimes imports as five steps floating unattached to the product. Number in tens in the source file for the same reason you would by hand: inserting an operation later costs one row instead of a renumbering exercise.

Q: We imported our routings and every setup value came in sixty times too large. What is the recovery path?

A: Set the conversion factor on the setup column to 0.016667 and re-import the same file. Because a routing re-import wipes and recreates each product's steps, the corrected file simply replaces the bad steps: there is nothing to unwind and no duplicate rows to clean up. That is the upside of the wipe-and-recreate design. Two things to check before re-running: that all of each product's steps are still in one file, and that any jobs scheduled against the bad routing are rescheduled afterwards if you want them on the corrected timings, since their frozen snapshot still holds the wrong numbers.

Frequently Asked Questions

Ready to Transform Your Production Scheduling?

User Solutions has been helping manufacturers optimize their production schedules for over 35 years. One-time license, 5-day implementation.

User Solutions Team

User Solutions Team

Manufacturing Software Experts

User Solutions has been developing production planning and scheduling software for manufacturers since 1991. Our team combines 35+ years of manufacturing software expertise with deep industry knowledge to help factories optimize their operations.

Let's Solve Your Challenges Together