欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

用友uap nc65开发-使用自定义公式解决参照多显问题

程序员文章站 2022-03-07 23:39:14
...

用友uap nc65开发-使用自定义公式解决参照多显问题

1.场景描述:在项目开发中,收费清单存在多房产且该字段为参照,在数据库中存在多个pk值且以逗号隔开,但在界面无法显示,在前面博客中已使用另外一种方法解决,但对于数据量大的单据无法处理,会导致宕机。
2.解决思路:使用自定义显示公式,传入参照的表名,pk,name,对应行的pk_head,通过代码处理,将参照对应的pk在对应表中查出对应的name值,并使用逗号分割显示在界面。
3.在home\resources\formulaconfig\custfunction目录下新建一个xml文件配置公式,如图所示:
用友uap nc65开发-使用自定义公式解决参照多显问题
xml文件配置如下:
<?xml version="1.0" encoding="utf-8"?>
<formula-array>
<formula>
  <customType>0</customType>
  <functionName>MultiRefName</functionName>
  <functionClass>nc.itf.fdc_pr.formula.MultiRefNameFormula</functionClass>
</formula>
</formula-array>
其中functionClass对应公式支持的java类,functionName对应公式显示名称。
4.MultiRefNameFormula代码支持类如下:
package nc.itf.fdc_pr.formula;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

import nc.bs.framework.common.NCLocator;
import nc.itf.fdc_crmbd.IH3H045Maintain;
import nc.vo.pub.formulaset.IFormulaConstant;
import nc.vo.pub.formulaset.core.ParseException;
import nc.vo.pub.formulaset.function.PostfixMathCommand;
/**
 * 
 * @author lqh
 *
 */
public class MultiRefNameFormula extends PostfixMathCommand{
	

	public MultiRefNameFormula() {
		numberOfParameters = 4;//参数数量
		functionType = IFormulaConstant.FUN_CUSTOM;//公式类型
		functionDesc = "根据传进来的多选参照主键传出参照显示名称";//公式描述
	}
	
	@Override
	/**
	 * Stack 栈取数据的顺序和存数据的顺序相反(FILO先进后出)
	 * 所以要用反序赋值
	 */
	public void run(Stack s) throws ParseException {
		checkStack(s);
		String tableName = (String) s.pop();//表名
		String pkFieldName = (String) s.pop();//主键字段名
		/**
		 *  传进来的是一个list,其中的每一个String对应一行数据
		 *  所以返回也要返回一个List,对应每一行数据
		 */
		ArrayList<String> pks = (ArrayList<String>) s.pop();//每一行的主键
		String nameFieldName = (String) s.pop();//要获取的字段名
		List<String> names = getRefName(tableName, pkFieldName, pks.toArray(new String[0]), nameFieldName);
//		for (int i = 0 ; i < pks.size() ; i ++){
//			String pk = pks.get(i);
//			if (pk != null){
//				String name = getRefName(tableName,pkFieldName,pk.split(","),nameFieldName);
//				names.add(name);
//			}else{
//				names.add(null);
//			}
//		}
		s.push(names);
	}

	private List<String> getRefName(String tableName, String pkFieldName, String[] pks, String nameFieldName) {
		IH3H045Maintain maintain = NCLocator.getInstance().lookup(IH3H045Maintain.class);
		String[] names = maintain.queryRefName(tableName, pkFieldName, pks, nameFieldName);
		return Arrays.asList(names);
	}

}


重要代码方法在类中已经标记。

public String[] queryRefName(String tableName, String pkFieldName,
			String[] pks, String nameFieldName) {
		if (tableName == null || pks == null || pks.length == 0) {
			return null;
		}
		String[] names = new String[pks.length];
		if (pkFieldName == null) {
			pkFieldName = "pk_head";
		}
		if (nameFieldName == null) {
			nameFieldName = "name";
		}
		BaseDAO dao = new BaseDAO();
		StringBuilder sql = new StringBuilder();
		for (int i = 0; i < pks.length; i++) {
			sql.setLength(0);
			sql.append("select ");
			sql.append(nameFieldName);
			sql.append(" from ");
			sql.append(tableName);
			sql.append(" where ");
			sql.append(pkFieldName);
			sql.append(" in ( '1' ");
			int j = 0;
			if (pks[i] == null){
				names[i] = null;
				continue;
			}
			for (String str : pks[i].split(",")) {
				if (str != null) {
					sql.append(",'").append(str).append("'");
					j++;
					if (j == 300) {
						sql.append(") or pk_head in ( '1' ");
					}
				}
			}
			sql.append(")");
			try {
				String name = (String) dao.executeQuery(sql.toString(),
						new ResultSetProcessor() {

							/**
						 * 
						 */
							private static final long serialVersionUID = -4527998249487262608L;

							@Override
							public Object handleResultSet(ResultSet rs)
									throws SQLException {
								StringBuffer name = new StringBuffer();
								while (rs != null && rs.next()) {
									name.append(rs.getString(1)).append(",");
								}
								if (name.length() != 0) {
									name.deleteCharAt(name.lastIndexOf(","));
									return name.toString();
								}
								return null;
							}
						});
				names[i] = name;
			} catch (DAOException e) {
				ExceptionUtils.wrappBusinessException("查询数据库错误:"
						+ e.getMessage());
			}
		}
		return names;
	}


5.重启服务器,清理缓存,打开单据模版初始化节点,我们使用另外一个字段来实现该多参照名字,在该字段中配置显示公式:
temp->getcolvalue( fdc_pr_bill,pk_allhouses,pk_head ,pk_head );
multirefname( "name",temp,"pk_head" ,"fdc_crmbd_fangchanzhubiao")
先在收费清单表中查出对应行的房产pk值赋给temp,后调用我们写的自定义公式,将值传入。
用友uap nc65开发-使用自定义公式解决参照多显问题

6.结果如下:
用友uap nc65开发-使用自定义公式解决参照多显问题
用友uap nc65开发-使用自定义公式解决参照多显问题用友uap nc65开发-使用自定义公式解决参照多显问题