zoukankan      html  css  js  c++  java
  • AX中操作Excel

    2011.04.17进入融贯资讯,离开了熟悉的C#,开始另一段开发之路。X++!!

    找到了组织,加入了专业的开发团队,有专业的老师,前辈指路。虽然对ERP还比较模糊,慢慢努力,哈哈!

    在前辈的指导下, 为期一周的库存初始化。下面把开发中用到的东西简单介绍一下,好自己以后查找。

    需要用到的类:

     SysExcelCell;SysExcelComment;SysExcel;SysExcelRange;
    新添加的类:
     在AX中没有关于excel验证的类,类似于SysExcelComment(备注)添加了一个类ROG_SysExcelValidation类。
    ROG_SysExcelValidation中新增方法:
    //在AX中添加类的字段申明在ClassDeclaration中
    class ROG_SysExcelValidation extends SysExcel
    {
            MSOfficeVersion version;
    }
    //注意所有的关于excel的操作在AX中都会继承自SysExcel类
    //所以在SysExcel中添加了新变量
    //COM  ROG_Validation;
    //返回COM对象
    public COM comObject()
    {
        return ROG_Validation;
    }
    //关于验证的一些删除操作吧。不过我自己还没有验证是否正确。
    public void delete()
    {
        ROG_Validation.delete();
    }
    //本类的构造函数,注意两个入参
    static client ROG_SysExcelValidation construct(MSOfficeVersion _version, COM _validation)
    {
        return new ROG_SysExcelValidation(_validation, _version);
    }
    //实例化方法
    protected void new(COM _validation, MSOfficeVersion _version)
    {
        ;
        super();
        version = _version;
        ROG_Validation = _validation;
    }
    //仿造commont类写的方法,还没有验证是否正确。
    public str text(str _text = comment.text())
    {
        return ROG_Validation.text(_text);
    }

    因为都是给range(Excel)中的区域添加验证。给range里面添加一个方法ROG_AddValidation

    public ROG_SysExcelValidation ROG_AddValidation(ROG_ValidationType _type,int _i = 0)
    {
        //申明一个range.Validation()需要返回的一个com对象
        COM     validationLocal;
        ;
       
        //此举仿照ASP.NET中range的Validation属性,试出来的。
        validationLocal = range.Validation();
       
        //在这开发中还定义了一个枚举类型ROG_ValidationType
        //对应的三个值validationString,validationReal,ValidationInt64分别对三个不同类型的数据类型添加不同的判断
        switch(_type)
        {
            case ROG_ValidationType::validationString:
            {
         //此方法也是仿效asp.net中的range对象方法(参数一:对应excel中验证的数据类型)
         //参数2:错误提示框的方式(分别有stop,warning,information)
         //参数3:验证类型所对应的方式,比如说大于,小于或等于。等等。都是枚举类型。
         //参数4,5:对应需要验证的数据类型的范围。
                validationLocal.add(6,1,1,0,20);
         //在。net中ErrorTitle是对应的属性,在AX中封装成了COM的方法。
                validationLocal.ErrorTitle("Error");
         //错误提示信息。
                validationLocal.ErrorMessage("input string length must 0 between 20");
                break;
            }
            case ROG_ValidationType::validationReal:
            {
                validationLocal.add(2,1,1,0,10000);
                validationLocal.ErrorTitle("Error");
                validationLocal.ErrorMessage("Please enter the value between 0 to 10000");
                break;
            }
            case ROG_ValidationType::ValidationInt64:
            {
                validationLocal.add(1,1,5,0);
                validationLocal.ErrorTitle("Error");
                validationLocal.ErrorMessage("Please enter the value greater than 0");
                break;
            }
            default:
                break;
        }

        //返回一个range对象,range的构造函数version对应的版本MSOfficeVersion。
        return ROG_SysExcelValidation::construct(version, validationLocal);

    }
    这样就对range验证规则添加了方法,根据不同的验证数据类型添加相应的验证规则。

    下面都是对库存初始化的操作了。
    首先添加一个关于库存初始化的类ROG_InveertoryInitExcel.
    class ROG_InvertoryInitExcal
    {
        //操作excel必须的app对象
        SysExcelApplication                     excApp;
        //excel中的workbook集合对象
        SysExcelWorkbooks                       excBooks;
        //工作薄对象
        SysExcelWorkbook                        excBook;
        //每一个workbook里面都会有worksheet的集合对象
        SysExcelWorksheets                      excSheets;
        //
        SysExcelWorksheet                       excSheet;
        //单元格的集合
        SysExcelCells                           excCells;
        SysExcelCell                            excCell;
        //备注对象
        SysExcelComment                         excComment;
        //区域对象。这个是为添加验证的。
        SysExcelRange                           excRange;
    }


    public void createExcel(container _conColums,container _conCommons,container _conType,FileName _fileName,ROG_IfOpen _ifOpen)
    {
        int                                 i;
        //调用本类方法的类对象
        ROG_InvertoryInitExcal              invertoryInitExcal;
        COMVariant                          variant = new COMVariant();
        COM                                 com;
        COM                                 comRange;
        ;
        //给一个字符串返回variant对象的字符串
        variant.bStr(_fileName);
        invertoryInitExcal = new ROG_InvertoryInitExcal();

        try
        {
            excApp = SysExcelApplication::construct();
            excBooks = excApp.workbooks();
            excBook = excBooks.add();
            excSheets = excBook.worksheets();
     //返回的是一个excelSheet   就是直接excel里面的sheet1
            excSheet = excSheets.itemFromNum(1);
            excCells = excSheet.cells();

            for(i = 1;i <= conLen(_conColums); i++)
            {
         //给第一行的I列添加容器_conCommons第I列的值。
                excCells.item(1,i).value(conPeek(_conColums,i));
         //给第一行的I列添加容器_conCommons第I列的值。
                excComment = excCells.item(1,i).addComment(conPeek(_conCommons,i));
         //下面两行是仿造。net中的range对象的EntireColumn方法,可能在AX中全部封装在COM中,在range
         //里面没有表现出来。所以得先赋值给一个COM对象了。
                com = excCells.item(1,i).comObject();
         //得到的是第一行所有列的一个区域。
                comRange = com.EntireColumn();
         //注意第二个参数是要COM对象的range。
                excRange = SysExcelRange_2000::ROG_construct(MSOfficeVersion::Office2000,comRange);
         //循环给每一列添加验证。
                switch(conPeek(_conType,i))
                {
                    case Types::Int64:
                    case Types::Integer:
                        excRange.ROG_AddValidation(ROG_ValidationType::ValidationInt64);
                        break;
                    case Types::Real:
                        excRange.ROG_AddValidation(ROG_ValidationType::validationReal);
                        break;
                    case Types::String:
                        excRange.ROG_AddValidation(ROG_ValidationType::validationString);
                        break;
                    default:
                        break;
                }
            }

            //先把所有的单元格解锁。locked方法也仿照.net中,在AX中还是属于COM对象。
            excApp.activeSheet().cells().comObject().locked(false);
            //锁住特定的区域
            excRange =  excApp.activeSheet().range("1:1");
            excRange.comObject().locked(true);
            //给sheet添加一个保护码
            excApp.activeSheet().protect("sfs");
            //将excel保存到相对应的路径中去。
            excBook.saveAs(_fileName);
            if(_ifOpen == NoYes::Yes)
            {
                excApp.visible(true);
            }
            else
            {
                excBooks.close();
                excApp.quit();
            }

        }
        catch(exception::Error)
        {
            if(!excApp)
                excApp.quit();
        }
    }
    下面方法就把需要插入到excel表头的值给添加进去了。
    //第一个参数,表名,第二个参数:要保存的字段名,是否打开。
    void createNewExcel(ROG_TableName _tableName,FileNameSave _fileNameSave,ROG_IfOpen _ifOpen)
    {
     //需要插入的原表对象
            ROG_FieldMapping                    fieldMapping;
     //系统表,处理字段对象。
            DictField                           dictField;
     //所有列的容器
            container                           conColums;
     //所有备注的容器
            container                           conCommons;
     //所有数据类型容器
            container                           conType;
            int                                 i;
            ;
            //dictTable = new DictTable(tableNum(ROG_InvertroyData));
            while select fieldMapping
                order by FieldOrder
                where  fieldMapping.IfImported == NoYes::Yes &&
                       fieldMapping.TableName == _tableName
            {
         //将ROG_FieldMapping的FieldName添加到dictField中去                   
                dictField = new DictField(tableName2Id(_tableName),fieldName2Id(tableName2Id(_tableName),fieldMapping.FieldName));
         //将列名添加到列容器
                conColums = conIns(conColums,conLen(conColums)+1,dictField.label());
         //将帮助注释添加到备注容器中去。
                conCommons = conIns(conCommons,conLen(conCommons)+1,dictField.help());
         //将字段的基础类型添加到类型容器中去。
                conType = conIns(conType,conLen(conType)+1,dictField.baseType());
            }
     //将已有的容器调入到创建Excel方法中去。
            this.createExcel(conColums,conCommons,conType,_fileNameSave,_ifOpen);
    }
    上面那些只是一些操作excel中的对象,方法。下面的是在AX窗体中怎么调用上述一些方法。
    在窗体ROG_Invertory中的datasourse为表ROG_InvertoryData.
     在设计里面添加一个grid,grid的datasourse为ROG_InvertoryData.
     设计还有一个buttongroup,包含两个MenuItemButton:Mapping  调用映射窗体。CreateTemplate 调用创建Excel窗体。
     这中间值得注意的是,因为在跳到映射窗体去的时候会有一个窗体之间的传值问题,给MenuItemButton的datasourse属性设置为表 ROG_InvertoryData.MenuItemName 属性是设置跳到哪个窗体。
    窗体ROG_FieldMapping 映射窗体。在窗体方法中添加了createMappingRecords()方法
    void createMappingRecords()
    {
        ROG_TableName                   tableName;
        int                             i;
        ROG_FieldMapping                fieldMapping;
        DictTable                       dictTable;
        DictField                       dictField;
        ;
        //得到所要操作的表对象
        dictTable = new DictTable(element.args().record().TableId);
        //往fieldMapping中添加数据。
        ttsbegin;
            delete_from fieldMapping;
            for(i = 1;i<= dictTable.fieldCnt() - 15;i++)
            {
                fieldMapping.TableName = tableId2Name(element.args().record().TableId);
                fieldMapping.FieldName = fieldId2Name(element.args().record().TableId,dictTable.fieldCnt2Id(i));
                fieldMapping.IfImported = NoYes::Yes;
                fieldMapping.FieldOrder = i;
                fieldMapping.insert();
            }
        ttscommit;
    }
    将上述方法在run中运行。
    public void run()
    {
        super();
        this.createMappingRecords();
    }
    本窗体的datasourse为表ROG_FieldMapping
    本窗体的设计中一个grid,值得注意的是里面的checkBox空间的扩展数据类型是ROG_IfImported,他的EmnuType是NoYes

    最后一个窗体:ROG_CreateTemplate.主要在里面button按钮BtnImport中重写了clicked方法()
    void clicked()
    {
        ROG_InvertoryInitExcal              invertoryInitExcal;
        ;
        super();
        invertoryInitExcal = new ROG_InvertoryInitExcal();
        //第一个参数表名,第二个参数  文件路径,第三个参数是否打开!
        invertoryInitExcal.createNewExcel("ROG_InvertroyData",FileOpen.valueStr(),IfOpen.value());
    }

    第一次写这玩意,慢慢积累!加油!

  • 相关阅读:
    ngnix+uwsgi+django 部署mezzanine
    shell三剑客之find
    Flask常见面试问题
    redis宕机如何解决?如果是项目上线的宕机呢?
    UiPath,容智Ibot在线接单,有需求的欢迎过来
    CORS和CSRF
    JWT黑名单和白名单
    Django项目常见面试问题
    降低Redis内存占用
    Redis-缓存有效期与淘汰策略
  • 原文地址:https://www.cnblogs.com/boydg123/p/2031135.html
Copyright © 2011-2022 走看看