none
officeの参照設定のdllをvb6.0からvb.netへ移行する RRS feed

  • 質問

  • 【Officeの参照設定のDLLをVB6.0からVB.NETへ移行する】

    主に言語はVBAまたはVBを使ってシステム課で保守、運用を行っているプログラマーです。
    一つご相談したいことがありましてご質問させていただきました。
    文書作成支援のためにOffice2002のWordのVBAを使ってデータを簡単に貼り付けるマクロを登録しておりましたが、
    ある時期からテンプレートが増えてきたためVB6.0でDLLを作成してレジストリー登録してWordのVBAから参照設定していました。

    ところが当社も来年の春からOSが現在のWindowsXpからWindows7に切り替わります。
    そこでVB6.0のプログラムをCOMクラステンプレートを利用してVB2005.NETにバージョンアップしてタイプライブラリーを登録して
    新規の文書で正常に動作することは確認できたのですが、以前に作成している数万の古い文書も新しいDLLを参照設定するように切り替えたいのですが
    そのようなことは可能でしょうか。

    先日私のパソコンが先行してWindows7にバージョンアップしたため、とりあえずWindows7でVB6.0のソースをコンパイルして、
    WindowsXpでレジストリー登録してリリースしたのですが過去の文書の参照設定が全て不可になったため、古いWindowsXpでコンパイルしたDLLに戻しました。
    まだあまり詳しく調べていないのですがクラスルートのキーがWindows7上で新たに作られたため、WindowsXp上のローカルマシンのクラスルートのキーと
    不整合になったのだと思います。
    新しいWindows7の環境でVB6.0で作った古いDLLの参照設定を、新しいVB.NETで作成した新しいDLLに参照設定を切り替えて運用することは可能でしょうか。Officeは2010にバージョンアップいたします。

    とてもセンシティブなデータを取り扱っているためどうしても実現したいと思っています。
    ご指導のほどよろしくお願いいたします。

    2010年5月30日 8:18

回答

  • まず、長期間の運用に耐えなければならないのであれば、文書ファイルに外部参照を含めるような設計は見直すべきと思います。

    次回バージョンアップ時に、また同じような苦労をすることになります。

    実行環境が Office 2010 で、開発環境が VB.NET に移行するなら、VSTO ベースのアプリケーションレベルアドインで実装するのが妥当な気がします。

    とまれ

    >まだあまり詳しく調べていないのですがクラスルートのキーがWindows7上で新たに作られたため、WindowsXp上のローカルマシンのクラスルートのキーと
    >不整合になったのだと思います。

    という目先の問題については、VB.NET のプロジェクトで、旧 VB6 時代の ActiveX DLL とバイナリ互換(インターフェース ID やクラス ID を一致させる)ように設定すれば、VB6 時代の ActiveX DLL の単純んな身代わりとして動作するはずです。

    >そこでVB6.0のプログラムをCOMクラステンプレートを利用してVB2005.NETにバージョンアップしてタイプライブラリーを登録して

    というのが、具体的にどんなプロジェクトを吐き出したのか分からないので、具体的にどこをどうすればいいのか分かりませんが。

     

    • 回答としてマーク 山本春海 2010年6月1日 2:00
    2010年5月30日 13:50
  • ありがとうございました。
    だんだんとイメージが湧いてきました。
    元々ワードのテンプレートにマクロを組み込んで文書を新規作成するイベントでメニューバーを作成して
    ユーザーに利用してもらっていたので常に作成元のテンプレートのマクロを参照していて問題なかったのですが、
    あるメーカーさんの文書機能でそのテンプレートを開くようになりメニューバーも作成できず作成元のテンプレートも
    参照できなくなっていたためデータ側にマクロを持たせるような形になっていました。
    またその文書システムに引用機能が付いていたため古いマクロでも最新のプログラムで動作させる必要がありDLLを作ったのだと思います。
    渋木さんのおっしゃる通りVSTOやアドインのようにアプリケーション側に常にプログラムを常駐させておけば問題ないことに気づきました。
    そうすれば過去の文書を開いたいときも古いDLLのリファレンスは削除して、新しいVSTOのインターフェースで動作させれば問題なく動作するような気がします。
    だんだんと柔軟な発想が消えてしまって混乱してしまいました。.NET Framework 全般のフォーラムに載せてしまい申し訳ありませんでした。
    でも大変参考になりました。感謝いたします。
    • 回答としてマーク inataku 2010年5月31日 13:50
    2010年5月31日 13:48

すべての返信

  • まず、長期間の運用に耐えなければならないのであれば、文書ファイルに外部参照を含めるような設計は見直すべきと思います。

    次回バージョンアップ時に、また同じような苦労をすることになります。

    実行環境が Office 2010 で、開発環境が VB.NET に移行するなら、VSTO ベースのアプリケーションレベルアドインで実装するのが妥当な気がします。

    とまれ

    >まだあまり詳しく調べていないのですがクラスルートのキーがWindows7上で新たに作られたため、WindowsXp上のローカルマシンのクラスルートのキーと
    >不整合になったのだと思います。

    という目先の問題については、VB.NET のプロジェクトで、旧 VB6 時代の ActiveX DLL とバイナリ互換(インターフェース ID やクラス ID を一致させる)ように設定すれば、VB6 時代の ActiveX DLL の単純んな身代わりとして動作するはずです。

    >そこでVB6.0のプログラムをCOMクラステンプレートを利用してVB2005.NETにバージョンアップしてタイプライブラリーを登録して

    というのが、具体的にどんなプロジェクトを吐き出したのか分からないので、具体的にどこをどうすればいいのか分かりませんが。

     

    • 回答としてマーク 山本春海 2010年6月1日 2:00
    2010年5月30日 13:50
  • 貴重なお返事ありがとうございます。
    外部参照するようにした理由はもう一つありまして、データベースのサーバー名が変更された時にも対応できるようにしたためです。

    VSTOは毎回最新のプログラムがダウンロードされるようですのでこちらを検討してます。

    現在.NETで吐き出しているComClassのプロジェクトはこのような内容です。
    マクロのボタンをクリックしてDLL側のクラスオブジェクトを作成してアクセスしています。

    ワードの画面にメニューボタンを作成して、VBA側のサンプルにアクセスして、.NET側サンプルを参照しています。

    私の理解できている範囲内では、参照設定を古いVB6.0 DLLから新しいVB.NET DLLに切り替えようとしています。

    もし容易に移行が行える方法がありましたら教えていただきたいと思います。

    どうぞ何卒よろしくお願いいたします。


    VBA側サンプル
    '*******************
    '* フィールドの保護
    '*******************
    Public Sub exeProtect()

        Dim objElectricDoc As New ElectricDoc
        objElectricDoc.Protect
        Set objElectricDoc = Nothing
       
    End Sub

    '********
    ' ヘルプ
    '********
    Private Sub exeHelp()

        Dim objElectricDoc As New ElectricDoc
        objElectricDoc.callHELP
        Set objElectricDoc = Nothing
       
    End Sub

     

    VB.NET側サンプル
    <ComClass(ElectricDoc.ClassId, ElectricDoc.InterfaceId, ElectricDoc.EventsId)> _
    Public Class ElectricDoc

    #Region "COM GUID"
        ' これらの GUID は、このクラスおよびその COM インターフェイスの COM ID を
        ' 指定します。この値を変更すると、
        ' 既存のクライアントはクラスにアクセスできなくなります。
        Public Const ClassId As String = "197848fe-7f4d-4b9f-9de9-c57e123e9643"
        Public Const InterfaceId As String = "3cda149c-d708-4497-8e8c-858cbf55d71e"
        Public Const EventsId As String = "8e29a640-93f4-424d-bde6-d9bfb0aa70c5"
    #End Region

        ' 作成可能な COM クラスにはパラメータなしの Public Sub New() を指定しなければ
        ' なりません。これを行わないと、クラスは COM レジストリに登録されず、
        ' CreateObject 経由で
        ' 作成できません。
        Public Sub New()
            MyBase.New()
        End Sub


        '*******************
        '* フィールドの保護
        '*******************
        Public Sub Protect()

            If WordGlobal_definst.ActiveDocument.ProtectionType <> Word.WdProtectionType.wdNoProtection Then
                WordGlobal_definst.ActiveDocument.Unprotect()
                MsgBox("「フィールドの保護」を解除しました。", vbInformation)
            Else
                WordGlobal_definst.ActiveDocument.Protect(Word.WdProtectionType.wdAllowOnlyFormFields)
                WordGlobal_definst.CommandBars("Forms").Visible = True
                MsgBox("「フィールドの保護」を解除する場合は、" & vbCrLf & "再度「フィールドの保護」を押します。", vbInformation)
                MsgBox("「フィールドの保護」された状態で「登録」ボタンを押した場合で再編集するには、" & vbCrLf & "「フォーム」ツールバーの「フォームの保護」ボタンで解除してください。", vbInformation)
            End If

        End Sub

        '***********************
        '* フィールド保護の解除
        '***********************
        Public Sub UnProtect()

            If WordGlobal_definst.ActiveDocument.ProtectionType = Word.WdProtectionType.wdAllowOnlyFormFields Then
                WordGlobal_definst.ActiveDocument.Unprotect()
                MsgBox("「フィールドの保護」を解除しました。", vbInformation)
            End If

        End Sub

    2010年5月31日 1:07
  • ありがとうございました。
    だんだんとイメージが湧いてきました。
    元々ワードのテンプレートにマクロを組み込んで文書を新規作成するイベントでメニューバーを作成して
    ユーザーに利用してもらっていたので常に作成元のテンプレートのマクロを参照していて問題なかったのですが、
    あるメーカーさんの文書機能でそのテンプレートを開くようになりメニューバーも作成できず作成元のテンプレートも
    参照できなくなっていたためデータ側にマクロを持たせるような形になっていました。
    またその文書システムに引用機能が付いていたため古いマクロでも最新のプログラムで動作させる必要がありDLLを作ったのだと思います。
    渋木さんのおっしゃる通りVSTOやアドインのようにアプリケーション側に常にプログラムを常駐させておけば問題ないことに気づきました。
    そうすれば過去の文書を開いたいときも古いDLLのリファレンスは削除して、新しいVSTOのインターフェースで動作させれば問題なく動作するような気がします。
    だんだんと柔軟な発想が消えてしまって混乱してしまいました。.NET Framework 全般のフォーラムに載せてしまい申し訳ありませんでした。
    でも大変参考になりました。感謝いたします。
    • 回答としてマーク inataku 2010年5月31日 13:50
    2010年5月31日 13:48
  • >渋木さんのおっしゃる通りVSTOやアドインのようにアプリケーション側に常にプログラムを常駐させておけば問題ないことに気づきました。
    >そうすれば過去の文書を開いたいときも古いDLLのリファレンスは削除して、新しいVSTOのインターフェースで動作させれば問題なく動作するような気がします。

    そうですね。アプリケーションレベルのアドインに以降できるようなら、それが無難な線だと思います。

    2010年5月31日 14:04