Excel VBA > VBA:実務活用 > できるだけファイルをコピーされたくない時の対策について考える
このエントリーをはてなブックマークに追加

できるだけファイルをコピーされたくない時の対策について考える

マクロ付きファイルのコピーを防ぐ方法はあるか

Excelマクロは、基本的には1つのファイル(xlsm)でデータとプログラムのセットで構成することができるため非常に手軽に配布できます。しかし一方で、これらファイルを意図しない方法で広めたくないということがあります。そこで今回は、このような場合に「コピーを防ぐ方法はあるのか」と言う点について考えてみます。
なお、ここでいう「ファイルコピー」とは、意図しない第三者に使われたくないということを指しています。

ファイルコピーを100%防ぐ方法はない!?

いきなり本末転倒なお話です(これは意見が分かれるかもしれません)が、弊社ではマクロ付きファイルのコピーを100%確実に防ぐ方法は実質ないと考えます。
ExcelファイルはWisnows OSに管理されており、VBA等のプログラムが生きるのは、Excel上でそのファイルが開かれた時だけです。
つまり、VBA等のプログラムが「制御できる前の段階で」操作されることに関しては、手の出しようがないということになります。

事前対策は困難

上記理由から、そもそも「マクロ付きファイルのコピーを未然に防ぐ」という意味では、このファイルとは別に監視用などのアプリをセットにする等が必要となり、これはこれで技術的難易度が相当上がると思われます。
(例えばMicrosoftのOfficeインストール時に必要なプロダクトIDのように)コピー防止のセキュリティ的観点からインターネット上のサーバとやり取りさせる場合等において、サーバ側の管理も必要になります(なぜならば、サーバが止まる等が発生するとマクロ付きファイルが動かなくなる可能性もありますので)。
あるいは(利用者が)「スタンドアローンで使いたい」なども考慮する必要もあります。

コピーを躊躇してもらう

インターネット上のダウンロード配布やメールでの添付ファイルでの送付以外に、直接客先にマクロ付きファイルを持って行き、そのPCでしか動かない方法は取れるかもしれません。ただ仮にそのPCの入れ替えなどが発生した場合の手間などを考えると(少なくとも弊社では)対応が困難になります。ただし、こういった方法もコピー自体を防ぐ方法ではありません
そこで、「もはやファイルのコピーは防げない」ということを前提に、「できるだけコピーされない」ようにする方法について考えました。
ちなみに下記に挙げる方法も100%ではございません。

Excelファイルにパスワードを入れる

Excelには「パスワード」を含めることができる機能があります。そこでファイルあるいはシートにパスワードを施します。簡易的な方法ですが、効果もあります。
ただし、この場合は「意図しない第三者」と「本来の提供先」が友人関係である場合などでは、「マクロ付きファイルとパスワードをセット」で意図的に送られてしまうと実質的効果はゼロになってしまいます。
そこでこの機能に更にプラスアルファとして下記機能を加えます。

契約情報を加える

例えば、上記パスワードのほかに下記のシートを加えます。
copy_block_01

ここでの狙いは「心理的な抑制」です。上記は一例ですが、機密性あるいは個人的な情報が含まれるほど一般的な感覚では、「契約情報の内容までを関係ない人には送ったらちょっとまずいな」という気持ちになる効果を狙っています。簡単に言えば、「私的な情報を他者に閲覧されたら困る」内容を加えます。

契約情報シートを死守する

この方法をとった場合に、起こり得る問題ですが、「契約情報のみが削除されてしまう」ことです。この方法を取られると、先ほど申し上げた抑止力がゼロになってしまいます。
そこで、このシートはマクロ付きファイルでは必要不可欠な形にする必要が出てきます。そうです、VBAを使って対処します。

シート死守対策の前提

VBA上で「このシートがないと動かない」と言う形にするのは、それほど難しくなりません。

Private Sub Workbook_Open()

    Dim Wsh As Worksheet
    Dim blnOpen As Boolean

    blnOpen = False
    For Each Wsh In ThisWorkbook.Worksheets

        ‘シート名「契約情報」があればフラグをTrue(有り)にする
        If Wsh.Name = “契約情報” Then
            blnOpen = True
            Exit For
        End If
    Next Wsh

    ‘フラグがFalseなら起動しないでブック終了
    If blnOpen = False Then
        MsgBox “契約情報シートがありませんのでブックを終了します”, vbCritical
        ThisWorkbook.Close False
    End If

End Sub

上記をブックのオープンイベントに書き込めば、起動時に、契約情報シート有無を毎回チェックし、このシートが存在しなければブックを強制的に終了することができます。
つまり、このシートを削除した場合には、ファイル自体が使えないということになります。
ただし、ある程度のスキルのある方だと、これだけでは十分でないことがお分かりかもしれません。そうです、これだけでは回避方法があります。そこで以下2つの対策を施します。

「契約内容の変更を防ぐ」シート死守対策1

抑止力をゼロにするには、契約情報を書き換えてしまう方法が考えられます。
そこで変更ができないようにExcelの一般機能にあるシートのパスワード(保護)を設定します。基本的にはセルのクリックさえできない形にします(Excelバージョンにより保護できる幅が変わってきますので注意が必要です)。
copy_block_02

上記設定後に、セルをクリックするとダイアログが表示(実質何もできない)
copy_block_03

「シートの差し替えを防ぐ」シート死守対策2

より高度な突破口としては、「契約情報シートを削除」した後に、「契約情報シートを新規作成(偽シート)」というパターンも考えられます。
そこでこの対策としては、事前に用意している契約情報シートの一部のセルに文字を埋め込んでおきます。
ここでは、A列の一番下の行に文字を入れています。
copy_block_04
最大ポイントは「プログラムだけが知っている場所(セル)に文字を入れる」ことです(フォントの色も念のため白などにするとベターですね)。
こうすることで、この文字があるかどうかをチェックすることで「本物シートなのか偽シートなのかを判別できる」ようにします。
(言い換えると、偽シートを作った人は、この文字もセルに入力しなければならない)
これを先ほどのオープンイベントのプログラムに追加します。

Private Sub Workbook_Open()

    Dim Wsh As Worksheet
    Dim blnOpen As Boolean

    blnOpen = False
    For Each Wsh In ThisWorkbook.Worksheets

        ‘シート名「契約情報」があるか
        If Wsh.Name = “契約情報” Then

            ‘文字列「本物」があればフラグをTrue(有り)にする
            If Wsh.Cells(1048576, 1).Value = “本物” Then
                blnOpen = True
                Exit For
            End If

        End If
    Next Wsh

    ‘フラグがFalseなら起動しないでブック終了
    If blnOpen = False Then
        MsgBox “契約情報シートがありませんのでブックを終了します”, vbCritical
        ThisWorkbook.Close False
    End If

End Sub

文字列はもっと複雑にすることや、複数のセルに分散して埋め込んでおけば、偽装を防ぐ精度が高まります。
このようにすることで抑止力を維持することができます。
しかしながら繰り返しますが、この方法を使っても家族間など非常に身近な関係であると実質的な効果はありませんし、100%確実に防げることは保証されないので、状況に応じた使い分けなどが実務上では必要になると思われます。

カテゴリ:VBA:実務活用