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);
}
参照