// =============================================================================
// B28 中文版 — 自定义函数实现(MyFunctions.cs)
// B28 Chinese — Custom function implementation (MyFunctions.cs)
// =============================================================================
//
// 关键点 / Key points:
// 1. 自定义函数所在的类必须是 public static class,方法必须是 public static
// The containing class MUST be public static, methods MUST be public static
// 2. [ExcelFunction] 是 Excel-DNA 的特性:贴在方法上,方法名就变成 Excel 公式
// [ExcelFunction] is the Excel-DNA attribute: paste on a method, the method
// name becomes an Excel formula
// 3. [ExcelArgument(Name="...", Description="...")] 给参数起中文名 + 说明
// [ExcelArgument(Name="...", Description="...")] gives parameters a friendly name + tooltip
// =============================================================================
using ExcelDna.Integration; // Excel-DNA 的核心 API / Excel-DNA core API
namespace MyExcelAddIn
{
///
/// 自定义函数集合 / Custom function collection.
/// 类必须是 public static / The class MUST be `public static`.
///
public static class MyFunctions
{
// -------------------------------------------------------------------------
// 示例 1:两数相加 / Example 1: add two numbers
// Excel 里输入:=MyAdd(10, 20) → 30
// -------------------------------------------------------------------------
[ExcelFunction(
Name = "MyAdd", // Excel 公式名 / Excel formula name
Description = "把两个数相加,返回结果。", // 鼠标悬停提示 / Hover tooltip
Category = "我的工具", // 函数向导分组 / Function-wizard category
IsVolatile = false)] // 非易失(数据没变不重算)/ Non-volatile
public static double MyAdd(
[ExcelArgument(Name = "数值1", Description = "第一个加数")] double x, // 第一个参数
[ExcelArgument(Name = "数值2", Description = "第二个加数")] double y) // 第二个参数
{
return x + y; // 真正干活的 / The real work
}
// -------------------------------------------------------------------------
// 示例 2:字符串拼接 / Example 2: concatenate strings
// Excel 里输入:=MyConcat("Hello", " ", "World") → "Hello World"
// -------------------------------------------------------------------------
[ExcelFunction(
Name = "MyConcat",
Description = "把多个文本拼接成一个字符串。",
Category = "我的工具")]
public static string MyConcat(
[ExcelArgument(Name = "文本1", Description = "第一段文本")] string a,
[ExcelArgument(Name = "文本2", Description = "第二段文本")] string b,
[ExcelArgument(Name = "文本3", Description = "可选的第三段文本")] string c)
{
// 容错:空字符串视为无 / Tolerate empty inputs
string result = (a ?? "") + (b ?? "") + (c ?? "");
return result;
}
// -------------------------------------------------------------------------
// 示例 3:RTD 实时数据包装 / Example 3: wrap an RTD server
// Excel 里输入:=GetLivePrice() → 每隔 ~1 秒跳一个新数
// -------------------------------------------------------------------------
///
/// 包装 RTD 服务 MyExcelAddIn.MyRtdServer,让用户用 =GetLivePrice() 就能调用。
/// Wrap the RTD server MyExcelAddIn.MyRtdServer so users can call =GetLivePrice().
///
[ExcelFunction(
Name = "GetLivePrice",
Description = "获取实时价格(RTD 实时数据示例)。",
Category = "我的工具 - 实时")]
public static object GetLivePrice()
{
// XlCall.RTD(服务全名, 回调参数, 主题1, 主题2, ...)
// XlCall.RTD(serverProgID, callbackParams, topic1, topic2, ...)
// 服务全名按"命名空间.类名"的约定 / Server full name = "Namespace.ClassName"
return XlCall.RTD("MyExcelAddIn.MyRtdServer", null, "PRICE");
}
}
}