从事了多年的生产系统开发、设计与维护,对生产流程控制与现场数据采集还算是比较熟悉,经历了多个公司的系统建设,总结了一些比较实在功能模块。任何一家企业都有多个客户,而每一个客户的产品各不相同,不同的产品有着不同的生产流程,因此我们必须通过流程管理系统来规范我们的流程,通过可视化的流程设计界面,用户可以非常方便的设计出符合产品生产工艺的流程,该项目中用到了大量的条码打印功能,所以本文主要讲解如何在系统中实现条码打印,条码打印大概分为如下几种方式:

1.利用专业的条码打印软件进行打印,比如 BarTender, FastReport等。

2.通过 Graphics 进行绘图,最后将图片打印出来。

在程序中通过 BarTender 进行条码打印

首先在 BarTender 中创建新文件,并增加一个类型为 code128类型的条码,如下图所示:
生产制造追溯系统(一)_第1张图片

双击这个条形码,在“数据源”选项中设置该条码的数据源属性,指定数据源名称为 {SN},如下图所示,此处很关键。

生产制造追溯系统(一)_第2张图片

以下为关键性代码:

            //获取默认打印机
            System.Drawing.Printing.PrintDocument pringdocument = new System.Drawing.Printing.PrintDocument();
            string pring_name = pringdocument.PrinterSettings.PrinterName;//打印机名

该方法具备4个参数,第一个参数为打印机名称,一般情况下就获取默认打印机即可,第二个参数为模板文件的路径,第三个参数为需要打印的字段,也就是上面第二个图中定义的变量名称,最后一个参数就是第三个参数名对应的参数值。

 public static BarTender.ApplicationClass engine = null;
        public static BarTender.FormatClass format = null;

        /// 
        /// Bartender打印
        /// 
        /// 
        /// 
        /// 
        /// 
        /// 
        public static string BartenderPrint(string printerName, string labelPath, string[] keys, string[] values)
        {
            try
            {
                //获取打印文件
                string filename = labelPath; 
                if (string.IsNullOrEmpty(filename))
                {
                    return "label[BartenderPrint] 未找到可用的标签模板文件!";
                }
                if (engine == null)
                {
                    engine = new BarTender.ApplicationClass();
                }

                List list = new List();

                format = (BarTender.FormatClass)engine.Formats.Open(filename);

                for (int i = 1; i <= format.NamedSubStrings.Count; i++)
                {
                    for (int k = 0; k < keys.Length; k++)
                    { 
                        BarTender.SubString sub = format.NamedSubStrings.GetSubString(i);
                        if (sub.Value != keys[k])
                        {
                            continue;
                        }

                        list.Add(sub.Name);
                        format.SetNamedSubStringValue(sub.Name, values[k]);
                    }
                } 

                format.PrintSetup.Printer = printerName;
                BarTender.Messages msg = null;
                format.Print("", true, -1, out msg); 
            }
            catch (Exception ex)
            { return ex.Message; }
            return "";
        }

在程序中通过 Graphics 进行条码打印
在 C# 中 ,Graphics 属于 System.Drawing命名空间,通过Graphics可以将条码绘制成图片,然后将图片打印出来即可。

  private void CreatePalletListImg(Graphics g)
        {
            var pen = new Pen(Brushes.Black) { Width = 0.4F };
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            const int persion_height = 75;//条码Y轴间隔距离
            System.Drawing.Font font0 = new Font("微软雅黑", 3, FontStyle.Regular, GraphicsUnit.Millimeter);

            Code128 _Code = new Code128();
            Font font1 = new Font("微软雅黑", 3.5F, FontStyle.Bold, GraphicsUnit.Millimeter);
            Font font2 = new Font("微软雅黑", 5, FontStyle.Bold, GraphicsUnit.Millimeter);
            Font font3 = new Font("宋体", 2.8F, FontStyle.Regular, GraphicsUnit.Millimeter);

            g.DrawString(string.Format("Model:{0}", dt_source.Rows[0]["MODEL"].ToString().Trim()), font1, Brushes.Black, 20, 23);
            //**************************************

            g.DrawString(string.Format("PN:{0}", dt_source.Rows[0]["PN"].ToString().Trim()), font1, Brushes.Black, 20, 60);
            var imgTemp1 = _Code.GetCodeImage(dt_source.Rows[0]["PN"].ToString().Trim(), Code128.Encode.Code128A);
            g.DrawImage(imgTemp1, 23, 80, 240, 27); //条码            

            //**************************************
            g.DrawString(string.Format("Packing List:{0}", dt_source.Rows[0]["PACKING_LIST"].ToString().Trim()), font1, Brushes.Black, 20, 120);
            var imgTemp2 = _Code.GetCodeImage(dt_source.Rows[0]["PACKING_LIST"].ToString().Trim(), Code128.Encode.Code128A);
            g.DrawImage(imgTemp2, 23, 140, 180, 27); //条码

        }

调用绘图方法:

  void PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {

            CreatePalletListImg(e.Graphics);
        }

下一篇文章,我们将介绍如何通过FastReport进行条码打印以及如何在网页中调用客户端进行打印。

生产制造追溯系统(一)_第3张图片

生产制造追溯系统(一)_第4张图片

流程管控
针对每一种产品的流程,系统都可以进行流程防呆,防止操作员漏工序生产,上一个工序还未完成的情况下禁止操作下一个工序。

生产制造追溯系统(一)_第5张图片

生产过程追溯
完整记录每一个产品的生产过程,包含每一个工序的生产时间,操作员工号,生产线,检验结果等详细信息,数据永久保存,随时可以查询历史数据,减少纸张浪费。

生产制造追溯系统(一)_第6张图片

生产制造追溯系统(一)_第7张图片

AQL 动态检验
利用AQL国际标准,由系统根据 AQL 自动分配抽检产品,打破传统的抽检模式,进一步确保品质。

在线包装与打印
配置包装规则,在线实现卡通包装,包装结束后自动打印标贴,有效防止 A 箱 B 货的品质事件发生。

生产制造追溯系统(一)_第8张图片
电子看板
电子看板实时更新生产状况,将生产状况透明化,帮助管理层了解生产进度,进一步找出生产瓶颈,从而做出更合适的改善,提高生产效率。

生产制造追溯系统(一)_第9张图片

生产制造追溯系统(一)_第10张图片

动态组装
根据不同的产品配置不同的装配规则,有效防止操作员扫描错误的条码,使追溯变得更完整。

不良品维修系统
完整的坏机维修流程,帮助品质人员掌握不良品流向,通过分析不良现象找出改善方案。
生产制造追溯系统(一)_第11张图片

生产制造追溯系统(一)_第12张图片

系统对接
对接 SAP、E10等 ERP 系统.

数据报表
包装报表,条码过站记录报表,工单直通率报表,产品直通率报表,QA抽检报表,不良品维修报表,待维修报表,工单生产状态报表,装配报表等等

生产制造追溯系统(一)_第13张图片

生产制造追溯系统(一)_第14张图片

生产制造追溯系统(一)_第15张图片

生产制造追溯系统(一)_第16张图片

欢迎交流:
QQ:969661314
Email:allen0717#163.com (#改@)