DDEを使用したExcel制御について

[戻る]
よこよこ 2003/10/15(水) 12:00:40
こんにちは。いつも参考にさせて頂いております。よこよこです。

今回はVisualStudio.net 2002(VC7) + Windows XP Pro.環境にて開発しております。

自作のデータ収集ソフトで収集したデータをDDEを使用して
Excelに貼り付けようと思い、DDEの勉強も兼ねてダイアログベースで
フォーム上にボタンを1個配置し、下記のようなコードを書いてみました。

このプログラムの概要ですが、大まかに以下のような動作をします。

1.フォーム上のボタンをクリックすると、新規でExcelブックをオープンし、
  最初のワークシートを選択。
2.セルA1〜A17にそれぞれ'0〜'F(0〜16を16進表記の文字列に変換したものの
  先頭にシングルクォートを付けたもの)を書く。
3.セルB1〜B17にそれぞれ隣のセルへの参照を示す=A1〜=A17を書く。
4.セルC1〜C17にそれぞれA1〜A17のセルの値を参照し、10進文字列に
  変換して表示するように=HEX2DEC(A1)〜(A17)を書く。

コンパイルも問題なく通り、実際に動作を確認してみましたが、
4の部分で問題が起きてしまいました。

4の部分のHEX2DECという関数は「分析ツール」と呼ばれているアドインで
提供されているものなんですが、コレがどうやら有効になっていないらしく、
#NAME?というエラー表示になってしまいます。(ただこの時、分析ツール有効の
チェックボックスにチェックは入っている)

しかも、このブックを保存して再度、DDEからではなくExcel単体で起動し、
4の部分を手で打ち直してみると正常に表示が行われます。

そういったことから考えると、DDEで開く時かセルにデータを書き込む方法に
何か間違いがあるのかな?と思うのですが…。

この現象について、どなたか情報をお持ちの方いらっしゃいませんでしょうか?

ちなみにExcelはExcel2002を使用して確認しています。

宜しくお願い致します。

=====

void CExcelTestMFCDlg::OnBnClickedButton1()
{
    // TODO : ここにコントロール通知ハンドラ コードを追加します。
    CWorkbooks oBooks;
    CWorksheets oSheets;
    CWorksheet oSheet;
    CRange oRange;
    COleVariant covOptional(DISP_E_PARAMNOTFOUND, VT_ERROR);

    // EXCELをまだ作成していなければ新しいインスタンスを生成する
    if(oExcel.m_lpDispatch == NULL ){
        oExcel.CreateDispatch("Excel.Application");
    }

    // 画面に表示する
    oExcel.put_Visible(TRUE);
    oExcel.put_UserControl(TRUE);

    // ブックを追加し、1番目のシートを選択する
    oBooks  = oExcel.get_Workbooks();
    oBook   = oBooks.Add(covOptional);
    oSheets = oBook.get_Worksheets();
    oSheet  = oSheets.get_Item(COleVariant((short)1));

    // ここからがセルへのデータ書き込み部分
    int i;
    CString str_Value;
    CString str_Row;

    for(i=0; i<16; i++){
        str_Row.Format("%d", i+1);      //  1〜16の文字列
        str_Value.Format("\'%X", i);    // '0〜'Fの文字列

        // 指定したセルに'0〜'Fを書込
        oRange = oSheet.get_Range(COleVariant("A"+str_Row), covOptional);
        oRange.put_Value2(COleVariant(str_Value));

        // =A?を書込
        oRange = oSheet.get_Range(COleVariant("B"+str_Row), covOptional);
        oRange.put_Value2(COleVariant("=A"+str_Row));

        // =HEX2DEC(A?)を書込
        oRange = oSheet.get_Range(COleVariant("C"+str_Row), covOptional);
        oRange.put_Value2(COleVariant("=HEX2DEC(A"+str_Row+")"));
    }
}

※"CApplication","CRange","CWorkbook","CWorkbooks","CWorksheet","CWorksheets"は
 タイプライブラリからクラスを自動生成したものです。
※oExcel, oBookはCExcelTestMFCDlgのメンバ変数として定義してあります。

=====

渋木宏明(ひどり) [E-Mail] [HomePage] 2003/10/16(木) 01:33:19
>自作のデータ収集ソフトで収集したデータをDDEを使用して

↑の手法は DDE ではなくて「オートメーション」です。

>そういったことから考えると、DDEで開く時かセルにデータを書き込む方法に
>何か間違いがあるのかな?と思うのですが…。

そうですね。

「Excel への働きかけ方」が分からない時は、Excel で解決しましょう。

Excel の [ツール]-[マクロ]-[新しいマクロの記録] で手動操作をマクロとして記録す
ることができるので、記録されたマクロを見れば、「4の部分を手で打ち直してみる」
が実際にはどのような手順であるかが分かります。

「セルに文字列または数値を格納する」のと「セルに式を格納する」のは異なる手順の
ようです。(Excel の仕様)

よこよこ 2003/10/16(木) 10:20:25
こんにちは。よこよこです。
渋木宏明(ひどり)さん、レスありがとうございます。


> ↑の手法は DDE ではなくて「オートメーション」です。
失礼しました。情報を求めてネットをさまよっていた時にDDEと書いているサイトが
あったような気がしまして、そのままDDEと思い込んでしまっていました。


> Excel の [ツール]-[マクロ]-[新しいマクロの記録] で手動操作をマクロとして記録> ることができるので、記録されたマクロを見れば、「4の部分を手で打ち直してみ
る」
> が実際にはどのような手順であるかが分かります。
アドバイスを参考にして、実際に手入力でマクロを記録してみました。

記録したマクロのソースを確認してみると、

    ActiveCell.FormulaR1C1 = "=HEX2DEC(RC[-2])"

のように記録されていましたので、これを参考にして前回のソースの

        // =HEX2DEC(A?)を書込
        oRange = oSheet.get_Range(COleVariant("C"+str_Row), covOptional);
        oRange.put_Value2(COleVariant("=HEX2DEC(A"+str_Row+")"));
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~変更前
の部分を、

        // =HEX2DEC(A?)を書込
        oRange = oSheet.get_Range(COleVariant("C"+str_Row), covOptional);
        oRange.put_FormulaR1C1(COleVariant("=HEX2DEC(RC[-2])"));
               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~変更後
のように変更してみました。が、結果は前回と同じでした。

また、色々試してみて分かったことですが、上記のoRange.put_FormulaR1C1〜部分で
書き込む数式を、アドインで実装される関数等ではなく標準で実装されている関数を
使って(式自体は全く違うものなので結果は異なりますが)試してみたところ(下記)
これはput_FormulaR1C1/put_Value2のどちらを使ってもエラーにはならずに、正常に
動作することが確認できました。

        oRange.put_FormulaR1C1(COleVariant("=IF(ISBLANK(RC[-2]),\"BLANK\",RC[-
2])"));
        oRange.put_Value2(COleVariant("=IF(ISBLANK(RC[-2]),\"BLANK\",RC[-
2])"));

ここまでの結果から予想すると、どうやらセルへの書込方法が問題なのではなく、
ブックを開く時点で何か方法が間違っているか操作が足りないためにアドインが
有効になっていないのではないかと思えてしまいます。

こちらでも引き続き調査していくつもりですが、他にも情報お持ちの方が
いらっしゃいましたら教えて下さい。
宜しくお願い致します。

渋木宏明(ひどり) [E-Mail] [HomePage] 2003/10/18(土) 16:11:29
>アドインが有効になっていないのではないかと思えてしまいます。

アドインを有効にするには、アドインの Installed プロパティに True をセットするだ
けでOKだったと思います。

分析ツールを有効にするなら、Application.AddIns("分析ツール").Installed = True 
かな?

古いスレッドには追加発言できません。