【C#×エクセル】一度だけマクロを実行してマクロを消す【VBA】

C#

本日は、C#で書くと汚くなるからエクセル側のマクロでやりたいけど、マクロのコード部分は見られたくない!
xlsmとかの形式にもしたくないし一回キックされたら後は消滅して欲しい… そんな時の解決策

スポンサーリンク

マクロで自分自身を削除する(上書く)

 

今回はC#で作成したデータセットを、既存のエクセル(関数もりもりの頭紙シートが一つだけ)にぶち込みます。
頭紙には GET.WORKBOOKでシート名を取得し、そのシートの金額の合計値を出す関数を仕込んでます、が、この関数はシートが存在する状態で再読み込みしないと上手く働かないのでそこも注意して進めます。
既存のエクセル拡張子はxlsm。ここ重要。xlsじゃダメ。

まずはエクセルマクロ側下準備

 

Option Explicit
Private Sub Worksheet_Activate()

  ' 画面描画停止
  Application.ScreenUpdating = False
  ' 強制再計算
  Application.CalculateFull
    
  Dim Cnt As Integer
  For Cnt = 1 To 10
    ' A列が数値でB列が空白の場合行非表示
    If IsNumeric(Cells(Cnt, 1).Value) = True And Cells(Cnt, 2) = "" Then Rows(Cnt).Hidden = True
  Next Cnt

  ' 画面描画実行
  Application.ScreenUpdating = True

End Sub

今回は1行目から10行目までのシートを、A列が空白なら非表示にする処理にしてみた。大事なのは下記の2つ。

Worksheet_Activate()

つまりこの頭紙シートがアクティブになった時にキックされるマクロとなる。今回の契機はこれでいく

Application.CalculateFull

これで強制的に再計算をさせ、 GET.WORKBOOKを有効にさせる。

C#側実装

 

エクセルにレコードセットぶち込むのは以前データテーブルぶち込む記事書いたのでこちらを参照ください。

配列→エクセル入力処理

        /////////////////////////////////////////////////////////
        //  概要:配列→エクセル入力処理                   
        //  はまみ:2019/06/22                                 
        /////////////////////////////////////////////////////////
        public void SetDataList(int SheetIndex, int nRow, int nColumn, string[,] strDataList
        {
            Boolean bRet = true;

            Excel.Worksheet ObjSheet = (Excel.Worksheet)ObjWorkBook.Sheets[SheetIndex];

            // 二次元配列のデータをExcelに貼り付ける
            Excel.Range Rng = (Excel.Range)ObjSheet.Cells[StartRow, StartColumn];
            Rng = Rng.get_Resize(strDataList.GetLength(0), strDataList.GetLength(1));
            Rng.Value = strDataList;

       // シートをアクティブにする。
            ObjWorkSheets[SheetIndex].Select();

       return;
         }

この関数で頭紙へ追加したい値を張り付け、ObjWorkSheets[SheetIndex].Select()でアクティブにして、
マクロのアクティベートをキックしてます。見栄え的にも開いたときに頭紙になるしいい感じ。

名前を付けて保存処理

        /////////////////////////////////////////////////////////
        //  概要:名前を付けて保存処理                  
        //  はまみ:2019/06/22                                 
        /////////////////////////////////////////////////////////
        public void SaveReName(string strFileName)
        {
            // アラートを止める
            ObjExcel.DisplayAlerts = false;
            // Excelファイルを保存する    
            ObjWorkBook.SaveAs(strFileName,Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook);
     }

ここが一番キモの処理。 SaveAs メソッド のパラメータにファイル名とファイル形式を指定してやります

filename
保存するファイルの名前。 フル パスを含めることができます。含めない場合、ファイルは現在のフォルダーに保存されます。
fileFormat
ファイルを保存するときに使用されるファイル形式を指定する XlFileFormat のいずれかの値。 既存のファイルでは、最後に指定されたファイル形式が既定のファイル形式になります。新しいファイルでは、使用している Excel のバージョンの形式が既定のファイル形式になります。

Microsoft.com

今回用意しているエクセルはxlsmです。まずそれの拡張子をxlsxに変更した文字列をstrFileNameに渡しています。

ただそれだけだと開いた時エラーになるので、 fileFormatパラメータにxlOpenXMLWorkbookを指定してやる、そうすることによりxlsx形式でリネームされて保存されるのでマクロが綺麗さっぱり消滅してくれます。

あと ObjExcel.DisplayAlerts = false; でアラート止めないと保存続行確認のダイアログ出ちゃうので必須。

ちなみにxls形式からの変換でも保存は出来ますが GET.WORKBOOK が上手く動作してくれないので、
実行時は必ずxlsm形式で行いましょう!!


コメント