条码扫描的字段设置与开发

栏目:云星空知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:3

条码扫描的字段设置与开发

误区:

    经常有小伙伴把扫描枪全程当成键盘用,这个使用场景在单据体录入时实际上和实际键盘录入是非常不同的,强烈不建议在单据体里面直接扫描录入

理由是:

    由于单据体与服务端可能存在复杂交互逻辑,很多二开插件会依赖单据体的行改变事件和单元格值改变事件处理业务逻辑,并刷新界面表格数据,尤其是在B/S架构中,网络的延迟导致数据的到达客户端的时间无法预测,如果这时再用来进行高速扫描枪数据扫描,就会存在服务端回发数据与扫描枪同时针对同一界面元素资源的竞争使用与覆盖(通俗讲就是打架);由于界面只展示最后数据,且因网络状况原因导致数据返回前后次序的不确定性将会导致随机覆盖前面数据。所以必须严格禁止在表格中直接扫描。即使您能接受因网络状况原因导致的不确定性带来的风险,我们还是强烈的不建议。


    最常用的方案是实战例子一】-- 严重推荐

        二开在单据头放置固定扫描框,使用专用扫描控件进行数据扫描录入(扫码后接收回车结束符,并发送数据到服务端,同时自动清空扫描框内容准备接收下次扫描

        后台用表单业务插件接收数据后自动填入单据体就可以了。这种方案是目前扫描枪的标准用法,最大的有点是高效、稳定、可控、扩展性强。



1、条码扫描
    条码扫描实际是一种通过PS2或USB接口快速的自动录入字符的设备,因此需要支持快速文本获取即可

2、支持版本

    以下例子基于K/3 Cloud 2016年3月补丁,包括5.0,6.0版本,在该时间点之后的补丁都支持,建议安装最新补丁


3、二次开发的实战例子

3.1、【实战例子一使用新的专用扫描控件实现扫描条码:(适用于超级快速的扫描)

1,BOSIDE中拖放文本字段控件FSPECSCANTEXT到单据头上,并设置即时触发更新属性为勾选;.
2,编写构造插件代码如下代码中类TestBarcodeScanerCreatePlugIn,修改编辑控件xtypekdscantext
3,编写业务插件代码如下代码中类TestBarcodeScanerPlugIn;

3.webp

 

插件代码:

using System;

using System.Data;

using Kingdee.BOS.Util;

using Kingdee.BOS.JSON;

using Kingdee.BOS.Resource;

using Kingdee.BOS.DataEntity;

using Kingdee.BOS.ServiceHelper;

using Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel;

using Kingdee.BOS.Core.Bill.PlugIn;

using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;

using Kingdee.BOS.Core.DynamicForm;

using System.Collections.Generic;

using Kingdee.BOS.Core.DynamicForm.PlugIn;

using System.IO;

using Kingdee.BOS.Orm.DataEntity;


namespace Kingdee.BOS.Test.PlugIn

{

    /// <summary>

    /// 测试扫描专用控件构造插件

    /// </summary>

    public class TestBarcodeScanerCreatePlugIn : AbstractDynamicWebFormBuilderPlugIn

    {

        public override void CreateControl(CreateControlEventArgs e)

        {

            base.CreateControl(e);

            if (e.ControlAppearance.Key.EqualsIgnoreCase("FSPECSCANTEXT"))

            {

                var editor = e.Control["item"] as JSONObject;

                if (editor != null)

                    editor["xtype"] = "kdscantext"; //强制修改为快速扫描控件(WPF/SL 边框为金色)

            }

        }

    }

    /// <summary>

    /// 测试条形码扫描枪业务插件

    /// </summary>

    public class TestBarcodeScanerPlugIn : AbstractDynamicFormPlugIn

    {

        Dictionary<string, bool> verifyCodes = new Dictionary<string, bool>();


        public override void AfterBindData(EventArgs e)

        {

            base.AfterBindData(e);

            if (verifyCodes.Count == 0)

            {

                verifyCodes["1901232892136"] = true;

                verifyCodes["227250948129"] = true;

                verifyCodes["227250948128"] = true;

            }

        }

        public override void BeforeUpdateValue(BeforeUpdateValueEventArgs e)

        {            

            if (!(e.Key.Equals("FBARCODE") || e.Key.Equals("FSPECSCANTEXT")))

            {

                return;

            }

            var code = e.Value != null ? e.Value.ToString() : "[null]";

            e.Cancel = true; //快速扫描不能回发数据,否则会引起服务端与客户端数据录入冲突


            if (string.IsNullOrWhiteSpace(code))

                return;


            // 添加新行

            var msg = "Error"; var verify = false;

            if (!verifyCodes.TryGetValue(code, out verify))

            {

                verify = false;

            }

            if (verify)

            {

                msg = "OK";

            }

            var isAppend = (bool)this.Model.GetValue("F_KD_Append");

            if (isAppend)

            {

                AppendRow(code, msg);

            }

            else

            {

                NewRowUpdateView(code, msg);

            }

        }


        private void AppendRow(string code, string msg)

        {

            var ekey = "FENTITY";

            this.Model.CreateNewEntryRow(ekey);

            int rowIndex = this.Model.GetEntryCurrentRowIndex(ekey);


            this.Model.SetValue("F_KD_BARCODE", code, rowIndex);

            this.Model.SetValue("F_KD_REMARK", msg, rowIndex);

            

            var info = this.View.OpenParameter.FormMetaData.BusinessInfo;

            var entity = info.GetEntity(ekey);

            var rowData = this.Model.GetEntityDataObject(entity, rowIndex);

            var field = info.GetField("F_KD_REMARK");

            this.View.StyleManager.SetEnabled(field.Key, rowData, "BillStatusByEntry", false);


            var redColor = "#FF0000";

            var whiteColor = "#FFFFFF";

            var blackColor = "#000000";

            var greenColor = "#00FFCC";

            var backColor = greenColor;

            var foreColor = whiteColor;

            var grid = this.View.GetControl<EntryGrid>(ekey);

            if (msg != "OK")

            {

                backColor = redColor;

            }

            else

            {

                foreColor = blackColor;

            }

            grid.SetForecolor("F_KD_REMARK", foreColor, rowIndex);

            grid.SetBackcolor("F_KD_REMARK", backColor, rowIndex);

        }


        private void NewRowUpdateView(string code, string msg)

        {

            var ekey = "FENTITY";

            var info = this.View.OpenParameter.FormMetaData.BusinessInfo;

            var ent = info.GetEntity(ekey);

            var entModel = this.Model.GetEntityDataObject(ent);

            var barCodeField = info.GetField("F_KD_BARCODE");

            var remarkField = info.GetField("F_KD_REMARK");

            var rowData = new DynamicObject(ent.DynamicObjectType);

            barCodeField.DynamicProperty.SetValue(rowData, code);

            remarkField.DynamicProperty.SetValue(rowData, msg);

            entModel.Add(rowData);

            this.View.UpdateView(ekey);

            var lastIdx = this.Model.GetRowIndex(ent, rowData);

            this.View.GetControl<EntryGrid>(ekey).SetFocusRowIndex(lastIdx);

            this.View.GetControl<EntryGrid>(ekey).SelectRows(new int[] { lastIdx });

        }

    }

}


3.2、【实战例子二】 使用普通文本字段实现扫描条码;

步骤:
1,BOSIDE中拖放文本字段控件FBARCODE,并设置即时触发更新属性为勾选;
2,编写业务插件代码如下代码中类TestBarcodeScanerPlugIn;

特别说明:特别针对单行文本录入字段,当SetEnterNavLock(True)执行后,单行文本录入框进入条码扫描模式:
#设置True后:
1、焦点不跳转;
2、服务端回填扫描框的数据不显示,实现快速连续扫描(2016年3月补丁,包括5.0,6.0);
3、鼠标焦点时离开不会自动提交当前扫描框的数据,只有回车到来才会提交,实现快速连续扫描断码补填(2016最新补丁);


       // 只用于普通扫描文本控件

        public override void ButtonClick(ButtonClickEventArgs e)

        {

            if (e.Key == "FVERIFY")

            {

            }

            if (e.Key == "FENTER")

            {

                this.View.GetControl("FBARCODE").SetEnterNavLock(true);

            }

            if (e.Key == "FTAB")

            {

                this.View.GetControl("FBARCODE").SetTabNavLock(true);

            }

            if (e.Key == "FNULL")

            {

                this.View.GetControl("FBARCODE").SetEnterNavLock(false);

                this.View.GetControl("FBARCODE").SetTabNavLock(false);

            }

        }


————————————————————————————————————————————


3.3、实战例子三】:

( 原始帖子参考:https://vip.kingdee.com/article/36127 )
所有存在条码扫描的字段的同学请注意,参考修改。
记得条码应用的要用这个,不要自己focus

1.webp

image.webp


源码:

from Kingdee.BOS.Core.DynamicForm.PlugIn.ControlModel import *

def ButtonClick(e):
   if ( e.Key == "FENTER" ):
       this.View.GetControl("FBASE").SetEnterNavLock(True)
   if ( e.Key == "FTAB" ):
       this.View.GetControl("FBASE").SetTabNavLock(True)
   if ( e.Key == "FNULL" ):
       this.View.GetControl("FBASE").SetEnterNavLock(False)
       this.View.GetControl("FBASE").SetTabNavLock(False)




---------------------------------------------

创建于2019年6月5日 10:36:21

编辑于2021年5月24日 14:00:16


条码扫描的字段设置与开发

误区: 经常有小伙伴把扫描枪全程当成键盘用,这个使用场景在单据体录入时实际上和实际键盘录入是非常不同的,强烈不建议在单据体里面...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息