カテゴリー: 設定

ExcelやVBAでの設定など、使い方について記載していきます

  • Excel VBAでWordを操作するための参照設定

    Excel VBAでWordを操作するための参照設定

    これは始まりの始まりでしかない、ただのメモっすw

    最近色々ドタバタで更新できていませんでしたが、ボチボチ再開したい

    でも、何か色々データが消えたので、立ち直るのに時間がwww

    ま、そーもいってられんから、何気なく、書き始めるのです

    ■Word文書

    仕事の現場で、Word文書の更新状況を確認する必要が出てきまして、始めはファイルの更新日付で管理していたのですが、SVNなどのソース管理システムでWord文書もバージョン管理をするようになりました

    そーすると、更新日付でみる必要がなくなり、バージョン管理で十分になったのですが、今度は、ファイルの中に記載された履歴情報などを実際に正しくかけているのか!?という管理が必要になりました

    ファイルを開くと、「更新履歴」という表があって、そこに以下の情報が書かれているのです

    • ファイルバージョン
    • 更新日付
    • 更新者名
    • 更新内容
    更新履歴
    更新履歴

    これをファイルを1つずつ開いて、文書内を「更新履歴」で検索して、内容をExcelに書き写す・・

    そんな悲しい作業が待っていたのです!w

    しかも、年だの月だのと言ったフォルダに複数のWord文書が配置されていて、同じ名前のファイルまであるのです!?

    ソース管理システムに保存される前の管理方法なんですけどね・・

    もーいらなくね???って思うんですけど、文書によっては、枝分かれすることもあるらしく、昔の状態でもファイルを残しておきたいのだそうだ・・

    最近作った文書ファイルなら、始めからソース管理システムに保存して、ブランチしていけばいいんでしょうけど、昔からあるファイルってのは、そーもいかないそーなんですw

    ■VBAでWordを処理したい

    というわけで、だったら、ExcelマクロのVBAで、フォルダ内のファイルをそれぞれ開いて、更新履歴の内容をコピーしてくるツールを作っちゃえばいいんじゃないの!?

    と思いつきましてー

    早速、ネットサーフィーーーーーンを開始!

    サンプルのソースなどを見つけたのですが、いきなり、以下のような単語(オブジェクト名)がでてくるのです!

    • Word.Application
    • Word.Document

    ま、何も気にせず、サンプルを実行してみたのですが、エラーが出て動きませんでした!!!

    参照設定
    参照設定

    Excelにも同じオブジェクトがあるので、何がダメなんだろう???

    と一瞬、疑問に思いましたが・・

    普通はオブジェクトを生成する場合は、CreateObjectをするんだけど、ExcelオブジェクトをCreateObjectしたことなんてありません!

    ■参照設定

    理由は簡単ですねー

    ExcelのVBAでは、始めから参照設定に「Microsoft Excel xx.x Object Library」が入っていますから!!!

    参照設定
    参照設定

    つまり、Wordオブジェクトがエラーになったのは、Wordの「Object Library」が参照設定にないからですね~

    と、気が付いてしまえば、「Microsoft Word xx.x Object Library」を参照可能なライブラリファイルの一覧から探して、チェックして「OK」をクリックするだけ!

    Microsoft Word xx.x Object Library
    Microsoft Word xx.x Object Library

    ■実行結果

    これで実行すれば、問題なくWordオブジェクトを生成してくれます!

    実行する
    実行する

    とまー、今回は最初のところだけを記事にしておきます

    実際に更新履歴を取得して、Excelに記載してくところは、今後勉強しながら記事にしていきたいと思います!

    というわけで、今回は短いですがw

    ではでは

  • Excel VBAの参照設定

    Excel VBAの参照設定

    【環境】Windows 10 Pro 64bit、Excel for Office 365

    Excel VBA (Microsoft Visual Basic for Applications)で参照設定を操作する方法について解説します

    ■参照設定を開く

    Visual Basic Editorの[ツール] – [参照設定]で開きます

    参照設定
    参照設定

    参照設定でライブラリファイルにチェックを入れることで、そのライブラリを VBA から使用することができるようになります

    参照設定のダイアログに関する説明は、MicrosoftのWEBサイトを見てくださいw

    参照サイト:「[参照設定] ダイアログ ボックス | Microsoft Docs

    ■FileSystemObjectオブジェクトを使うには?

    今回は、ファイル操作を行う時に、よく使用する FileSystemObject のメンバを参照できるようにしてみましょう!

    ・参照設定なし

    参照を設定せずに、変数のタイプに FileSystemObject を指定しても入力補完機能(インテリセンス)は利用できません

    参照なし
    参照なし

    ・参照設定あり

    – Microsoft Scripting Runtimeを追加

    「Microsoft Scripting Runtime」を参照設定 に追加します

    Scripting Runtime
    Microsoft Scripting Runtime を参照する

    すると インテリセンス が利用できるようになりますね!

    インテリセンス利用
    インテリセンスが利用できる

    メンバを参照することもできるので、非常にコード生成が楽になります

    メンバ参照のインテリセンス
    メンバ参照のインテリセンス

    ■Scriptingライブラリとは

    今、サンプル「 FileSystemObject_Sample1() 」では、 FileSystemObject を直接指定しています

    もちろん、参照の場合は、パラメータのヘルプなどもこれだけで表示することはできるのですがー

    パラメータのヘルプ
    パラメータのヘルプ

    FileSystemObject は、参照に追加したライブラリ 「 Microsoft Scripting Runtime 」の名の通り、「 Scripting 」というライブラリが持っているのです!

    オブジェクトブラウザーで「 Scripting 」というライブラリを選択して頂くと、以下のように、 FileSystemObject がいるのがわかりますよね!

    他にも 以下のような、便利なオブジェクトが多数含まれています

    • Dictionary
    • TextStream
    • Encoder
    • Drive
    • File
    • Folder
    オブジェクトブラウザー
    オブジェクトブラウザー

    この「 Scripting 」に「 FileSystemObject 」が含まれるということは、つまり「 Scripting.FileSystemObject 」が正式名称!?なのです!?(たぶん)

    正式名称
    「 Scripting.FileSystemObject 」が正式名称!?

    というわけで、オブジェクト名を使用してサンプルを書いてみます・・・①

    Sub FileSystemObject_Sample1()
        Dim obj As Scripting.FileSystemObject
        Set obj = New Scripting.FileSystemObject
        Call obj.CreateFolder("C:\\aaa")
        Set obj = Nothing 
       
    End Sub

    ちょっと、うるさいので、あっさりとこう書くこともできます・・・②

    Sub FileSystemObject_Sample1()
        Dim obj As New Scripting.FileSystemObject
        Call obj.CreateFolder("C:\\aaa")
        Set obj = Nothing  
      
    End Sub

    「 obj 」や「 Nothing 」も削って、こう書くことも・・やりすぎですかね?w・・・③

    Sub FileSystemObject_Sample1()
        With New Scripting.FileSystemObject
            Call .CreateFolder("C:\\aaa")
        End With
    End Sub

    ■実行時バインディング

    参照を使用せずに CreateObject を使用して、 FileSystemObject をオブジェクト化する際には 実行時バインディング として「 Scripting.FileSystemObject 」と指定しないとエラーになってしまいます

    Sub FileSystemObject_Sample2()
        Dim obj As Object
        Set obj = CreateObject("Scripting.FileSystemObject")
        Call obj.CreateFolder("C:\\aaa")
        Set obj = Nothing 
       
    End Sub

    というわけで、参照の場合も「 Scripting.FileSystemObject 」と書く癖をつけておいた方が良いかも知れませんね!

    参照を使った3つのやり方の中で最も近いのは、①ですかね?置き換えることを考えて①の書き方にしておけば良さそうです

    ■VBAで参照を操作する

    余談ではありますが、「 Microsoft Scripting Runtime 」のファイルは以下の “scrrun.dll” です

    ファイルパス
    ファイルパス

    ※パスは環境が64bitなので、32bitのシステムファイルのパスとして、
    「 C:\Windows\SysWOW64\ 」になっていますが、32bit環境では
    「 C:\Windows\System32\ 」になりますねー

    つまりは、この 「 Microsoft Scripting Runtime 」 のファイルがないと FileSystemObject は使えないのです!(ないってことはないと思いますが・・)

    ここからは、 VBA を使用して、参照を追加したり、削除したりしてみます!

    ・参照をVBAで追加

    参照設定のダイアログボックスを開いて、希望するライブラリを探して選択するのって、割と面倒ですよねw
    そんな時は、こんな感じで、VBAで登録してしまいましょう!

    ①参照追加の呼び出し元関数

    Sub CallReferencesAddFromFile_Sample()
        ' 参照に追加するライブラリのファイルパスを用意します(ここではFileSystemObjectを追加する例)
        Const DLL_SCRRUN As String = "C:\Windows\SysWOW64\scrrun.dll"
        ' 参照追加関数にライブラリのファイルパスを渡して呼び出す
        Call References_AddFromFile(DLL_SCRRUN)
    End Sub

    ②参照を追加する関数

    Sub References_AddFromFile(dllPath As String)
        ' 参照を追加する
        Call Excel.ThisWorkbook.VBProject.References.AddFromFile(dllPath)
    End Sub

    ・参照をVBAで削除

    参照を削除するには、以下のように行います

    ③参照削除の呼び出し元関数

    Sub CallReferencesRemove_Sample()
        ' 参照から削除するライブラリのファイルパスを用意します(ここではFileSystemObjectを削除する例)
        Const DLL_SCRRUN As String = "C:\Windows\SysWOW64\scrrun.dll"
        ' 削除関数にライブラリのファイルパスを渡して呼び出す
        Call References_Remove(DLL_SCRRUN)
    End Sub

    ④参照を削除する関数

    Sub References_Remove(dllPath As String)
        Dim obj As Object
        
        With Excel.ThisWorkbook.VBProject
            ' ファイルで参照しているものを検索します
            For Each obj In .References
                ' 参照不可ではない場合のみ実施する
                If (obj.IsBroken = False) Then
                    ' Name、Description、FullPath、IsBrokenのプロパティを持っています
                    If (obj.FullPath = dllPath) Then
                        ' 参照を削除する
                        Call .References.Remove(obj)
                    End If
                End If
            Next 
        End With
    End Sub

    ④はネストし過ぎて読みづらいですねー
    こういうソースはダメ!非常に恥ずかしいソースです・・

    というわけで、 VBIDE を使った書き方に書き直してみたが・・
    ネストが減らない上に、余計に気持ち悪くなってきたw

    ⑤気持ち悪い例w

    Sub References_Remove2(dllPath As String)
        Dim refers  As VBIDE.References
        Dim ref     As VBIDE.Reference
        Dim rName   As String
        
        Set refers = Excel.ThisWorkbook.VBProject.References
        
        ' 参照しているものを探します
        For Each ref In refers
            ' 参照不可ではない場合のみ実施する
            If (ref.IsBroken = False) Then
                ' ライブラリのファイルパスで比較
                If (ref.FullPath = dllPath) Then
                    rName = ref.Name
                    Exit For
                End If
            End If
        Next
        If (Len(rName) > 0) Then
            ' Nameプロパティを渡してオブジェクトを取得する
            Set ref = refers.Item(rName)        
            ' 参照を削除する
            Call refers.Remove(ref)        
            Set ref = Nothing
        End If
        
        Set refers = Nothing
        
    End Sub

    ⑧ライブラリ名で参照を削除する呼び出し元関数

    Sub CallReferencesRemove_Sample3()
        ' 参照から削除するライブラリ名
        Const DLL_SCRRUN As String = "Scripting"
        
        ' 削除関数にライブラリ名を渡して呼び出す
        Call References_Remove3(DLL_SCRRUN)
        
    End Sub

    ⑨ライブラリ名で参照を削除する関数

    Sub References_Remove3(dllName As String)
        Dim ref     As VBIDE.Reference
        
        With Excel.ThisWorkbook.VBProject
        
            Set ref = .References(dllName)
            
            If Not (ref Is Nothing) Then
                Call .References.Remove(ref)
            End If
            
            Set ref = Nothing
            
        End With
        
    End Sub

    パッと見は綺麗になったんですが、 IsBroken プロパティを見ていないし、
    「 Set ref = .References(dllName) 」でライブラリがなかったらエラーになります!

    根本的にライブラリのパスを使って、追加や削除するのがダメな気がしますけどw
    参考までに GUID で追加するサンプルも書いてみますが、大して変わり映えしないです

    ⑥ GUID を使用して参照を追加する呼び出し元関数

    Sub CallReferencesAddFromGuid_Sample()
        ' 参照に追加するライブラリのGUIDを用意します(ここではFileSystemObjectを追加する例)
        Const DLL_SCRRUN As String = "{420B2830-E718-11CF-893D-00A0C9054228}"
        
        ' 参照追加関数にライブラリのGUIDとバージョン(MajorとMinor)を渡して呼び出す
        Call References_AddFromGuid(DLL_SCRRUN, 1, 0)
        
    End Sub

    ⑦ GUID を使用して参照を追加する関数

    Sub References_AddFromGuid(guid As String, major As Long, minor As Long)
        ' 参照を追加する
        Call Excel.ThisWorkbook.VBProject.References.AddFromGuid(guid, major, minor)
        
    End Sub
    

    ・参照設定の一覧表示

    VBA で参照しているライブラリの一覧を表示してみます

    Sub GetReferencesList_Sample()
        Dim refers As VBIDE.References
        Dim ref As VBIDE.Reference
        
        Set refers = Excel.ThisWorkbook.VBProject.References
        
        For Each ref In refers
            Debug.Print "--------------------------------------------------------------------------------------------------------------"
            Debug.Print ref.Name, ref.guid & " : " & ref.Major & "." & ref.Minor & " : " & ref.Description
            Debug.Print ref.FullPath
        Next ref
        Debug.Print "--------------------------------------------------------------------------------------------------------------"
    

    出力結果

    --------------------------------------------------------------------------------------------------------------
    VBA           {000204EF-0000-0000-C000-000000000046} : 4.2 : Visual Basic For Applications
    C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA7.1\VBE7.DLL
    --------------------------------------------------------------------------------------------------------------
    Excel         {00020813-0000-0000-C000-000000000046} : 1.9 : Microsoft Excel 16.0 Object Library
    C:\Program Files (x86)\Microsoft Office\Root\Office16\EXCEL.EXE
    --------------------------------------------------------------------------------------------------------------
    stdole        {00020430-0000-0000-C000-000000000046} : 2.0 : OLE Automation
    C:\Windows\SysWOW64\stdole2.tlb
    --------------------------------------------------------------------------------------------------------------
    Office        {2DF8D04C-5BFA-101B-BDE5-00AA0044DE52} : 2.8 : Microsoft Office 16.0 Object Library
    C:\Program Files (x86)\Common Files\Microsoft Shared\OFFICE16\MSO.DLL
    --------------------------------------------------------------------------------------------------------------
    Outlook       {00062FFF-0000-0000-C000-000000000046} : 9.6 : Microsoft Outlook 16.0 Object Library
    C:\Program Files (x86)\Microsoft Office\Root\Office16\MSOUTL.OLB
    --------------------------------------------------------------------------------------------------------------
    VBIDE         {0002E157-0000-0000-C000-000000000046} : 5.3 : Microsoft Visual Basic for Applications Extensibility 5.3
    C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB
    --------------------------------------------------------------------------------------------------------------
    Scripting     {420B2830-E718-11CF-893D-00A0C9054228} : 1.0 : Microsoft Scripting Runtime
    C:\Windows\SysWOW64\scrrun.dll
    --------------------------------------------------------------------------------------------------------------
    

    ・参考

    VBProject を使う場合は、 VBIDE というライブラリを参照するとクラスが使えるようになります!

    ■注意事項

    参照設定は、開発時には非常に便利なのですが、開発したPC以外で動作させるには、
    色々と注意事項があるのです!

    • 参照はライブラリファイルを指定する
    • 参照ライブラリがインストールしていないPCでは動作しない
    • Office 等のバージョン違いやライブラリのバージョンが異なると動作しない
    • 古いバージョンで「参照不可」になると参照や削除ができません
    • 参照不可かどうかは References の IsBroken プロパティで確認する
    • 環境依存な参照は使わないようにする
    • 実行時バインディングに変換できるよう個別でクラス化しておく

    ではでは