1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

以前、VBScript.dllが2027年以降に廃止となることから Microsoft VBScript Regular Expressions 5.5を参照した正規表現(RegExp)の代替案を書きました。
【VBA】vba-regexを使用した正規表現(VBScript廃止の代替)

Selenium VBA の discussions 158 の中で、別案として .NET Framework の正規表現クラスを利用した方法を提示してくれた方がいます。

この技術の元になる技術が、vb2clr ライブラリで日本の方が開発しています。

VBA から .NET Frameworkの機能を使用する方法は以前にありましたが、その場合、別途 .NET Framework 3.5のインストールが必要でした。
これは、別の方法を使用しているため、.NET Framework 3.5のインストールは不要となります。

vb2clr の紹介

筆者も以前に記事を読んだことがあったのですが、何か難しいイメージがあってスルーしていたのですが、改めて見直しました。

vb2clrのライセンスは「修正BSDライセンス」(3条項BSDライセンス; BSD-3-Clause)となっています。

使い方

導入方法

  1. https://github.com/jet2jet/vb2clr からモジュールを取得します。
  2. 次にExitHandler.basCLRHost.clsファイルをプロジェクトにドラッグ&ドロップします。

image.png

補足

vb2clrは日本人の方が開発しており、Excel関連ファイルはShift-JISを用いている。
そのため、海外向けとしてUTF-8用に変換されたファイルが用意されている。

  • ExitHandler.utf8.bas
  • CLRHost.utf8.cls

参照設定

ツールの参照設定から次の2つのライブラリを参照します。

  • Common Runtime Language Execution Engine
  • mscorlib.dll

image.png

どちらも Windows 10 以降の環境であれば標準で搭載されているため、Excelマクロファイルの配布に支障はありません。

プログラム

正規表現は、GitHub上に掲載されているので、それ以外のサンプルプログラムを用意しました。
最初は理解できないで途方に暮れていたのですが、ネット検索しまくったところ中国の掲示板にサンプルプログラムが投稿されており突破口が開かれました。

[分享] vba里使用.net类

その中の一部を日本語に書き換えています。
vb2clr 使い方

StringBuilderのテスト

Sub StringbuildTest()
    Dim host As New CLRHost
 
    Call host.Initialize(False)
 
    Dim Assem As mscorlib.Assembly, sb As mscorlib.Object, r As Variant
    host.CLRLoadAssembly ("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
 
    Set sb = host.ToObject(host.CLRCreateObject("System.Text.StringBuilder"))
    Set sb = host.CLRInvokeMethod(sb, "Append", "The quick brown fox jumped over the lazy dog. ")
    Set sb = host.CLRInvokeMethod(sb, "Append", "Mary had a little lamb.")
 
    Debug.Print host.CLRProperty(sb, "Length")
    r = host.CLRInvokeMethod(sb, "ToString")
    Debug.Print r
 
    Set sb = Nothing
    Set host = Nothing
End Sub

SortedListとArrayListのテスト

Sub SortedlistTest()
    Dim host As New CLRHost
 
    Call host.Initialize(False)
 
    Dim Assem As mscorlib.Assembly, mySL As Object, Total%, i%, aList As Object, interfacelist As Object
    host.CLRLoadAssembly ("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
    Set Assem = host.CLRLoadAssembly("System.Collections, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
    Set mySL = host.ToObject(host.CLRCreateObject("System.Collections.SortedList"))
 
    mySL.Add "Third", "!"
    mySL.Add "Second", "World"
    mySL.Add "First", "Hello"
 
    Total = mySL.Count
    Debug.Print "番号:", Total
 
    For i = 0 To Total - 1
        Debug.Print mySL.GetKey(i), mySL.GetByIndex(i)
    Next
 
    Set mySL = Nothing
    Stop
 
    Set aList = host.ToObject(host.CLRCreateObject("System.Collections.ArrayList"))
    aList.Add ("Hello")
    aList.Add ("World")
    aList.Add ("!")
 
    For Each key In aList
        Debug.Print key
    Next key
 
    Debug.Print aList.IndexOf("!", 0)
    Set aList = Nothing
    Set host = Nothing
End Sub

SHAハッシュの取得

これは筆者の独自のものになります。

Excelを便利にする250以上の機能を体系化したアドインに「RelaxTools Addin for Excel」があります。

この中で「ハッシュ関数のユーザ定義関数を使用するためには、.Net 3.5をインストールする必要があります。」との記載があります。
これが解決できると思い組んでみました。

Private Sub ComputeSHATest()
 
    Debug.Print "SHA256"
    Debug.Print GetSHA256(Range("A1"))
 
    Debug.Print "SHA384"
    Debug.Print GetSHA384(Range("A1"))
 
    Debug.Print "SHA512"
    Debug.Print GetSHA512(Range("A1"))
End Sub

A1セルに"Hello World"をセット、C#で求めたハッシュ値と同じになりました。

結果
SHA256
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e
SHA384
99514329186b2f6ae4a1329e7ee6c610a729636335174ac6b740f9028396fcc803d0e93863a7c3d90f86beee782f4f3f
SHA512
2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b
basFunction
Option Explicit
Private Const C_SHA256 As Long = 1
Private Const C_SHA384 As Long = 2
Private Const C_SHA512 As Long = 3
'--------------------------------------------------------------
' SHA256算出関数
'--------------------------------------------------------------
Public Function GetSHA256(ハッシュ値算出範囲 As Range) As Variant
    Application.Volatile
    GetSHA256 = ComputeSHA(C_SHA256, ハッシュ値算出範囲)
 
End Function
'--------------------------------------------------------------
' SHA384算出関数
'--------------------------------------------------------------
Public Function GetSHA384(ハッシュ値算出範囲 As Range) As Variant
    Application.Volatile
    GetSHA384 = ComputeSHA(C_SHA384, ハッシュ値算出範囲)
 
End Function
'--------------------------------------------------------------
' SHA2512算出関数
'--------------------------------------------------------------
Public Function GetSHA512(ハッシュ値算出範囲 As Range) As Variant
    Application.Volatile
    GetSHA512 = ComputeSHA(C_SHA512, ハッシュ値算出範囲)
 
End Function
 
Private Function ComputeSHA(lngType As Long, r As Range) As Variant
 
    Dim host As New CLRHost
    Call host.Initialize(False)
    host.CLRLoadAssembly ("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")
 
    Dim str As String
    'Rangeの文字列結合(ワークシート関数のConcatを流用)
    str = Application.WorksheetFunction.Concat(r)
 
    'バイト読み込み
    Dim code() As Byte
    Dim objUTF8 As mscorlib.Object
    Set objUTF8 = host.ToObject(host.CLRCreateObject("System.Text.UTF8Encoding"))
    code = host.CLRInvokeMethod(objUTF8, "GetBytes", str)
    Set objUTF8 = Nothing
 
    'ハッシュ値計算
    Dim hashValue() As Byte
    Dim objSHA As mscorlib.Object
    Select Case lngType
        Case C_SHA256
            Set objSHA = host.ToObject(host.CLRCreateObject("System.Security.Cryptography.SHA256Managed"))
        Case C_SHA384
            Set objSHA = host.ToObject(host.CLRCreateObject("System.Security.Cryptography.SHA384Managed"))
        Case C_SHA512
            Set objSHA = host.ToObject(host.CLRCreateObject("System.Security.Cryptography.SHA512Managed"))
    End Select
    hashValue = host.CLRInvokeMethod(objSHA, "ComputeHash", code)
    Set objSHA = Nothing
 
    '16進数へ変換
    Dim description As String
 
    description = ""
 
    Dim i As Long
    For i = LBound(hashValue()) To UBound(hashValue())
        description = description & Right("0" & Hex(hashValue(i)), 2)
    Next i
 
    'return
    ComputeSHA = LCase(description)
 
    Set host = Nothing
End Function

注意点

補足: サポートクラス「CLRHost」

CLRHostクラスのインスタンスを利用し終わった場合は、必ずインスタンスを解放する

技術的な補足

COMベースではない

VB や VBA は COMベースでプログラムが実行されるため、COM相互運用をサポートした.NETアセンブリであれば直接利用することができますが、System.Xmlなどサポートしていないアセンブリは利用することができませんでした。
また、.NET Framework 4.5 からは、.NET型をCOMインターフェイスとして公開することを停止してしまいました。このため、.Net Framework 3.5をインストールする必要がありました。

vb2clrライブラリでは、COMベースではないため、ほぼすべての.NETアセンブリを利用可能になります。

mscorlib とは

mscorlibというのは何なのかというと、.NET Framework の標準ライブラリのコードを含むアセンブリ(DLL)のうち最も重要なものになります。
System.Object型やSystem.String型などの定義はすべてこの中にあります。
ちなみに「Multilanguage Standard Common Object Runtime Library」の略です。

mscorlib.dllにはSystem.Stringの他に、.NETフレームワークの基本となる多くのクラスや機能が定義されています。

公開キートークン

.NET Frameworkライブラリーを使用するのに公開キートークンを知る必要がある。

host.CLRLoadAssembly ("System.IO, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")

調べ方

VS 2022用開発者コマンドプロンプトを起動します。
ネイティブx64バージョン([ x64 Native Tools Command Prompt for VS 2022 ] )を選択してください。

例として、「System.dll」を調べます。

cd "C:\Windows\Microsoft.NET\Framework64\v4.0.30319"

C:\Windows\Microsoft.NET\Framework64\v4.0.30319>SN.exe -T "System.dll"

Microsoft(R) .NET Framework Strong Name Utility バージョン 4.0.30319.0
Copyright (c) Microsoft Corporation. All rights reserved.

公開キー トークン b77a5c561934e089

よく使用するもの

アセンブリにより同じ公開トークン(PublicKeyToken)を使用している。

モジュール 公開トークン
System System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.IO.Compression.FileSystem System.IO.Compression.FileSystem, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.IO System.IO, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Text.Encoding System.Text.Encoding, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
System.Drawing System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

どのアセンブリを使っているのか

例えば、「System.Security.Cryptography.SHA256Managed」は、どのdllなのか?

マイクロソフトのdotnetのapiサイトで検索、バージョンを「.NET Framework 4.8.1」を指定する。
SHA256Managed クラスのところに、アセンブリ:mscorlib.dll と記載されている。
https://learn.microsoft.com/ja-jp/dotnet/api/system.security.cryptography.sha256managed?view=netframework-4.8.1

SN.exe -T "mscorlib.dll"
公開キー トークン b77a5c561934e089

System.dll と同じなので、下記を使用すればよい。

Dim Assem As mscorlib.Assembly
host.CLRLoadAssembly ("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")

最後に

この方法を使えば、 .NET Framework 4の多くの機能を利用出来るようになります。
2018年頃に公開されたライブラリですが、遅ればせながら紹介させて頂きました。

Excel には Mac版もあるので、あくまで Windows限定になります。

vb2clr の他に vb2net ライブラリがあり、これは .NET(旧.NET Core)を利用できるようになっています。これなら Mac版でも動作するかも知れませんね。
VBから.NET(旧.NET Core)を利用してみる

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?