C/C++でやっています。
( 再投稿になります。 )
基本的にはMinGWで組んでいるのですが、C/C++からExcel操作ができたらいいなと思い、
VC++で Excel操作をするクラスオブジェクトを組んでいます。
ほとんどサイトからの拝借ですが、エクセルの最大行数の取得ができません。
Excel VBA だと
Dim MaxRow As Long Dim MaxCol As Long ' 1番目のシートで使われているセルの最大行数 MaxRow = ThisWorkBook.Sheets(1).Cells(Rows.Count, 1).End(xlUp).Row ' 1番目のシートで使われているセルの最大列数 MaxCol = ThisWorkBook.Worksheets(nSheet).cells(1, Columns.Count).End(xlToLeft).Column
でできるアレです。
「Excelで使える最大行数・最大列数」
ではなく、
「現在なんらかの値が入っている (= 使われている ) 最大行数・最大列数」
です。
ソースコード自体は 「【技術部】[C++] C++でのExcel操作まとめ - UMYA.net」というページから拝借して
Excel::_ApplicationPtr等のようなオブジェクトは クラスのメンバ変数 として保持し、クラスにまとめました。
インターフェース IExcel クラスを定義し、これを継承して CExcel クラス を生成。
動的リンクにしたいので このままでは使用不可能なので COMのようにして
IExcel* CreateExcelInstance( void );
という関数で IExcel型として生成して、
bool WriteExcel( IExcel* pExcel, long nSheet, long nRow, long nCol, const char *data );
のような関数にオブジェクトを渡して間接的に操作する方法にしています。
C++
1/* 定義だけです。実装は上記サイト等から 2 拝借したものです。 3 なので、定義のみとします。 4 イメージとして。 */ 5 6// 必要なヘッダファイルはすでにインクルード済みとします。 7 8// 必要なタイプライブラリ? も すでにインポート済みとします。 9 10 11// Interface 12class IExcel 13{ 14 public: 15 virtual ~IExcel(){} 16 17 virtual bool Open( const char *ExcelFilePath ) = 0; 18 virtual bool Write( long nSheet, long nRow, long nCol, const char *data ) = 0; 19 virtual bool Read( long nSheet, long nRow, long nCol, char *result ) = 0; 20 virtual long CountRow( long nSheet, long nCol ) = 0; 21 virtual bool Save( void ) = 0; 22 virtual bool Kill( void ) = 0; 23}; 24 25 26 27// 実装クラス 28class CExcel : public IExcel 29{ 30 private: 31 bool bVisible; 32 private: 33 bool bRunning; 34 private: 35 Excel::_ApplicationPtr Excel; 36 Excel::WorkbooksPtr WorkBooks; // エクセル本体用 37 Excel::_WorkbookPtr WorkBook; // エクセルブック用 38 protected: 39 void WcharToCString( WCHAR *wstr, char *str ); 40 void ToStrCell( long nRow, long nCol, char *result ); 41 public: 42 CExcel( bool bVisible ); 43 ~CExcel(); 44 45 bool Run( void ); 46 bool Open( const char *ExcelFilePath ); 47 bool Write( long nSheet, long nRow, long nCol, const char *data ); 48 bool Read( long nSheet, long nRow, long nCol, char *result ); 49 long CountRow( long nSheet, long nCol ); 50 bool Save( void ); 51 bool Kill( void ); 52}; 53 54 55// 実行ファイルから使えるようにする関数群。 56// これらを使用して間接的に操作する。 57 58FUNCTION_DEFINITION 59IExcel* CreateExcelInstance( bool bVisible ){ 60 try{ 61 return new CExcel( bVisible ); 62 }catch( int e ){ 63 return NULL; 64 } 65} 66 67FUNCTION_DEFINITION 68void DestroyExcelInstance( IExcel* pExcel ){ 69 delete pExcel; 70} 71 72FUNCTION_DEFINITION 73bool OpenExcelFile( IExcel* pExcel, const char *ExcelFilePath ){ 74 return pExcel->Open( ExcelFilePath ); 75} 76 77FUNCTION_DEFINITION 78bool KillExcel( IExcel* pExcel ){ 79 return pExcel->Kill(); 80} 81 82FUNCTION_DEFINITION 83bool WriteExcel( IExcel* pExcel, long nSheet, long nRow, long nCol, const char *data ){ 84 return pExcel->Write( nSheet, nRow, nCol, data ); 85} 86 87FUNCTION_DEFINITION 88bool ReadExcel( IExcel* pExcel, long nSheet, long nRow, long nCol, char *result ){ 89 return pExcel->Read( nSheet, nRow, nCol, result ); 90} 91 92 93FUNCTION_DEFINITION 94bool SaveExcelFile( IExcel* pExcel ){ 95 return pExcel->Save(); 96} 97
のようにしています。
たとえば、
シート1 をデータベースのように ( 疑似データベース ) して
"A11" セルから開始するとします。
( A1~ A10 ぐらいまでは タイトルや 情報等を載せるとして。 )
名前 - ふりがな - 年齢 - 住所 - 電話番号 - ... - 備考
のようにあって、
データベースのようにするので、追加されたりするので最大行数はすぐにはわからないとします。
この場合、このC/C++の実行ファイルから追加・削除等をするとするならいいですが、
Excelに直接入れるときもあるとします。
その場合、最大行数がわからないので 追加できません。
大阪太郎 - おおさかたろう - 20歳 - 大阪府(略) - ...
東京二郎 - とうきょうじろう - 21歳 - 東京都(略) - ...
京都三郎 - きょうとさぶろう - 22歳 - 京都府(略) - ...
と三件あったら、
A11 から開始しているとしているので、
大阪太郎 = A11, 東京二郎 = A12, 京都三郎 = A13
となり、
最大行数: 13
と返ってくるようにしたいのです。
( できれば最大列数も。 )
以前質問したときの回答では
C++
1// 先ほどあったクラス CExcel のメンバ関数とする 2long CExcel::CountRow( long nSheet, long nCol ){ 3 long row = -1; 4 5 //ワークシート内で使用されているセル範囲を取得 6 Excel::RangePtr pRange = Work_sheet->UsedRange; 7 8 //セル範囲の行数を取得 9 row = pRange->Count; // 方法1 10 11 //セル範囲の列数を取得 12 // row = pRange->Count; 13 14 row = pRange->End[Excel::xlDown]->Row; // 方法2 15return row; 16} 17
のようなやり方を教えていただきました。
しかし、自宅に帰ってやってみると
方法1 でやると戻り値が 234
方法2 をコメントアウトし、方法1 で試すと 戻り値が long max = 234
方法1 をコメントアウトし、方法2 でやると 戻り値 が long max = 11
となってしまいます。
方法2が近いと思うのですが、A11から開始し A13 までは埋まっているので 13 が返ってくるのを期待していたのですが...
期待している戻り値: 13
for文で開始行から 適当に最大値 3000 までの行を Readメンバ関数 ( CExcel::Read ) で 読み取り、
読み取れなかった場合、break でループを抜けて戻り値として返す。
というやり方を思いついたのでやってみたところ、方法1 と同じになってしまいました。
どうすれば最大行数を取得できるのでしょうか?
[環境等]
言語 : C/C++
コンパイラ : VC++2010 Express ( DLL側 ), MinGW ( 実行ファイル側 )
Excelバージョン: Excel 2007
知りたいこと : C/C++から Excel操作するときに 指定シートの ( なんらかのデータが書き込まれている ) セルの「最大行数」と「最大列数」の求め方
宜しくお願い致します。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/01/10 08:27
2017/01/20 04:16
2017/01/20 09:54