Accessアプリ保守開発で作ったツール集

### 1. VBA/クエリのソースエクスポート ###
Accessを使ったアプリを保守・運用するにあたり、不便なことの１つが
**「仕様変更時の影響範囲を調べるのが大変！」**
という点。

例えばテーブルのカラム名を変更するとき、どのクエリに影響があるかを調べるには、全部のクエリ定義を画面でいちいち開いてチェックetc.せねばなりません。
Access標準のデータベース構造解析機能やフリーの仕様書作成ツールなどを使えば楽ですが、それでも規模が大きくなるほど手間かかって大変やし、できればエディタのgrepなどでちゃっちゃと調べられると楽ですよね。

というわけで、AccessアプリのフォームおよびモジュールのVBAコード、及びクエリのSQL定義をテキストベースでファイル出力するスクリプトを作ってみました。
元ネタはおなじみ、T'sWareはんの記事
[「Access Tips#642　すべてのモジュールをテキストファイルにエクスポートする方法」](https://tsware.jp/tips/tips_642.htm)
を参考にして、各オブジェクトの内容をテキストに一括エクスポートします。
``` VB
Public Sub sPb_ソースエクスポート()

    On Error Resume Next
    
    Dim vbc As Object
    Dim 出力パス名 As String
    
    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = "保存先フォルダを指定してください"
        .ButtonName = "出力"
        .InitialView = msoFileDialogViewSmallIcons
        If .Show Then
            出力パス名 = .SelectedItems(1)
        Else
            Exit Sub
        End If
    End With
    
    ' VBAソースの出力
    For Each vbc In VBE.ActiveVBProject.VBComponents
        With vbc
            ' 拡張子を設定
            Select Case .Type
            Case 1      ' 標準モジュール
                .export 出力パス名 & "\" & .Name & ".bas"
            Case 2      ' クラスモジュール
                .export 出力パス名 & "\" & .Name & ".cls"
            Case 100    ' フォーム／レポートのモジュール
                .export 出力パス名 & "\" & .Name & ".cls"
            End Select
        End With
    Next vbc

    ' クエリー定義の出力
    Dim fso As New Scripting.FileSystemObject
    Dim fo As TextStream
    Dim qd As DAO.QueryDef
    For Each qd In CurrentDb.QueryDefs
        Set fo = fso.CreateTextFile(FileName:=出力パス名 & "\" & qd.Name & ".sql")
        fo.Write qd.SQL
        fo.Close
    Next
    
    MsgBox "VBA及びクエリソースファイルをエクスポートしました", vbInformation + vbOKOnly, "お知らせ"
    Exit Sub

End Sub
```
****
### 2. リンク先テーブルの一括切り替え ###
筆者の場合、Accessアプリの本番データはファイルサーバに、テスト用データはローカルPCに配置していますが、アプリ開発に際してテスト用／本番用で都度リンクテーブルを切り替えるのは非常に大変やし、ミスオペも起こりかねません。

というわけで、リンク先テーブルを一括して切り替えるスクリプトを作ってみました。
``` VB
Public Sub sPb_テーブルリンク先切り替え()

    On Error Resume Next
    
    Dim tbl As DAO.TableDef
    Dim i As Long
    
    i = 0
    For Each tbl In CurrentDb.TableDefs
        With tbl
            ' ODBC以外のリンクテーブルが対象
            If .Connect <> "" And _
               Left$(.Connect, 5) <> "ODBC;" Then
                ' コンスタント cPb_モードの内容が"テスト"であればテストDBにリンク、それ以外は本番DBにリンク
                If cPb_モード = "テスト" Then
                    .Connect = ";DATABASE=（テストDBファイルのパス）;TABLE=" & .Name
                Else
                    .Connect = ";DATABASE=（本番DBファイルのパス）;TABLE=" & .Name
                End If
                .RefreshLink        ' リンク先情報の更新
                i = i + 1
                Debug.Print "テーブル名：" & .Name
            End If
        End With
    Next tbl
    
    If cPb_モード = "テスト" Then
        MsgBox i & "件のテストモードへのテーブルリンクの切り替えが完了しました。", vbInformation + vbOKOnly, "お知らせ"
    Else
        MsgBox i & "件の本番モードへのテーブルリンクの切り替えが完了しました。", vbInformation + vbOKOnly, "お知らせ"
    End If

End Sub
```
****
### 3. 構成要素を一覧表示 ###
これがあると、特に仕様書の作成・保守のタイミングで地味に便利です:wink:
``` SQL
SELECT "01.テーブル" AS 区分, Name
FROM MsysObjects
WHERE left([Name], 4) <> "Msys"
AND type = 1
AND flags = 0

UNION

SELECT "02.リンクテーブル" AS 区分, Name
FROM MsysObjects
WHERE type = 6

UNION

SELECT "03.クエリ" AS 区分, Name
FROM MsysObjects
WHERE Left([Name], 1) <> "~"
AND type = 5

UNION

SELECT "04.フォーム" AS 区分, Name
FROM MsysObjects
WHERE type = -32768

UNION

SELECT "05.レポート" AS 区分, Name
FROM MsysObjects
WHERE type = -32764

UNION

SELECT "06.マクロ" AS 区分, Name
FROM MsysObjects
WHERE type = -32766
AND name <> "TMPCLPMacro"

UNION SELECT "07.モジュール" AS 区分, Name
FROM MsysObjects
WHERE type = -32761
ORDER BY 区分, Name;
```