複数のユーザーで使用可能

Accessなどのデータベースを使用するのが当たり前だが

私はExcel愛好者なので、Excelを使用する!

 

 xx.basで保存→Excelbook1  basの呼び出し→Excelbook1読み込みモジュール→

Excelbook2保存data

 では出来ないだろうか?

 

 

呼び出したいモジュールとして,下記のような2つがあるとしよう。

まずは,これらをそれぞれ自由にエディタ(メモ帳とか)で書いて,ファイルとして保存。

HogeModule.bas

'---------------------------------------------------------------

' hogeのためのモジュール。
Attribute VB_Name = "HogeModule"

Sub hoge()
    MsgBox "hoge"
End Sub

Function hello(x)
    hello = "Hello, " & x & "!"
End Function
'---------------------------------------------
FugaModule.bas

' fugaのためのモジュール。
Attribute VB_Name = "FugaModule"


Sub fuga()
    MsgBox "fuga"
End Sub
'----------------------------
そして,これらの2つを呼び出したいという旨,設定ファイルに記述する。

下記のように。

 

libdef.txt

'---------------------------------

.\HogeModule.bas .\FugaModule.bas

'--------------------------------

次に,呼び出したい側のエクセルファイルに,モジュールを自動的に読み込むという設定を書く。

 

事前に下記の設定を行なっておくこと。

(Excel2003の場合)

ツール>マクロ>セキュリティ>信頼できる発行元>Visual Basic プロジェクトへのアクセスを信頼する をオン

 

(Excel2007の場合)

リボンの「開発」タブ>マクロのセキュリティ>VBAプロジェクトオブジェクトモデルへのアクセスを信頼する

http://support.microsoft.com/kb/282830/ja

※「プログラミングによるVisual Basicプロジェクトへのアクセスは信頼性に欠けます」というエラーメッセージが出ないようになる。

'------------------------------------------------------------------------------------------------------

 

ここでは,呼び出し側のファイルをcaller.xlsとする。

「ブックを開いたときに自動的に〜〜」という処理は ThisWorkbook の中に書く。

 

下記の内容をコピペ。

 

caller.xls のThisWorkbook

'----------------------------------------------------------------------------------------------------------------

 

' ワークブックを開く時のイベント Private Sub Workbook_Open() ' txtに書いてある外部ライブラリを読み込み load_from_conf ".\libdef.txt" End Sub

 

'------------------------------------------------------------------------------------------------------------------------

 


' -------------------- モジュール読み込みに関する関数 --------------------



' 設定ファイルに書いてある外部ライブラリを読み込みます。
Sub load_from_conf(conf_path)
   
   ' 全モジュールを削除
    clear_modules
   
   ' 絶対パスに変換
    conf_path = abs_path(conf_path)
    If Dir(conf_path) = "" Then
        MsgBox "外部ライブラリ定義" & conf_path & "が存在しません。"
        Exit Sub
    End If
   
   ' 読み取り
    fp = FreeFile
    Open conf_path For Input As #fp
    Do Until EOF(fp)
       ' 1行ずつ
        Line Input #fp, temp_str
        If Len(temp_str) > 0 Then
            module_path = abs_path(temp_str)
            If Dir(module_path) = "" Then
               ' エラー
                MsgBox "モジュール" & module_path & "は存在しません。"
                Exit Do
            Else
               ' モジュールとして取り込み
                include module_path
            End If
        End If
    Loop
    Close #fp

    ThisWorkbook.Save
   
End Sub


' あるモジュールを外部から読み込みます。
' パスが.で始まる場合は,相対パスと解釈されます。
Sub include(file_path)
   ' 絶対パスに変換
    file_path = abs_path(file_path)
   
   ' 標準モジュールとして登録
    ThisWorkbook.VBProject.VBComponents.Import file_path
End Sub


' 全モジュールを初期化します。
Private Sub clear_modules()
    For Each component In ThisWorkbook.VBProject.VBComponents
        If component.Type = 1 Then
           ' この標準モジュールを削除
            ThisWorkbook.VBProject.VBComponents.Remove component
        End If
    Next component
End Sub


' ファイルパスを絶対パスに変換します。
Function abs_path(file_path)

   ' 絶対パスに変換
    If Left(file_path, 1) = "." Then
        file_path = ThisWorkbook.Path & Mid(file_path, 2, Len(file_path) - 1)
    End If
   
    abs_path = file_path

End Function

 

これで完了だ。

caller.xlsを開くと,HogeModule.hoge() も FugaModule.fuga() も実行可能な状態になっている。

'----------------------------------------------------------------------------------------------------------------

備考 

  • ワークブックを開くときのイベント

Option Explicit

' ワークブックを閉じる前のイベント(キャンセル可)
Private Sub Workbook_BeforeClose(Cancel As Boolean)
    If MsgBox("Workbook_BeforeCloseイベントが発生しました。" & vbCr & _
        "キャンセルしますか?", vbInformation + vbYesNo) = vbYes Then
        Cancel = True
    End If
End Sub
'----------------------------------------------------------------------------------------------------------
' ワークブックを保存する前のイベント(キャンセル可)
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
    If MsgBox("Workbook_BeforeSaveイベントが発生しました。" & vbCr & _
        "キャンセルしますか?", vbInformation + vbYesNo) = vbYes Then
        Cancel = True
    End If
End Sub
'-----------------------------------------------------------------------------------------------------------
' ワークブックを開く時のイベント
Private Sub Workbook_Open()
    ActiveWindow.ScrollRow = 1
    MsgBox "Workbook_Openイベントが発生しました。"
End Sub
'---------------------------------------------------------------------------------------
' シートを切り替えるイベント
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
    MsgBox "Workbook_SheetActivateイベントが発生しました。" & vbCr & _
        "シート名は" & Sh.Name & "です。"
End Sub
'-------------------------------------------------------------------------------------------------
' ウィンドウを切り替えるイベント(自ブックが手前)
Private Sub Workbook_WindowActivate(ByVal Wn As Window)
    MsgBox "Workbook_WindowActivateイベントが発生しました。"
End Sub
'----------------------------------------------------------------------------------------------------
' ウィンドウを切り替えるイベント(自ブックが裏)
Private Sub Workbook_WindowDeactivate(ByVal Wn As Window)
    MsgBox "Workbook_WindowDeactivateイベントが発生しました。"
End Sub

'-------------------------------------------------------------------------------------------------------

'《標準モジュールのインポートをVBAで自動化する方法》

   Public Sub Sample_ImportModule_01()
 
     ' ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
    ' 参照設定:
   ' 「Microsoft Visual Basic for Application Extensibility」
     ' ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
    
       ' このブックのVBProjectをオブジェクト変数に格納する。

Public Sub Sample_ImportModule_01()
       Dim Obj As VBIDE.VBProject
      Set Obj = ThisWorkbook.VBProject
  
      ' インポートしたいファイル名を決める。
      Dim ImpFile As String
      ImpFile = "C:\Users\coco\Desktop\VBFuku\HogeModule.bas .\FugaModule.bas "

     ' ブック内にモジュールがあるか判別する。
      If exists_ImpFile(ImpFile) Then
        MsgBox "既に同一モジュールが存在します。", vbExclamation
    Else
        ' このブックにVBAモジュールをインポートします。
         Obj.VBComponents.Import ImpFile
    End If

    ' オブジェクトを破棄する。
    Set Obj = Nothing

 End Sub

  ' *
 ' * ブック内にモジュールがあるか判別する関数
 ' *
  Public Function exists_ImpFile(  pImpFile As String  ) As Boolean

   ' 戻り値をFalseで初期化する。
    exists_ImpFile = False

   ' FileSystemObjectを生成する。
    Dim F As Object
        Set F = CreateObject("Scripting.FileSystemObject")

     ' ファイルのベース名を切り出す。
      Dim fileName As String
      fileName = F.GetBaseName(pImpFile)
  
      ' このブックのVBProjectをオブジェクト変数に格納する。
      Dim Obj As VBIDE.VBProject
      Set Obj = ThisWorkbook.VBProject
 
      ' VBProjectに存在するコンポーネント数を変数に格納する。
      Dim CompCnt As Long
      CompCnt = Obj.VBComponents.Count
  
      ' VBProjectに存在するコンポーネントを一つずつ参照する。
      Dim lp As Long
     For lp = 1 To CompCnt
          ' モジュールが既に存在していないか判別する。
         If Obj.VBComponents(lp).Name = fileName Then
              ' 戻り値をTrueにする。
              exists_ImpFile = True
             GoTo END_JUDGE
          End If
      Next
  
  END_JUDGE:
  
      ' オブジェクトを破棄する。
      Set Obj = Nothing
      
  End Function

 

'-----------------------------------------------------------------------------------------------------------------

  • 標準モジュールを削除する方法

Sub CodeDelete()
 Dim Obj As Object
 For Each Obj In ThisWorkbook.VBProject.VBComponents
  With Obj
    If .Type = 1 Then
        Application.VBE.activeVBProject.VBComponents.Remove Obj
    End If
  End With
 Next Obj
End Sub
'----------------------------------------------------------------------------------------------------------------