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());
}

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

原文地址:https://www.cnblogs.com/boydg123/p/2031135.html