• [AX]AX2012 Number sequence framework :(二)实现自定义模块的Number sequence


    有了“[AX]AX2012 Number sequence framework :(一)概览与原理浅析”一文中对Number sequence framework的初步分析,实现自己的模块的Number sequence就比较容易理解了。这里以实现一个我们自己的“MES”模块为例来看看具体如何操作,在这个MES模块中我们有一个WeighingJobsID的EDT扩展类型,用它来表示唯一一个称量任务,它的编号来自于一个Number sequence。

    1.首先我们需要在NumberSeqModule base enum下添加模块“MES”的子项

    2.定义扩展类型WeighingJobId,字符串类型的EDT

    3.创建保存模块参数配置的表MESParameters,可以从其他模块照抄,这个表必须有一个ParametersKey EDT类型的字段“key”,创建一个非重复的索引“Key”,仅包含字段“key”。在表MESParameters上创建一些方法:

    void delete()
    {
        throw error("@SYS23721");
    }
    void update()
    {
        super();
        flush MESParameters;
    }
    //AOSRunMode::CalledFrom
    static MESParameters find(boolean _forupdate = false)
    {
        MESParameters parameter;
    
        parameter.selectForUpdate(_forupdate);
    
        select firstonly parameter
            index Key
            where parameter.Key == 0;
    
        if (!parameter && !parameter.isTmp())
        {
            Company::createParameter(parameter);
        }
    
        return parameter;
    }
    
    //返回当前Number sequence模块的ENUM值
    static client server NumberSeqModule numberSeqModule()
    {
        return NumberSeqModule::MES;
    }
    
    client server static NumberSequenceReference numRefWeighingJobId()
    {
        
        //使用当前公司创建一个scope
        NumberSeqScope scope = NumberSeqScopeFactory::createDataAreaScope(curext());
        //根据EDT类型和scope在NumberSequenceReference表中查找相应的引用记录
        return NumberSeqReference::findReference(extendedtypenum(WeighingJobId), scope);
    }

    4.从NumberSeqApplicationModule扩展自己的Module类NumberSeqModuleMES,重载numberSeqModule()和loadModule()两个方法:

    class NumberSeqModuleMES extends NumberSeqApplicationModule
    {
    }
        NumberSeqDatatype datatype = NumberSeqDatatype::construct();
    
        /* Weighing job number */
        //指定data type的一些参数,用于在wizard生成number sequence时使用
        datatype.parmDatatypeId(extendedTypeNum(WeighingJobId));//EDT类型
        datatype.parmReferenceHelp("Unique identifier for weighingjobs");
        datatype.parmWizardIsContinuous(false);//是否连续
        datatype.parmWizardIsManual(NoYes::No);//是否手工输入编号
        datatype.parmWizardIsChangeDownAllowed(NoYes::No);//可往下修改编号
        datatype.parmWizardIsChangeUpAllowed(NoYes::No);//可往上修改编号
        datatype.parmSortField(1);
        datatype.parmWizardHighest(999999);//编号最大值
    
        datatype.addParameterType(NumberSeqParameterType::DataArea, true, true);//该函数可以多次调用,组合多个scope类型,注意最后一个参数,为true表示可配置 
        this.create(datatype);
    
      
    }
    public NumberSeqModule numberSeqModule()
    {
       return NumberSeqModule::MES;
    }

    5.创建配置MES parameters的form MESParameters,其他模块照抄,删除不需要的内容,保留Data source下的表NumberSequenceReference及其下的表NumberSequenceTable,包含表MESParameters到data source,实现修改以下方法:

    public class FormRun extends ObjectRun
    {
        boolean                 runExecuteDirect;
        TmpIdRef                tmpIdRef;
    
        fieldId                 tmpFieldId;
    
    
        NumberSeqScope             scope;
        NumberSeqApplicationModule numberSeqApplicationModule;
        container                  numberSequenceModules;
    }
    
    public void init()
    {
        this.numberSeqPreInit();
    
        super();
    
        MESParameters::find();
    
        this.numberSeqPostInit();
    
    }
    void numberSeqPreInit()
    {
        runExecuteDirect   = false;
    
        numberSequenceModules = [NumberSeqModule::MES];
        numberSeqApplicationModule = new NumberSeqModuleMES();
        scope = NumberSeqScopeFactory::createDataAreaScope();//使用当前公司创建scope
        NumberSeqApplicationModule::createReferencesMulti(numberSequenceModules, scope);//在NumberSequenceReference表中创建当前模块的所有引用
        tmpIdRef.setTmpData(NumberSequenceReference::configurationKeyTableMulti(numberSequenceModules));
    }
    
    void numberSeqPostInit()
    {
        numberSequenceReference_ds.object(fieldNum(NumberSequenceReference, AllowSameAs)).visible(numberSeqApplicationModule.sameAsActive());
        referenceSameAsLabel.visible(numberSeqApplicationModule.sameAsActive());
    }

    6.创建一个job调用一次NumberSeqModuleMES的loadModule()方法,注册模块的data type,当然可以放在其他一些地方来调用。loadModule()可以调用多次,它会自动更新已经创建的data type,或者添加新的data type:

    static void InstallModuleMES(Args _args)
    {
        NumberSeqModuleMES n = new NumberSeqModuleMES();
    
        n.loadModule();
    }

    运行一次JOB InstallModuleMES,所有我们模块的Number sequence的准备工作都做好了,接下来就可以使用“set up number sequence” wizard为我们的模块创建Number sequence,上面的例子中scope设置为按公司(DataArea),wizard会为每个公司的WeighingJobId创建一个单独的Number sequence,打开MESParameters窗口就能看到已经分配好的Number sequence。

    在X++代码中我们可以这样得到一个WeighingJobId的编号:

    static void TestNumSeqWeighingJobId(Args _args)
    {
    
        ;
        ttsBegin;//如果是连续的number seuqnce,必须放在ttsbegin...ttscommit中调用
        Info(NumberSeq::newGetNum(MesParameters::numRefWeighingJobId()).num());
        ttsCommit;
    
    }

    要在form上新建纪录时自动填充WeighingJobId需要一些更多的步骤,假设有个表WeighingJobs,字段WeighingJobId使用前面的EDT类型WeighingJobId,创建form WeigingJobs使用表WeigingJobs作为数据源,在WeighingJobs form上实现以下方法:

    public class FormRun extends ObjectRun
    {
        NumberSeqFormHandler numberSeqFormHandler;
    }
    public NumberSeqFormHandler numberSeqFormHandler()
    {
        if (!numberSeqFormHandler)
        {
            numberSeqFormHandler = NumberSeqFormHandler::newForm(
                MESParameters::numRefWeighingJobId().NumberSequenceId,
                 element,
                 WeighingJobs_ds,
                 fieldnum(WeighingJobs, WeighingJobId));
        }
        return numberSeqFormHandler;
    }

    还需要在表WeighingJobs的data source上实现以下方法:

    public void create(boolean _append = false)
    {
        element.numberSeqFormHandler().formMethodDataSourceCreatePre();
        super(_append);
        element.numberSeqFormHandler().formMethodDataSourceCreate();
    }
    public void write()
    {
        super();
        element.numberSeqFormHandler().formMethodDataSourceWrite();
    }
    public void delete()
    {
        element.numberSeqFormHandler().formMethodDataSourceDelete();
        super();
    }

    做完上述工作,在form上新建一个纪录时就能为WeighingJobId字段自动分配编号了。

    这里下载上述测试的样例工程,主要步骤基本上都是参照http://msdn.microsoft.com/EN-US/library/aa608474,重要的是要理解Number sequence framework是如何工作的。

  • 相关阅读:
    双元素非递增(容斥)--Number Of Permutations Educational Codeforces Round 71 (Rated for Div. 2)
    两两内积为0(牛客多校第七场)-- CDMA
    十进制快速幂(牛客多校第五场)-- generator 1
    分层最短路(牛客第四场)-- free
    %300为0的个数(牛客第四场)-- number
    3的倍数 或运算构造x(牛客第四场)-- triples I
    笛卡尔树--牛客第四场(sequence)
    线性基求交(线段树)--牛客第四场(xor)
    最短meeting路线(树的直径)--牛客第四场(meeting)
    最长相同01数的子串(map搞搞)--牛客第三场 -- Crazy Binary String
  • 原文地址:https://www.cnblogs.com/duanshuiliu/p/2703426.html
Copyright © 2020-2023  润新知