質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

3388閲覧

C#からExcel操作 Excelを閉じる際にVBAプロジェクトパスワード確認画面が表示されてしまう

YujiAkita

総合スコア7

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2016/11/17 09:46

###前提・実現したいこと
(実現したいこと)
C#のプログラム(フォーム)から、起動中のExcelにDBより取得した値を転記する。

エラーメッセージ

転記処理自体はは上手くいくのですが、転記後にエクセルを閉じる際に、
VBAプロジェクトパスワードを確認する画面が、5回表示されてしまいます。
このパスワード確認画面を表示しないようにしたいのです。
パスワード未入力で5回Okを押すと、閉じることができます。

###試したこと
オブジェクトが開放されていないのかと思い、オブジェクトの開放について調査しましたが、
ちゃんと開放されているようで、行き詰ってしまっています。

###該当のソースコード
(環境)
Windows7Professional
C# VisualStudio2012
.NetFramework4.0
Oracle 11g
Excel2010
Excelへのアクセスは、Interopを使用。

(Excelの制限)
Excelは他システムベンダーが開発したもので、シート保護されている。
許可された項目以外は入力できない。
もちろんVBAも修正できない。

(実行したコード)
private static bool CheckTransExport( DataTable transData, ref bool warnFlg, ref List<string> warnList, ref int regCount ) {

Excel.Application xlApp = null; Excel.Workbook xlBook = null; Excel.Worksheet xlSheet = null; try { // Excel読み込み ExcelUtilsForTrans.GetOpenedExcelApplication( out xlApp, out xlBook, DOWNLOAD_BOOK ); xlApp.ScreenUpdating = false; //画面再描画を停止 xlApp.Calculation = Excel.XlCalculation.xlCalculationManual; //数式再計算を停止 xlApp.Visible = false; //Excelを非表示 // 作業シート読み込み xlSheet = (Excel.Worksheet)( xlBook.Sheets[SHEET_EXPORT] ); // 最終行取得 Excel.Range lastcell; lastcell = xlSheet.UsedRange; int maxRow = lastcell.Rows.Count - 1; // Excelシートの型式コード、ディストリコード列をDataTableへセット DataTable tblSheet = ExcelUtilsForTrans.GetValueTable( DOWNLOAD_BOOK, SHEET_EXPORT, (int)DataStartRow.ExportSheet, (int)ColIndexForExport.ColProductSumFlgHid, maxRow, (int)ColIndexForExport.ColProductDistributerCdHid ); string productModelCd = string.Empty; string productModelNm = string.Empty; string countryCd = string.Empty; string distributerCd = string.Empty; string productSumRowFlg = string.Empty; string distributerSumRowFlg = string.Empty; int colIdx = 0; // 列番号 int rowIdx = 0; // 行番号 int arraycolIdx = 0; // 転記先配列_列番号 // データクリア foreach ( DataRow Row in tblSheet.Rows ) { rowIdx++; productModelCd = StringUtils.ToString( Row[CLM_NAME_EXPORT_PRODUCT_MODEL_CD] ); distributerCd = StringUtils.ToString( Row[CLM_NAME_EXPORT_DISTRIBUTER_CD] ); productSumRowFlg = StringUtils.ToString( Row[CLM_NAME_EXPORT_PRODUCT_SUM_FLG] ); distributerSumRowFlg = StringUtils.ToString( Row[CLM_NAME_EXPORT_DISTRIBUTER_SUM_FLG] ); if ( "1" != productSumRowFlg && "1" != distributerSumRowFlg ) { // 合計行以外 for ( colIdx = 0; colIdx <= ITEM_COUNT_EXPORT - 1; colIdx++ ) { arraycolIdx = NumericUtils.ToInt( transInfoArrayForExport[colIdx][(int)TransInfoIndex.ColIdx] ); xlSheet.Cells[rowIdx + DataStartRow.ExportSheet, arraycolIdx] = ""; } } } // データチェック // 対象データのループ処理 foreach ( DataRow Row in transData.Rows ) { if ( StringUtils.ToString( Row[Constants.CLM_NAME_PRODUCT_YM] ) == StringUtils.ToString( Row[Constants.CLM_NAME_PLAN_YM] ) ) { colIdx = 0; rowIdx = 0; productModelCd = StringUtils.ToString( Row[Constants.CLM_NAME_PRODUCT_MODEL_CD] ); countryCd = StringUtils.ToString( Row[Constants.CLM_NAME_COUNTRY_CD] ); distributerCd = StringUtils.ToString( Row[Constants.CLM_NAME_DISTRIBUTER_CD] ); // ディストリコードの3桁と国コードが一致する行を検索 rowIdx = GetExcelRowIdxModelCdCountryCd( tblSheet, (int)DataStartRow.ExportSheet, productModelCd, countryCd, CLM_NAME_EXPORT_PRODUCT_MODEL_CD, CLM_NAME_EXPORT_DISTRIBUTER_CD ); if ( -1 == rowIdx ) { // 該当行なし // 警告リスト追加 // 警告メッセージ 65040:K-SCMオンラインExcelに存在しません。(値 型式コード:{0}、型式名:{1}、ディストリコード:{2}) MsgDef msgDef = MsgManager.MESSAGE_WRN_65040; productModelNm = StringUtils.ToString( Row[Constants.CLM_NAME_PRODUCT_MODEL_NM] ); ExcelUtils.SetErrorListForExcelTrans( ref warnList, ref warnFlg, ref warnFlg, new Msg( msgDef, productModelCd, productModelNm, distributerCd ) ); continue; } } if ( 0 < rowIdx ) { // 該当行が存在する場合、貼付け xlSheet.Cells[rowIdx, NumericUtils.ToInt( transInfoArrayForExport[colIdx][(int)TransInfoIndex.ColIdx] )] = Row[Constants.CLM_NAME_QUANTITY]; regCount++; } colIdx++; } return true; } catch ( Exception ex ) { logger.Exception( ex ); return false; } finally { xlApp.ScreenUpdating = true; // 画面再描画を再開 xlApp.Calculation = Excel.XlCalculation.xlCalculationAutomatic; // 数式再計算を再開 xlApp.Visible = true; // Excelを表示 // Excelリソース解放 ExcelUtilsForTrans.ReleaseExcelComObject( xlSheet ); ExcelUtilsForTrans.ReleaseExcelComObject( xlBook ); ExcelUtilsForTrans.ReleaseExcelComObject( xlApp ); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2016/11/17 11:45

コード量も多いですしタグを使ってインデントつきのコードにすべきと思います。
YujiAkita

2016/11/18 01:45

見づらくて申し訳ございません!無事解決しましたので次回はインデント付きで投稿させていただきます!
guest

回答1

0

ベストアンサー

ちゃんと開放されているようで、行き詰ってしまっています。

lastcellがリリース漏れに見えますがこれはリリースしなくてもよいオブジェクトなのでしょうか・・・

C#でのCOM操作をしたことがないので推測ですが、およそCOMオブジェクトの操作により得られた所謂オブジェクト(Application, Workbooks, Workbook, Worksheet, Range, Cell, etc.)は全てCOMオブジェクトになると思うので、そうしたものは残らずリリースしないとリリース漏れ問題になると思います。

リリース漏れ問題が本件の原因かどうか自分にはわかりませんが、いずれにせよCOMを扱うアプリケーションではまずリリース漏れ問題を撲滅する必要があると思います。

なお質問のタグにC++,COM,Excelを付けた方が詳しい方のコメントがつく可能性が高くなる気がします。

投稿2016/11/17 12:26

KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YujiAkita

2016/11/18 01:44

解決しました! すみません、ソースをきちんと追っていくと ROTから取得するロジックで、 解放漏れになってしまう箇所があったみたいです。 お手数お掛けして申し訳ありません。 いろいろ調べて頂いてありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問