次の方法で共有


DLL からのユーザー定義関数の呼び出し

適用対象: Excel 2013 | Office 2013 | Visual Studio

ワークシートからユーザー定義関数 (UDF) を呼び出すことは、組み込み関数を呼び出すのと同じくらい簡単です。セル数式を使用して関数を入力します。 ただし、C API からは、コールバックで使用する定義済みの関数コードはありません。 UDF を呼び出せるように、C API は XLL 専用関数 xlUDF 関数をエクスポートします。 関数の最初の引数は文字列としての関数名であり、後続の引数は UDF で通常想定される引数です。

引数 44 を指定した xlfGetWorkspace 関数を使用して、現在登録されている XLL アドインの関数とコマンドの一覧を取得できます。 これは 3 列の配列を返し、各列は次を表します。

  • XLL の完全パスとファイル名

  • XLL からエクスポートされた UDF またはコマンドの名前

  • 戻り値と引数コード文字列

注:

[!����] XLL �t�@�C������G�N�X�|�[�g���ꂽ�Ƃ��̖��O�́AExcel ���F�����Ă��� UDF �܂��̓R�}���h�̓o�^���Ƃ͈�v���Ȃ��”\��������܂��B

Excel 2007 以降では、Analysis Toolpak (ATP) 関数が完全に統合され、C API には PRICE、 xlfPrice などの関数の独自の列挙体があります。 以前のバージョンでは、こうした関数の使用には、xlUDF を使用する必要がありました。 アドインが Excel 2003 および Excel 2007 以降のバージョンで動作する必要があり、これらの関数を使用している場合は、現在のバージョンを検出し、適切な方法で関数を呼び出す必要があります。

次の例は、実行中の Excel のバージョンが 2003 以前の場合に、ATP 関数 PRICE を呼び出す xlUDF 関数を表しています。 この例の gExcelVersion12plus など、グローバル バージョン変数の設定については、「 下位互換性」を参照してください。

注:

[!����] ���̗�ł́A�t���[�����[�N�֐� TempNum�A TempStrConst ��g�p���A��������� Excel �� C API ��Ăяo���悤�ɐݒ肵�Ă��܂��B

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 は変更されていません。 たとえば、次の 2 つの 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 ��Ăяo���ꍇ�A pxArg �̒l �� Excel12 �ւ̌Ăяo����ł�ς�炸�A UDF_1 ���Ԃ��l�� xRetVal �Ɋ܂܂�Ă��܂��B

この方法で UDS への呼び出し回数を多く行う場合、まず最初に xlfEvaluate 関数を使用して関数の名前を評価できます。 その結果の数は、xlfRegister 関数が返す登録 ID と同じで、関数名の代わりに xlUDF 関数への最初の引数として渡すことができます。 これにより Excel は、関数名の検索が毎回必要な場合に比べ、より速く関数を検索、呼び出すことができます。

関連項目