AX 2012 R2运行时网格数据导出(适配筛选)方案咨询
AX 2012 R2 网格数据精准导出解决方案(匹配当前显示)
问题回顾
需要实现网格数据导出,要求完全匹配当前网格显示状态:筛选后导出单条/筛选结果,无筛选导出全部记录。原代码存在以下问题:
- 性能极差,大数据量下卡顿明显
- 偶发崩溃、部分行丢失
numRows取表记录数,完全不支持网格筛选场景,导出数据和显示不一致
原代码问题分析
for(j = 1 ; j <= numRows; j++) { try { s = formGridControl.getLineData(j); // UI层逐行取数,性能差且易越界崩溃 } catch { infolog.clear(); break; // 直接中断导致丢行 } arr = s.value('lines'); tempArray = arr.value(1); for(z=2; z<=tempArray.lastIndex(); z++) // 硬编码索引,网格列变化时直接错位丢数据 { finalArray = tempArray.value(z); line2+=[finalArray]; } row = this.parseContainer1(line2,separator); tempFile.write(row); line2 = conNull(); }
可行解决方案
核心思路:直接获取网格绑定数据源的筛选后数据集,而非从UI层逐行读取,同时匹配网格可见列顺序。
完整代码实现
public void exportGridToCsv(FormGridControl _formGridControl, str _fileName) { FormDataSource formDataSource; QueryRun queryRun; TableId tableId; DictTable dictTable; FieldId fieldId; List visibleColumns; ListEnumerator enumerator; str csvHeader, csvRow; FileIOPermission filePerm; AsciiIo asciiIo; #File // 初始化控件与数据源 formDataSource = _formGridControl.dataSource(); queryRun = formDataSource.queryRun(); // 获取已筛选的查询结果,完全匹配网格显示 tableId = formDataSource.table(); dictTable = new DictTable(tableId); // 获取网格可见列(按显示顺序) visibleColumns = _formGridControl.visibleColumns(); enumerator = visibleColumns.getEnumerator(); // 构建CSV表头 while (enumerator.moveNext()) { fieldId = enumerator.current(); csvHeader += strFmt('"%1",', dictTable.fieldName(fieldId)); } // 移除最后一个多余逗号 if (strlen(csvHeader) > 0) { csvHeader = substr(csvHeader, 1, strlen(csvHeader) - 1); } // 处理文件权限 filePerm = new FileIOPermission(_fileName, #io_write); filePerm.assert(); // 初始化文件流 asciiIo = new AsciiIo(_fileName, #io_write); asciiIo.outFieldDelimiter(','); asciiIo.outRecordDelimiter('\r\n'); // 写入表头 if (csvHeader) { asciiIo.write(csvHeader); } // 遍历筛选后的记录写入CSV while (queryRun.next()) { csvRow = ''; enumerator.reset(); while (enumerator.moveNext()) { fieldId = enumerator.current(); // 处理特殊字符(比如双引号)避免CSV格式错误 csvRow += strFmt('"%1",', strReplace(queryRun.get(tableId).(fieldId), '"', '""')); } if (strlen(csvRow) > 0) { csvRow = substr(csvRow, 1, strlen(csvRow) - 1); asciiIo.write(csvRow); } } // 释放权限 CodeAccessPermission::revertAssert(); info(strFmt("导出完成,文件路径:%1", _fileName)); }
方案优势
- 精准匹配显示:通过
formDataSource.queryRun()直接获取网格经过筛选、排序后的数据集,完全和当前显示一致 - 性能优异:直接从数据源层读取数据,避免UI层频繁交互,大数据量下无卡顿
- 稳定性高:规避
getLineData()的索引越界问题,不会出现崩溃或丢行 - 自适应列:自动获取网格可见列,列顺序、显示/隐藏状态变化时无需修改代码
- 格式兼容:处理双引号转义,避免CSV格式错误
使用方式
在表单的导出按钮点击事件中调用:
void clicked() { str fileName; fileName = WinAPI::getSaveFileName(element.hWnd(), ["CSV files (*.csv)|*.csv|All files (*.*)|*.*"], '', 'ExportGridData', 'csv'); if (fileName) { this.exportGridToCsv(YourGridControlName, fileName); } }
内容的提问来源于stack exchange,提问作者Devv
相关产品推荐
相关产品推荐

