共用方式為


從 DLL 呼叫使用者定義函式

適用於:Excel 2013 |Office 2013 |Visualstudio

從工作表 (UDF) 呼叫使用者定義函式就像呼叫內建函式一樣簡單:您可以透過單元格公式輸入函式。 不過,從 C API 中,沒有預先定義的函式程式代碼可搭配回呼使用。 為了讓您能夠呼叫 UDF,C API 會匯出僅限 XLL 的函式 xlUDF 函式。 函式的第一個自變數是作為字串的函式名稱,而後續的自變數則是UDF通常預期的自變數。

您可以使用 xlfGetWorkspace 函式搭配自變數 44,以取得目前註冊的 XLL 載入宏函數和命令清單。 這會傳回三欄陣列,其中的數據行代表下列專案:

  • XLL 的完整路徑和名稱

  • 從 XLL 導出的 UDF 或命令名稱

  • 傳回和自變數程序代碼字串

注意事項

從 XLL 導出的名稱可能與 Excel 知道 UDF 或命令的已註冊名稱不同。

從 Excel 2007 開始,ANALYSIS Toolpak (ATP) 函式已完全整合,而 C API 具有其專屬的函式列舉,例如 PRICE、 xlfPrice。 在舊版中,您必須使用 xlUDF 來呼叫這些函式。 如果您的載入宏需要使用 Excel 2003 和 Excel 2007 或更新版本,且其使用這些函式,您應該偵測目前的版本,並以適當的方式呼叫函式。

範例

下列範例顯示當 Excel 的執行版本為 2003 或更早版本時,用來呼叫 ATP 函式 PRICExlUDF 函數。 如需有關設定全域版本變數的資訊,例如此範例中的 gExcelVersion12plus ,請參閱 回溯相容性

注意事項

此範例會使用 Framework 函式 TempNumTempStrConst 來設定自變數,並使用 Excel 來呼叫 C API。

LPXLOPER TempNum(double d);
LPXLOPER TempStrConst(const LPSTR lpstr);
int cdecl Excel(int xlfn, LPXLOPER pxResult, int count, ...);
double call_ATP_example(void)
{
  XLOPER xPrice;
  int xl_ret_val;
  if(gExcelVersion12plus) // Starting in Excel 2007
  {
    xl_ret_val = Excel(xlfPrice, &xPrice, 7,
      TempNum(39084.0), // settlement date 2-Jan-2007
      TempNum(46706.0), // maturity date 15-Nov-2027
      TempNum(0.04), // Coupon
      TempNum(0.05), // Yield
      TempNum(1.0), // redemption value: 100% of face
      TempNum(1.0), // Annual coupons
      TempNum(1.0)); // Rate basis Act/Act
  }
  else // Excel 2003-
  {
    xl_ret_val = Excel(xlUDF, &xPrice, 8,
      TempStrConst("PRICE"),
      TempNum(39084.0), // settlement date 2-Jan-2007
      TempNum(46706.0), // maturity date 15-Nov-2027
      TempNum(0.04), // Coupon
      TempNum(0.05), // Yield
      TempNum(1.0), // redepmtion value: 100% of face
      TempNum(1.0), // Annual coupons
      TempNum(1.0)); // Rate basis Act/Act
  }
  if(xl_ret_val != xlretSuccess || xPrice.xltype != xltypeNum)
  {
// Even though PRICE is not expected to return a string, there
// is no harm in freeing the XLOPER to be safe
    Excel(xlFree, 0, 1, &xPrice);
    return -1.0; // an error value
  }
  return xPrice.val.num;
}

當您呼叫透過就地修改自變數來傳回值的 XLL 函式時, xlUDF 函式仍會透過結果 XLOPER/XLOPER12的位址傳回值。 換句話說,結果會如同透過一般 return 語句一樣傳回。 未修改對應至用於傳回值之自變數的 XLOPER/XLOPER12 。 例如,請考慮下列兩個 UDF。

// Registered as "1E". Returns its argument incremented by 1.
void WINAPI UDF_1(double *pArg)
{
  *pArg += 1.0;
}
// Registered as "QQ". Returns its argument unmodified
// unless it is a number, in which case it increments it
// by calling UDF_1.
LPXLOPER12 WINAPI UDF_2(LPXLOPER12 pxArg)
{
  static XLOPER12 xRetVal; // Not thread-safe
  XLOPER12 xFn;
  xFn.xltype = xltypeStr;
  xFn.val.str = L"\005UDF_1";
  Excel12(xlUDF, &xRetVal, 2, &xFn, pxArg);
  xRetVal.xltype |= xlbitXLFree;
  return &xRetVal;
}

UDF_2呼叫 UDF_1 時,在呼叫 Excel12 之後,pxArg 的值會保持不變,而 UDF_1 傳回的值會包含在 xRetVal 中。

當您以這種方式對 UDF 進行大量呼叫時,可以先使用 xlfEvaluate 函式來評估函式名稱。 產生的數位與 xlfRegister 函式所傳回的註冊標識符相同,可以將函式名稱當做第一個自變數傳遞給 xlUDF 函式。 這可讓 Excel 比每次都必須查閱函式名稱更快速地尋找和呼叫函式。

另請參閱