MFCでExcelを読み込みたい – プログラミング – Home

MFCでExcelを読み込みたい
 
通知
すべてクリア

MFCでExcelを読み込みたい


ひまわり
 ひまわり
(@ひまわり)
ゲスト
結合: 22年前
投稿: 7
Topic starter  

環境:MFC、Office2007、VS2012

MFCでExcelファイルを読み込むソフトを作成しています。
「A1」と指定したセルを読み込む事は出来たのですが、
列/行の終端を読み込む方法が分かりません。

ファイルの全ての内容を読み込みたいのですが
1セルずつ読み込んでいては時間がかかりそうですし、
ぱっと終端を判別する方法は無いでしょうか?

ググってもMFCでExcelの読み書きのサイトは少なく、
基本的な事しか書かれておらず参考になりません。
良い解説サイトなどもご存知でしたら教えてください。


引用解決済
トピックタグ
AR2
 AR2
(@ar2)
Estimable Member
結合: 5年前
投稿: 110
 

 1行まとめて取得とか、方法があるなら私も知りたいです。

 ですが、例えばCListCtrlとかのテキストも1カラムごとに情報を取り出しますが、そ
れと同じだと思います。
 通常のCOMインターフェイスを使うと1セルずつ読み出す以外の方法はなかったと思い
ます。

 終端の判別も空欄がX個続く場所が見つかったら終端とみなす・・・といった判別をし
てますね。


返信引用
Bull
 Bull
(@Bull)
ゲスト
結合: 15年前
投稿: 5
 

MFCでの方法はよくわからないのですが、タイプライブラリを使う方法でよくやっています。
COMでn×mの配列をSafeArrayを使って、書き込んだり読み込んだり出来ます。

大雑把に書くとこんな感じ

//アクティブ・シートを取得
_WorksheetPtr pSheet = pXL->ActiveSheet;

variant_t arr;
arr.vt = VT_ARRAY | VT_VARIANT;
{
SAFEARRAYBOUND sab[2];
sab[0].lLbound = 1; sab[0].cElements = 15;
sab[1].lLbound = 1; sab[1].cElements = 15;
arr.parray = SafeArrayCreate(VT_VARIANT, 2, sab);
}

//データを格納
for (int i = 1; i < 15; i++){
for(int j = 1; j < 15; j++){
variant_t tmp;
tmp = (long)(i + j);
// Add to safearray...
long indices[] = { i, j };
SafeArrayPutElement(arr.parray, indices, (void *)&tmp);
}
}

//配列をExcelへ出力
pSheet->Range[A1][O15]->Value2 = arr;

少し前まで、非常に詳細に解説しているサイトがあって、
よく参考にさせてもらっていたのですが、最近見てみると
残念ですがなくなったしまったようです。


返信引用
ひまわり
 ひまわり
(@ひまわり)
ゲスト
結合: 22年前
投稿: 7
Topic starter  

自分で少し調べてみたところ、
CRangeのSpecialCellsメソッドを使えば良さそう・・・
というところまでは分かりました。

が、セットする値が何を指定すれば良いのかがわかりません。
MSDNにもCRangeのクラス説明が無いですし、解説サイトも見つけられずお手上げです。

>Bullさん
ありがとうございます。
提示していただいた内容はExcelに書き込む内容ですよね?
Excelの内容を読み込み、かつシートのセルの終端が知りたいのです。

自分も、その解説サイトのアドレスは見つけられたのですが
ページが無くなってますね。残念(T_T


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 22年前
投稿: 320
 

ExcelをCOMとして扱っているとすると,Worksheetの使用しているセルの範囲は,Worksheetオブ
ジェクトのUsedRangeプロパティを使うことで取得できます。
https://msdn.microsoft.com/ja-jp/library/office/ff840732.aspx

OOXMLのSpreadsheetMLを直接読み書きしているならば,
・dimension要素のref属性に範囲が書かれています
・そもそも,使用されているセルにしかc要素が存在しません
という2点が使えるかと思います。


返信引用
Bull
 Bull
(@Bull)
ゲスト
結合: 15年前
投稿: 5
 

>Excelの内容を読み込み、かつシートのセルの終端が知りたいのです。

MFCは使用していませんが、こんな感じでできます。
#include <iostream>
#include <iomanip>
#include <string>
#include <comutil.h>

#pragma warning (disable:4192)
//Excelを操作するためのタイプライブラリを読みこむ(Excel2013用)
#import C:\Program Files\Microsoft Office
15\root\vfs\ProgramFilesCommonX86\Microsoft Shared\OFFICE15\MSO.DLL no_auto_exclude
auto_rename
#import C:\Program Files\Microsoft Office
15\root\vfs\ProgramFilesCommonX86\Microsoft Shared\VBA\VBA6\Vbe6ext.olb
#import C:\Program Files\Microsoft Office 15\root\office15\EXCEL.EXE
no_auto_exclude auto_search auto_rename dual_interfaces
using namespace Excel; //名前空間の定義

struct StartOle {
StartOle() { CoInitialize(NULL); }
~StartOle() { CoUninitialize(); }
} _inst_StartOle;

void dump_com_error(_com_error &e)
{
std::cerr << Oops - hit an error!\n;
std::cerr << \tCode = << std::setw(8) << std::hex << e.Error() << '\n';
std::cerr << \tCode meaning = << e.ErrorMessage() << '\n';
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
std::cerr << \tSource = << (LPCTSTR) bstrSource << '\n';
std::cerr << \tDescription = << (LPCTSTR) bstrDescription << '\n';
}

int main(int argc, char* argv[])
{
_ApplicationPtr pXL;

//Excelの起動
if (SUCCEEDED(pXL.CreateInstance(LExcel.Application))) {

try {
pXL->Visible[0] = VARIANT_TRUE;

//ワークブックを開く
WorkbooksPtr pBooks = pXL->Workbooks;
_WorkbookPtr pBook = pBooks->Open(bstr_t(Book1.xlsx));

//アクティブ・シートを取得
_WorksheetPtr pSheet = pXL->ActiveSheet;

RangePtr pCells = pSheet->UsedRange;
pCells->Select(); //セル範囲を選択

//セル範囲のデータを取得
variant_t data = pCells->Value2;
long index[2];
long lNumRows;
long lNumCols;

SafeArrayGetUBound(data.parray, 1, &lNumRows);
SafeArrayGetUBound(data.parray, 2, &lNumCols);

for (int r = 1; r <= lNumRows; r++) {
index[0] = r;
for (int c = 1; c <= lNumCols; c++) {
index[1] = c;
variant_t val;
SafeArrayGetElement(data.parray, index,
&val);

switch(val.vt)
{
case VT_R8:
{
std::cout << std::setw(5) <<
val.dblVal;
break;
}
case VT_BSTR:
{
std::wcout << val.bstrVal <<
L ;
break;
}

case VT_EMPTY:
{
std::cout << ' ';
break;
}
}
}
std::cout << \n;
}

::Sleep(2 * 1000);
pXL->WindowState[0] = xlMinimized;
std::cout << 動作確認のために一時停止:;
std::string buff;
std::getline(std::cin, buff);

pBook->Saved[0] = VARIANT_TRUE;
pBook->Close();
pBook.Release();

pBooks.Release();
}
catch (_com_error &e) {
dump_com_error(e);
return 1;
}

pXL->Quit();
pXL.Release();
}
}


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました