メインページ | ファイル一覧 | ファイルメンバ

nExpCsv.cpp

説明を見る。
00001 00010 #include "stdafx.h" 00011 #include "nExpCsv.h" 00012 #include "ExportPropertySheet.h" 00013 #include "ProgDlg.h" 00014 00015 #ifdef _DEBUG 00016 #define new DEBUG_NEW 00017 #undef THIS_FILE 00018 static char THIS_FILE[] = __FILE__; 00019 #endif 00020 00021 #define INI_OUT_DOC _T("OutputDocument") 00022 #define INI_OUT_COL _T("OutputColumn") 00023 #define INI_HEADER _T("OutputHeader") 00024 #define INI_FORMAT _T("ColumnFormat") 00025 #define INI_LIST_SPLIT _T("ListSeparater") 00026 #define INI_MODE _T("CSVFormatMode") 00027 #define INI_SPLIT _T("ColumnSeparater") 00028 #define INI_QUOTE _T("ColumnQuote") 00029 #define INI_ALT_SPLIT _T("AltSeparater") 00030 #define INI_ALT_CRLF _T("AltCrlf") 00031 00032 // 00033 // メモ! 00034 // 00035 // この DLL が MFC DLL に対して動的にリンクされる場合、 00036 // MFC 内で呼び出されるこの DLL からエクスポートされた 00037 // どの関数も関数の最初に追加される AFX_MANAGE_STATE 00038 // マクロを含んでいなければなりません。 00039 // 00040 // 例: 00041 // 00042 // extern "C" BOOL PASCAL EXPORT ExportedFunction() 00043 // { 00044 // AFX_MANAGE_STATE(AfxGetStaticModuleState()); 00045 // // 通常関数の本体はこの位置にあります 00046 // } 00047 // 00048 // このマクロが各関数に含まれていること、MFC 内の 00049 // どの呼び出しより優先することは非常に重要です。 00050 // これは関数内の最初のステートメントでなければな 00051 // らないことを意味します、コンストラクタが MFC 00052 // DLL 内への呼び出しを行う可能性があるので、オブ 00053 // ジェクト変数の宣言よりも前でなければなりません。 00054 // 00055 // 詳細については MFC テクニカル ノート 33 および 00056 // 58 を参照してください。 00057 // 00058 00060 // CnExpCsvApp 00061 00062 BEGIN_MESSAGE_MAP(CnExpCsvApp, CWinApp) 00063 //{{AFX_MSG_MAP(CnExpCsvApp) 00064 // メモ - ClassWizard はこの位置にマッピング用のマクロを追加または削除します。 00065 // この位置に生成されるコードを編集しないでください。 00066 //}}AFX_MSG_MAP 00067 END_MESSAGE_MAP() 00068 00070 // CnExpCsvApp の構築 00071 00072 CnExpCsvApp::CnExpCsvApp() 00073 { 00074 // TODO: この位置に構築用のコードを追加してください。 00075 // ここに InitInstance の中の重要な初期化処理をすべて記述してください。 00076 } 00077 00079 // 唯一の CnExpCsvApp オブジェクト 00080 00081 CnExpCsvApp theApp; 00082 00083 int CnExpCsvApp::ExitInstance() 00084 { 00085 // TODO: この位置に固有の処理を追加するか、または基本クラスを呼び出してください 00086 WinHelp(0L, HELP_QUIT); 00087 00088 m_Session.Term(); 00089 return CWinApp::ExitInstance(); 00090 } 00091 00092 BOOL CnExpCsvApp::InitInstance() 00093 { 00094 // TODO: この位置に固有の処理を追加するか、または基本クラスを呼び出してください 00095 if (m_Session.Init()) return FALSE; 00096 LNSetThrowAllErrors(TRUE); 00097 00098 return CWinApp::InitInstance(); 00099 } 00100 00101 STATUS CnExpCsvApp::DoExport( 00102 VIEWIXDATA *pViewIxData, 00103 WORD Flags, 00104 HMODULE hModule, 00105 char *AltLibraryName, 00106 char *FileName) 00107 { 00108 LNSTATUS rc = LNNOERROR; 00109 // データベースハンドルからNLDatabaseに変換 00110 DBHANDLE DbHandle = pViewIxData->hNoteFile; 00111 try { 00112 m_Session.GetDatabase(DbHandle, &m_Db); 00113 00114 try { 00115 m_Db.GetViewFolder( pViewIxData->ViewNoteID, &m_View ); 00116 00117 DoExportMain(pViewIxData, Flags, hModule, AltLibraryName, FileName); 00118 00119 // 念のためにビューが開いていたら閉じる 00120 if (m_View.IsOpen()) m_View.Close(); 00121 00122 } catch (LNSTATUS Lnerror) { 00123 rc = Lnerror; 00124 } 00125 00126 } catch (LNSTATUS Lnerror) { 00127 rc = Lnerror; 00128 } catch (...) { 00129 AfxMessageBox(_T("ERROR...")); 00130 } 00131 00132 // エラーメッセージの表示 00133 if (LNIsError(rc)) { 00134 char ErrorBuf[LNERROR_MESSAGE_LENGTH]; 00135 LNGetErrorMessage(rc, ErrorBuf); 00136 AfxMessageBox(ErrorBuf); 00137 } 00138 00139 // データベースハンドルを返還する 00140 try { 00141 DbHandle = m_Db.GetDatabaseHandle(); 00142 } catch (LNSTATUS ) { 00143 } 00144 00145 return NOERROR; 00146 } 00147 00148 LNSTATUS CnExpCsvApp::DoExportMain( 00149 VIEWIXDATA *pViewIxData, 00150 WORD Flags, 00151 HMODULE hModule, 00152 char *AltLibraryName, 00153 char *FileName) 00154 { 00155 LNSTATUS code = LNNOERROR; 00156 00157 //-------------------------------------------------- 00158 // コマンドラインパラメータの規定値 00159 //-------------------------------------------------- 00160 BOOL bDialog = TRUE; // /X 00161 int nOutDoc = 0; // /D0 00162 int nOutCol = 0; // /C0 00163 BOOL bHeader = FALSE; // /H 00164 int nFormat = 0; // /F0 00165 int nListSplit = 0; // /L0 00166 int nMode = 0; // /M0 00167 int nSplit = 0; // /S0 00168 int nQuote = 0; // /Q0 00169 int nAltSplit = 0; // /P0 00170 int nAltCrlf = 0; // /R0 00171 00172 //-------------------------------------------------- 00173 // ファイル名中にある / を \ に置き換える 00174 // ※ファイル名中の最後の / が \ に化ける?ため同一視する 00175 //-------------------------------------------------- 00176 LNString strFileName = (LNCHAR*)FileName; 00177 ReplaceAll(strFileName, _T("/"), _T("\\")); 00178 // AfxMessageBox(strFileName); 00179 00180 //-------------------------------------------------- 00181 // ファイル名とパラメータを" \" で分離する 00182 //-------------------------------------------------- 00183 LNString strParam; 00184 LNINT pos = 0, loc; 00185 if (LNWARN_NOT_FOUND != strFileName.Find(_T(" \\"), pos, &loc) ) { 00186 LNString strTempName(strFileName); 00187 strTempName.GetSubString( loc, strTempName.GetCharacterCount() - loc, &strParam ); // パラメータ 00188 strTempName.GetSubString( 0, loc, &strFileName ); // ファイル名 00189 } 00190 strParam += _T(" \\"); // パラメータの終端記号 00191 // AfxMessageBox(strParam); 00192 00193 //-------------------------------------------------- 00194 // ファイル名にピリオド(.)が無ければ拡張子(.csv)を追加 00195 //-------------------------------------------------- 00196 LNText tokens; 00197 strFileName.Parse( _T("\\"), &tokens); 00198 if (tokens.GetCount() > 0) { 00199 LNString strTempName(tokens[tokens.GetCount()-1]); 00200 if (LNWARN_NOT_FOUND == strTempName.FindChar('.', 0, &loc) ) { 00201 strFileName.Append(_T(".csv")); 00202 } 00203 } 00204 00205 //-------------------------------------------------- 00206 // パラメータをチェックして変数に設定 00207 //-------------------------------------------------- 00208 ReplaceAll(strParam, _T(" "), _T("")); // 空白を除去 00209 for (pos=1; LNWARN_NOT_FOUND != strParam.Find(_T("\\"), pos, &loc ) ; pos=loc+1) { 00210 LNString strTemp; 00211 strParam.GetSubString( pos, loc-pos, &strTemp ); 00212 // AfxMessageBox(strTemp); 00213 00214 char cType; UINT nVal; 00215 int nResult = _stscanf( strTemp, _T("%c%d"), &cType, &nVal ); 00216 if (nResult == 1) { 00217 switch (cType) { 00218 // ダイアログを表示しない 00219 case 'X': bDialog = FALSE; continue; 00220 // ヘッダー行を出力する 00221 case 'H': bHeader = TRUE; continue; 00222 } 00223 } else if (nResult == 2 ) { 00224 switch (cType) { 00225 case 'D': // 書き出し対象の文書 00226 if (nVal < 0 || nVal > 1) break; 00227 nOutDoc = nVal; 00228 continue; 00229 case 'C': // 書き出し対象の列 00230 if (nVal < 0 || nVal > 1) break; 00231 nOutCol = nVal; 00232 continue; 00233 case 'F': // 列の書式化 00234 if (nVal < 0 || nVal > 1) break; 00235 nFormat = nVal; 00236 continue; 00237 case 'L': // 複数値の分離記号 00238 if (nVal < 0 || nVal > 6) break; 00239 nListSplit = nVal; 00240 continue; 00241 case 'M': // CSV形式 00242 if (nVal < 0 || nVal > 2) break; 00243 nMode = nVal; 00244 continue; 00245 case 'S': // 列の分離記号 00246 if (nVal < 0 || nVal > 1) break; 00247 nSplit = nVal; 00248 continue; 00249 case 'Q': // 列の囲み処理 00250 if (nVal < 0 || nVal > 2) break; 00251 nQuote = nVal; 00252 continue; 00253 case 'P': // 代替分離記号 00254 if (nVal < 0 || nVal > 5) break; 00255 nAltSplit = nVal; 00256 continue; 00257 case 'R': // 代替改行記号 00258 if (nVal < 0 || nVal > 2) break; 00259 nAltCrlf = nVal; 00260 continue; 00261 } 00262 } 00263 00264 // パラメータのエラー 00265 CString strFmt; 00266 strFmt.Format("パラメータ(/%s)は正しくありません。", strTemp.GetPlatformTextPtr() ); 00267 AfxMessageBox(strFmt, MB_ICONEXCLAMATION ); 00268 } 00269 00270 00271 //-------------------------------------------------- 00272 // ビューの設計情報を取得する 00273 //-------------------------------------------------- 00274 m_arrData.SetView( m_View ); 00275 00276 //-------------------------------------------------- 00277 // エクスポートダイアログを表示 00278 //-------------------------------------------------- 00279 if (bDialog) { 00280 CExportPropertySheet prop; 00281 if (ID_WIZFINISH != prop.DoModal()) return LNNOERROR; 00282 00283 // ダイアログで選択した情報を変数に設定 00284 nOutDoc = prop.m_Page1.m_nOutDoc; 00285 nOutCol = prop.m_Page1.m_nOutCol; 00286 bHeader = prop.m_Page1.m_bHeader; 00287 nFormat = prop.m_Page1.m_nFormat; 00288 nListSplit = prop.m_Page1.m_nListSplit; 00289 nMode = prop.m_Page1.m_nMode; 00290 nSplit = prop.m_Page1.m_nSplit; 00291 nQuote = prop.m_Page1.m_nQuote; 00292 nAltSplit = prop.m_Page1.m_nAltSplit; 00293 nAltCrlf = prop.m_Page1.m_nAltCrlf; 00294 } 00295 00296 //-------------------------------------------------- 00297 // エクスポートする文書のNOTEIDを取得する 00298 // nOutDoc==0 ... すべての文書のNOTEID 00299 // nOutDoc!=0 ... 選択した文書のNOTEID 00300 //-------------------------------------------------- 00301 CArray<NOTEID, NOTEID&> notes; 00302 GetNoteID(pViewIxData, notes, (nOutDoc==0)); 00303 00304 //-------------------------------------------------- 00305 // 設定値の具体化 00306 //-------------------------------------------------- 00307 00308 // 列の書式化 00309 const LNNotesSession *session = (nFormat == 0) ? &m_Session : NULL; 00310 00311 // 複数値の分離記号 00312 LPCTSTR _szListSplit[] = {NULL, _T(""), _T(" "), _T(","), _T(":"), _T(";"), _T("\n")}; 00313 LPCTSTR szListSplit = _szListSplit[nListSplit]; 00314 00315 // 列の分離記号 00316 LPCTSTR _szSplit[] = {_T(","),_T("\t")}; 00317 LPCTSTR szSplit = _szSplit[nSplit]; 00318 00319 // 列分離記号の置換え記号 00320 LPCTSTR _szAltSplit[] = {NULL, _T(""), _T(" "), _T(":"), _T(";"), _T(",")}; 00321 LPCTSTR szAltSplit = _szAltSplit[nAltSplit]; 00322 00323 // 改行の置換え記号 00324 LPCTSTR _szAltCrlf[] = {NULL, _T(""), _T(" ")}; 00325 LPCTSTR szAltCrlf = _szAltCrlf[nAltCrlf]; 00326 00327 m_arrData.SetOption(session, szListSplit, szSplit, nQuote, szAltSplit, szAltCrlf); 00328 00329 //-------------------------------------------------- 00330 // エクスポートファイルを開く 00331 //-------------------------------------------------- 00332 int nOutputMode = ios::out | ios::binary; 00333 if (Flags & IXFLAG_APPEND) nOutputMode |= ios::app; // 追加モード 00334 ofstream fofs(strFileName, nOutputMode); 00335 if ( !fofs ) { 00336 throw (LNSTATUS)ERR_PROTECTED; 00337 // Cannot write or create file (file or disk is read-only) 00338 } 00339 00340 //-------------------------------------------------- 00341 // 列名を出力する 00342 //-------------------------------------------------- 00343 if (bHeader) { 00344 fofs << (LPCTSTR)m_arrData.ToCSVHeader(); 00345 // fofs << endl; 00346 fofs << "\x0D\x0A"; 00347 fofs.flush(); 00348 } 00349 00350 //-------------------------------------------------- 00351 // 出力文書なし 00352 //-------------------------------------------------- 00353 if (notes.GetSize() == 0) return LNNOERROR; 00354 00355 //-------------------------------------------------- 00356 // 書き出し中ダイアログの表示 00357 //-------------------------------------------------- 00358 CExportingDlg prog; 00359 prog.Create(); 00360 prog.SetStatus(_T("CSVファイルを書き出しています...")); 00361 prog.SetRange(0, notes.GetSize()); 00362 prog.SetPos(0); 00363 00364 m_View.Open(); 00365 //-------------------------------------------------- 00366 // NOTEIDからビュー内の文書を取得するための2つのテーブルを作成する 00367 // NOTEID-->LNVFEntry ... 文書そのもの(高速だがメモリ制限有り) 00368 // NOTEID-->LNVFPosition ... ビュー内の文書位置 00369 //-------------------------------------------------- 00370 BOOL bEntry = TRUE; 00371 CMap<NOTEID, NOTEID&, LNVFEntry, LNVFEntry&> mapIdToEnt; 00372 CMap<NOTEID, NOTEID&, LNVFPosition, LNVFPosition&> mapIdToPos; 00373 { 00374 LNVFEntry entry; 00375 LNSTATUS lns = m_View.GotoFirst(&entry); 00376 while (lns == LNNOERROR) { 00377 NOTEID note = entry.GetNoteID(); 00378 // NOTEIDから文書エントリ:LNVFEntryを取得するためのMap 00379 if (bEntry) mapIdToEnt[note] = entry; 00380 00381 // NOTEIDから文書位置:LNVFPositionを取得するためのMap 00382 LNVFPosition pos; 00383 m_View.GetPosition(&pos); 00384 mapIdToPos[note] = pos; 00385 00386 try { 00387 lns = m_View.GotoNext(&entry); 00388 }catch (LNSTATUS lnerror) { 00389 if (lnerror != ERR_MEM_HANDLES) throw lnerror; 00390 // エントリ:LNVFEntryの開きすぎでメモリ不足の場合 00391 // mapIdToEnt.RemoveAll(); 00392 // いくつかのエントリ:LNVFEntryを開放して、 00393 POSITION pos = mapIdToEnt.GetStartPosition(); 00394 for (int i=0; i<100 && pos ; i++) { 00395 mapIdToEnt.GetNextAssoc(pos, note, entry); 00396 mapIdToEnt.RemoveKey(note); 00397 } 00398 bEntry = FALSE; // これ以降、文書位置:LNVFPositionのみ保存する 00399 } 00400 } 00401 } 00402 00403 // CString strFmt; 00404 // strFmt.Format("Ent=%d / Pos=%d", mapIdToEnt.GetCount(),mapIdToPos.GetCount()); 00405 // AfxMessageBox(strFmt); 00406 //-------------------------------------------------- 00407 // CSVデータの書き出し 00408 //-------------------------------------------------- 00409 int Count = notes.GetSize(); 00410 prog.SetRange(0, Count); 00411 for(int i=0; i<Count; i++) { 00412 prog.SetPos(i); 00413 // NOTEIDから文書エントリを取得 00414 NOTEID note = notes[i]; 00415 LNVFEntry entry = mapIdToEnt[note]; 00416 // 文書エントリテーブルに存在しなかった場合、文書位置から取得 00417 if (entry.IsNull()) m_View.GetEntry( &entry, mapIdToPos[note] ); 00418 // else mapIdToEnt.RemoveKey(note); 00419 00420 // CSV1行の出力 00421 LNNote doc; 00422 try { 00423 GetDatabase().GetNote(note, &doc); 00424 } catch (LNSTATUS) { 00425 // CString strFmt; 00426 // strFmt.Format("文書無し NOTEID=%8.8x", note); 00427 // AfxMessageBox(strFmt); 00428 } 00429 fofs << (LPCTSTR)m_arrData.ToCSVData(entry, doc); 00430 // fofs << endl; 00431 fofs << "\x0D\x0A"; 00432 fofs.flush(); 00433 00434 // Cancelボタンが押された 00435 if (prog.CheckCancelButton()) break; 00436 } 00437 m_View.Close(); 00438 00439 fofs.flush(); 00440 fofs.close(); 00441 00442 return code; 00443 } 00444 00445 // 00446 // すべてまたは選択されている文書IDの取得 00447 // 00448 LNSTATUS CnExpCsvApp::GetNoteID(VIEWIXDATA *pViewIxData, CArray<NOTEID,NOTEID&> &notes, BOOL bAll) 00449 { 00450 HCOLLECTION hCollection = pViewIxData->hViewCollection; 00451 CString strFmt; 00452 HANDLE hSelected = pViewIxData->hSelectedList; // 選択文書のIDTABLE 00453 00454 COLLECTIONPOSITION CollPosition; 00455 HANDLE hBuffer; 00456 DWORD NotesFound; 00457 WORD SignalFlags; 00458 /* コレクション内のどこから読み込み始めるかを制御する */ 00459 /* データ構造 COLLECTIONPOSITION を設定する */ 00460 /* 読み込みの開始位置を指定する */ 00461 CollPosition.Level = 0; 00462 CollPosition.Tumbler[0] = 0; 00463 00464 /* このコレクション内に存在する文書の全文書 ID のバッファを取得する 00465 コレクションが空かどうかを調べるために戻りコードを検査する */ 00466 do { 00467 00468 LNSTATUS error = NIFReadEntries( 00469 hCollection, // このコレクションのハンドル 00470 &CollPosition, // コレクション内の開始位置 00471 NAVIGATE_NEXT, // エントリのスキップ順 00472 1L, // スキップ数 00473 NAVIGATE_NEXT, // スキップ後に使う順番 00474 0xFFFFFFFF, // 戻り数の最大値 00475 READ_MASK_NOTEID, // 必要な情報 00476 // READ_MASK_SUMMARYVALUES, 00477 &hBuffer, // 情報のハンドル(戻り) 00478 NULL, // バッファの長さ(戻り) 00479 NULL, // スキップされたエントリ(戻り) 00480 &NotesFound, // 文書数(戻り) 00481 &SignalFlags); // 共用する警告(戻り) 00482 00483 if (error) return(error); 00484 /* 文書 ID のバッファのロック(位置の固定) 00485 結果のポインタを必要な型にキャストする */ 00486 if (hBuffer != NULLHANDLE) { 00487 NOTEID *IdList = (NOTEID far *)OSLockObject(hBuffer); 00488 // この集まり内の全文書 ID のリストをNotsArrayへ保存する 00489 for (DWORD i=0; i<NotesFound; i++) { 00490 // すべて(bAll)または選択文書(IDTableに存在する) 00491 if (bAll || IDIsPresent(hSelected, IdList[i])) notes.Add(IdList[i]); 00492 } 00493 // 文書 ID のリストのロックを解除する 00494 OSUnlockObject(hBuffer); 00495 // NIFReadEntries で確保されたメモリを解放する 00496 OSMemFree(hBuffer); 00497 } 00498 00499 // シグナルフラグがまだ設定されていればループを繰り返す 00500 } while (SignalFlags & SIGNAL_MORE_TO_DO); 00501 00502 return LNNOERROR; 00503 } 00504 00505 LNDatabase & CnExpCsvApp::GetDatabase() 00506 { 00507 return m_Db; 00508 }

LotusNotes CSV Export Plug-inに対してWed Jun 30 15:53:52 2004に生成されました。 doxygen 1.3.7