1. ホーム
  2. VBA

名前の秘密:Excelの隠された名前空間

2022-03-16 23:15:58

Excelの隠し名前空間について



この隠された名前空間は、アドインDLL("XLLS")が一時的に名前を保存できる、現在のExcelインスタンスに属するメモリの領域です。この領域を使用することにより、XLLは使用可能なマクロ・ワークシートがない場合でも、名前を定義することができます。



隠し名操作はXLM関数SET.NAME、GET.NAME、EVALUATEに基づいており、SET.NAMEはXLMマクロ・ワークシートで使用すると標準ワークシートレベルの名前を定義し、XLLで呼ばれるとアプリケーションレベルの名前を作成し隠し領域に格納する。



隠し領域に定義された名前は、標準のワークブック名とは大きく異なる特別な機能を持っています。これらの機能については、後で説明します。



隠し名に関連して利用可能なC APIコマンドは以下の通りです。



Excel4(xlfSetName,&xResult,2,&xName,&xValue)を実行します。 xValueを含む名前xlNameを定義する。



Excel4(xlfGetName,&xResult,1,&xName)を実行します。 xlNameの定義(例:"=1")を取得し、xResultに格納する。



Excel4(xlfEvaluate,&xResult,1,&xName)を実行します。 xlNameの内容(例:1)を取得し、xResultに格納する。



Excel4(xlfSetName,&xResult,1,&xName)を実行します。 の場合、xNameを削除します(2番目のパラメータは無視します)。



VBAで隠された名前空間にアクセスする



(1) 非表示の名前を作成する



次のステートメントは、文字列 "OK" を含む Test という隠し名前を作成します。



Application.ExecuteExcel4Macro "SET.NAME(""Test"",""OK")".NAME("""""""""""&quo);



(2) hidden名で表されるコンテンツの取得



Testという名前で表されるコンテンツを取得するには、次のコードを使用します。



TestVal = Application.ExecuteExcel4Macro("Test")



ExecuteExcel4Macro の引数として使用されるのは、名前そのものだけであることに注意してください。



(3) 非表示の名前を削除する



Testという名前を削除するには、次のような文を使用します。



Application.ExecuteExcel4Macro "SET.NAME(""Test"")"



SET.NAMEの第2パラメータは無視されることに注意してください。



隠し名前空間の特徴



隠し名前空間で定義された名前の主な特徴は、どのワークブックにも属さず、アプリケーション自体に属するということであり、これは次のことを意味します。



(1) Excelのどこからでも直接アクセスできる名前である。そのような名前が作成されたワークブックに関係なく、どのワークブックのどのVBAモジュール、ワークシート、マクロワークシート(およびDLLアドイン)でも直接読み取り、変更することができます。



(2) 現在のExcelセッションと同じ時間、生きている。



ワークブックWbk1.xlsのVBAモジュールの1つで名前を作成した後、ワークブックを閉じても、その名前は隠された名前空間に保存されています。その後、別のワークブックWbk2.xlsを開くと、このワークブックのVBAプロセスは、Wbk1.xlsで作成されたばかりの名前を取得し、変更することができます。隠された名前空間で定義された名前は、VBAアドインによって制限されることなく、永久的なquot;public変数"としてアクセスすることができます。



アプリケーションに属するこれらの隠し名については、すべてのワークブックとアドインを閉じても破棄されません。NAME(第2引数なし)またはExcelを終了して再起動することによっても破壊されます。この場合、これらの名前は一種のExcel環境変数として使用することができます。



(3) 完全に隠されている。



保護されたアドインがこの隠し名前空間を使用すると、新しい名前は他のVBAモジュールからは読み取れず、名前空間の身元証明書を知らない限りユーザーからも読み取ることができません。また、名前空間の身元証明書を知らない限り、ユーザーは読み取ることができません。また、隠し名前空間で定義された名前をリストアップする方法もありません。



これらの名前は、標準的な隠し名(つまり、.VisibleプロパティがFalseに設定されているワークブックまたはワークシート名)と混同しないように注意してください。標準的なワークブックレベルの名前は、以下のコードに示すように、Application.Namesコレクションを使用する任意のVBAプロシージャによって取得および変更することができるため、決して真に隠された名前ではありません。

Dim CName As Name
  For Each CName In Workbooks("Wbks1.xls").Names
    If CName.Hidden Then
        MsgBox CName.Name & " deleted"
        CName.Delete
    Delete
  Next CName





上記のコードでは、ワークブックWbks1.xlsのすべての隠し名前をループして削除していますが、これらのコードでは隠し名前空間に格納されている名前を検出できません。なぜなら、それらはApplication.Namesコレクションの一部ではないため、悪意のあるアクセスや変更から保護されています。







次のコードは、保護されたVBAアドインで隠された名前空間を使用する可能性を示しています。



これは、ユーザーが同じExcelセッションでアドインのメインプロシージャを3回以上実行することを制限するものです。許可された残りの実行回数のカウンターは、モジュールレベルの変数や依存アドイン名ではなく、隠し名前空間に格納されます。従来の方法の以下の欠点を除外することで、隠し名前空間はユーザーが保護を中止することができないようにします。



(1) 他の変数と同様に、VBAに格納されたカウンター変数もVBEで手動でクリアすることが可能です。



(2) 同じように、アドインのNamesコレクションをループすることで、任意の外部プロシージャがアドイン内のすべての隠しまたは非表示のワークブック名を読み取り、変更し、場合によっては削除することができます。



しかし、hidden 名前空間は、これらの危険を回避することができます。また、環境文字列ベースのインスタンス、一時ファイル、レジスタ・エントリなどの方法を使用するよりも簡単で、隠し名前空間は永久的なので、ユーザーはこのカウンターをリセットしなくてもワークブックを閉じたり開いたりすることができるようになります。



このコードでは、関数 SetHName、GetHName、DelHName は、長い Application.ExecuteExcel4Macro メソッドを直接使用しなくても、隠し名前を作成、取得、削除することができます。



コード一覧は以下の通りです。

Sub Main()
  Application.EnableCancelKey = xlDisabled
  Dim Count
  Count = GetHName("TswbkCount")
  If IsError(Count) Then
    SetHName "TswbkCount", 3
  ElseIf Count = 1 Then
    MsgBox "Macro disabled. you must restart Excel.", vbInformation
  Else
    SetHName "TswbkCount", Count - 1
  End If
End Sub
Sub SetHName(Name As String, Value)
  Application.ExecuteExcel4Macro _
    "SET.NAME(""" & Name & " " " "," & Value & ")"
End Sub
Function GetHName(Name As String)
  GetHName = Application.ExecuteExcel4Macro(Name)
End Function
Sub DelHName(Name As String)
  Application.ExecuteExcel4Macro "SET.NAME(""" & Name & """")"
End Sub