问:问题描述:
1.自定义公式标注为可序列化 测试代码如下:
[Serializable]
public class CustFun : FunctionInfo
{
public string _Name = String.Empty;
public int _MinArgs = 0;
public int _MaxArgs = 0;
public int _FunType = 0;
public int Row = 0;
public int Col = 0;
public string _SQL = string.Empty;
public override string Name
{
get { return _Name; }
}
public override int MaxArgs
{
get { return _MaxArgs; }
}
public override int MinArgs
{
get { return _MinArgs; }
}
public int FunType
{
get { return _FunType; }
}
public string SQL
{
get { return _SQL; }
}
public override object Evaluate(object[] args)
{
return "Test";
}
2.把自定义公式设置到Grid的当前工作簿中,测试代码如下:
private void button1_Click(object sender, EventArgs e)
{
Gd.ActiveSheet.AutoCalculation = false;
for (int i = 0; i < 100; i++)
{
CustFun a = new CustFun();
a._Name = "abc" + i.ToString();
a._FunType = 2;
a._SQL = "select 1";
//tag.Fun.Add("a" + i.ToString(), a);
Gd.ActiveSheet.AddCustomFunction(a);
Gd.ActiveSheet.SetFormula(1, i, a._Name+"()");
}
Gd.Save("C:\\def.xml", true);
}
}
3.加载模扳文件,测试代码如下:
private void button3_Click(object sender, EventArgs e)
{
Gd.Open("C:\\def.xml");
}
4.现象:一加载模板,公式就会自动计算,如果想加载模板后,公式不自动计算,该如何设置?
答:是否序列化CustFun应该对这个用例没有影响。
经过我们的验证,确实如您所述,在这样的用例下,确实显示了计算结果。
如果想要达到您所说的效果,可以将这些Cell的Text清空。代码如下:
for (int i = 0; i < this.fpSpread1.ActiveSheet.ColumnCount; i++)
{
this.fpSpread1.ActiveSheet.Cells[1, i].Text = string.Empty;
}
问:
1。现在我用咱们那控件是要做报表系统,我序列化自定义公式是为了让控件保存定义好的模板时把自定义公式也保存在模板文件中,这样下次再加载模板时就不用再调用 Gd.ActiveSheet.AddCustomFunction(a); 来创建自定义公式了,现在如果真的一加载模板就计算的在模板维护模块这样是不合适的,虽然手动可以清楚内容,所以我才考虑是否控件有什么属性可以设置,使其加载模板时不自动计算,不然似乎这是个不可控的问题。
2。如果自定义公式对象不标志为序列化,那么就保存不到模板里,下次加载模板后,设置公式的单元格会显示为:#NAME? 怎么才能不显示 #NAME? 呢?
代码示例:(注:Cell的单元格类型为字符型)
//定义自定义函数
public class CustFun : FunctionInfo
{
public string _Name = String.Empty;
public int _MinArgs = 0;
public int _MaxArgs = 0;
public int _FunType = 0;
public int Row = 0;
public int Col = 0;
public string _SQL = string.Empty;
public override string Name
{
get { return _Name; }
}
public override int MaxArgs
{
get { return _MaxArgs; }
}
public override int MinArgs
{
get { return _MinArgs; }
}
public int FunType
{
get { return _FunType; }
}
public string SQL
{
get { return _SQL; }
}
public override object Evaluate(object[] args)
{
return "def";
}
}
//设置公式,并保存模板
private void button1_Click(object sender, EventArgs e)
{
Gd.ActiveSheet.AutoCalculation = false;
CustFun a = new CustFun();
a._Name = "abc";
Gd.ActiveSheet.AddCustomFunction(a);
Gd.ActiveSheet.SetFormula(15, 0, "abc()");
Gd.Save("C:\\def.xml", true);
}
//加载模板文件
private void button3_Click(object sender, EventArgs e)
{
Gd.Open("C:\\def.xml");
//CustFun a = new CustFun();
//a._Name = "abc";
//Gd.ActiveSheet.AddCustomFunction(a);
}
答:您说的很清楚。
1. 序列化自定义公式类的问题,在您的用例下,确实需要序列化,您是正确的。
2. 自动计算和出现#NAME?是同一个问题。就是在设置了AutoCalculation = false情况下,通过Open方法打开模板,导入公式,仍然显示了计算结果。这一点应该是缺陷,目前无法解决。你可以用给出的代码,在Open之后,清除一次Text。