Last Updated 2003/06/11
Visual C++ MFC OLE
Excelへ文字列渡し
2003/06/11

Excelのセルへ文字列を書き込む.
char * から OLESTR 型への変換が必要となる.

A1〜A800に文字列を入れる簡単なサンプルは以下のとおり(遅い)

void CMyDlg::OnExcel() 
{
    // TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
    COleVariant variant;    //  VARIANT 型
    if( !m_pExcel->CreateDispatch("Excel.Sheet.5") )
        AfxMessageBox("couldn't create sheet object");

    CString sCell, sStr;
    for(int i = 1; i <= 800; i++) {
        sCell.Format("A%d", i);
        sStr.Format("%d", i);
        PutStr(sCell, sStr);  
    }
}


void CMyDlg::PutStr(CString cell, CString s)
{
    COleVariant vCell(cell);
    COleVariant vString(s);

    VARIANT vRet;

    vRet = m_pExcel->Range(vCell, vCell);
    Range range(V_DISPATCH(&vRet));
    range.SetValue(vString);
}

このサンプルをもとに動かしてみる.

    V_VT(&v) = VT_BSTR;
    V_BSTR(&v) = SysAllocString(OLESTR("A1"));
    vRet = worksheet.Range1(v);
    VariantClear(&v); 
    ASSERT(V_VT(&vRet) == VT_DISPATCH);
    range.AttachDispatch(V_DISPATCH(&vRet));
    V_VT(&v) = VT_BSTR;
    V_BSTR(&v) = SysAllocString(OLESTR("アラームメッセージ"));
    range.SetValue(v);

    CString sCell, sData;
    for( int i = 0 ; i < 800 ; i++ ) {
        sCell.Format( "A%d", i+2 );
        sData = ReadText( i );
        COleVariant vCell( sCell );
        COleVariant vData( sData );
        vRet = worksheet.Range1( vCell );
        range.AttachDispatch(V_DISPATCH(&vRet));
        range.SetValue( vData );

        if( ::PeekMessage(&message, NULL, 0, 0, PM_REMOVE) ) {
            ::TranslateMessage(&message);
            ::DispatchMessage(&message);
        }
    }

これだと800件80文字のデータを渡すのに30秒ほどかかってしまう.(非常に遅い)
速くするには DISPATCH の回数を減らさなくてはならない.それには配列渡しが必要となる.
Excelには左上と右下のセルを指定して2次元配列として渡す.

    COleSafeArray array;
    CString dummy;

    DWORD elm[2] = {800, 1};

    array.Create(VT_BSTR, 2, elm);
    elm[1] = 0;
    for(long i = 0; i < 800; i++) {
        dummy.Format("%i", i);
        elm[0] = i;
        array.PutElement((long *)elm, dummy.AllocSysString());
    }
    PutArray("A1", "A800", &array);

void CMyDlg::PutArray(CString cells, CString celle, COleSafeArray *a)
{
    COleVariant vCells(cells);
    COleVariant vCelle(celle);
    COleVariant vArray(*a);

    VARIANT vRet;

    vRet = m_pExcel->Range(vCells, vCelle);
    Range range(V_DISPATCH(&vRet));
    range.SetValue(vArray);
}




参照
前後のTips
Excelへ文字列渡し

DSS ProgrammingTipsCGI Ver1.02