UDF的参数限制
在UDF的开发中,大多数类型的参数使用和编写普通函数相同。但是对于参数,UDF也有很多限制。
http://technet.microsoft.com/zh-cn/windows/ms495224.aspx
上述文章说明的是Excel Services UDF中对于参数的说明,记录下来:
-------------------------------------------------
哪些数据类型可以用作 UDF 参数?
所支持的数据类型如下所示:
数值类型:Double、Single、Int32、UInt32、Int16、UInt16、Byte、Sbyte
字符串
布尔值
对象数组:一维或二维数组,即对象 [] 和对象 [,]
DateTime
-----------------------------------------------
有哪些受支持的返回值类型?
所支持的返回值类型如下所示:
数值类型:Double、Single、Int32、UInt32、Int16、UInt16、Byte、Sbyte
字符串
布尔值
对象数组:一或二维数组,即,对象 []、对象 [,]、int[] 和 int[,])
DateTime
对象
------------------------------------------------
对于UDF参数的限制有个大概的了解后,需要根据自己的功能需求进行针对性设计。
Range对象的引入
UDF往往要处理用户自己选择的Excel区域,这时候就需要Range参数。
例如:
public int GetMultiValues(string myserver,Excel.Range tagNameRange ,int mode)
传给tagNameRange 的是 $4$1:$12$1 之类的数据
下面举个简单的例子,实现的功能是将Range传给UDF函数,该函数将Range中对应的
测点的历史值以二维数组的方式返回。
/// <summary>
/// 从Excel.Range中获取测点列表
/// </summary>
/// <param name="tagNameRange"></param>
/// <param name="rowCount"></param>
/// <param name="columnCount"></param>
/// <returns></returns>
private string[] GetTagsFromRange(Excel.Range tagNameRange, int rowCount, int columnCount)
{
string[] tags = new string[rowCount];
for (int i = 1; i < rowCount + 1; i++)
{
for (int j = 1; j < columnCount + 1; j++)
{
tags[i - 1] = Convert.ToString((tagNameRange.Cells[i, j] as Excel.Range).Value2);
}
}
return tags;
}
public string[,] GetMultiArchive(string serverName, Excel.Range tagNameRange, DateTime time, int outputMode)
{
string[,] resultStr= null;
int rowCount = tagNameRange.Rows.Count;
int columnCount = tagNameRange.Columns.Count;
int columnMax = 0;
resultStr = InitResultArray(rowCount, columnCount, outputMode, out columnMax);
RDL_Interface m_rtdb = new RDL_Interface(serverName, ServePort, User, PassWord);
int resultInt = -1;
if (0 != m_rtdb.Connect())
{
return resultStr;
}
//读取测点点表
int[] errorArray = new int[rowCount];
string[] tags = GetTagsFromRange(tagNameRange, rowCount, columnCount);
Rython.iData[] valusArray = new Rython.iData[rowCount];
for (int i = 0; i < rowCount; i++)
{
valusArray[i] = new Rython.iData();
valusArray[i].Tagname = tags[i];
valusArray[i].TimeStamp = time;
}
resultInt = m_rtdb.GetHisDatas(ref valusArray, ref errorArray, time);
if (0 == resultInt)
{
resultStr = ConvertData2StringArray(valusArray, errorArray, columnMax);
}
return resultStr;
}
这里有个细节需要注意。 i,j是自定义,下标从1开始。
---------------------------------------
UDF函数结果显示
UDF函数如果返回的是多维数组,那么单元格里面公式和参数输入以后,回车。只能显示一个格子。
要完整的显示返回的多维数据,需要选择以公式所在单元格为首的区域,按F2,再同时按Ctrl+Shift+Enter(三键确认)
选择的区域行数列数要大于等于返回的数组,否则数组不显示或显示不完全。