【公式は教えてくれない】Access VBA Navigation Pane ナビゲーションウィンドウのオプションの罠

#マイクロソフトアクセス(MS Access)のNavigationのオプション
##通常の操作
###オプション>現在のデータベース>ナビゲーション>ナビゲーションオプション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/589b406b-e201-eec8-d355-4c0de60b5a9d.png)
###表示オプション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/740336cb-4d1c-3b13-167b-5472e2f76108.png)

- [ ] 隠しオブジェクトの表示
- [ ] システムオブジェクトの表示
- [x] 検索バーの表示

通常は検索バーの表示にのみチェックが入っている
####検索バーはナビゲーションペインの上のほうにある目立たないやつ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126919/3ddcf1a0-5427-3661-4388-1eb05ffdeaec.png)

##答えの前に
このオプションは当然ナビゲーションペインを表示しているときに有効です。設定はできても表示されなければわかりません。
###基礎知識
今回必要なのはまずSetOption
[SetOption](https://docs.microsoft.com/ja-jp/office/vba/api/access.application.setoption)
しかし、これはオプションの名前、しかも英語でなければならない
OptionName 	必須 	String 	オプションの名前を指定します。 オプション名引数の文字列の一覧については、「 Visual Basic でオプションを設定する」を参照してください。
Setting 	必須 	Variant 	オプションの設定値に対応する値を指定します。 引数 setting の値は、個々のオプションに設定できる値である必要があります。
注釈

使用できるオプションの値は、設定するオプションの種類によって異なります。 一般的なオプションには次の 3 種類があります。

 - チェック ボックスのオン/オフを切り替えて設定する、Yes または No の値を取るオプション
 - 文字列や数値を入力して設定するオプション
 - リスト ボックス、コンボ ボックス、またはオプション グループから選択できる定義済みのオプション

ユーザーがチェックボックスをオンまたはオフにして設定するオプションについては、次の例に示すように、引数 Setting にTrueまたはFalseを指定します。

```vb
Application.SetOption "Show Status Bar", True
```

[Visual Basic を使用してオプションを設定する(記載されていない)](https://docs.microsoft.com/ja-jp/office/vba/access/concepts/settings/set-options-from-visual-basic)
当然ここも載っていない

###英語なら?
https://www.fmsinc.com/MicrosoftAccess/2007/search-bar/Index.asp
検索バーは2007から
通常英語はこのオプションの名前と対応している

- [ ] Show Hide Objects
- [ ] Show System Objects
- [x] Show Search Bar

通常はこの英語の表記を調べて書くとできる。

```vb
Application.SetOption "Show Hide Objects", True
Application.SetOption "Show Hidden Objects", True
Application.SetOption "Show Search Bar", True
```

今回もそのセオリーが有効だが、実はこの表記の中で一つエラーになる。

```vb
Sub ShowNaviGationHIdeAndSystem()
'For Access 2007 Later
'Option > Navigation Option >
'Navigationにシステムテーブル、隠しオブジェクト、検索バーを表示させるかを切り替える
'検索バーは一応表示固定(True)にしています
'https://answers.microsoft.com/en-us/msoffice/forum/msoffice_access-mso_winother-mso_2013_release/ms-access-navigation-pane/44fd5617-5096-4c58-9cf6-7545434e5a74
'[SetOption](https://docs.microsoft.com/ja-jp/office/vba/api/access.application.setoption)
'[Visual Basic を使用してオプションを設定する(記載されていない)](https://docs.microsoft.com/ja-jp/office/vba/access/concepts/settings/set-options-from-visual-basic)
Dim flag As Boolean
flag = Application.GetOption("Show System Objects")
Application.SetOption "Show System Objects", Not flag 'システムオブジェクトの表示 False 非表示 True 表示
Application.SetOption "Show Hidden Objects", Not flag '隠しオブジェクトの表示 False 非表示 True 表示
Application.SetOption "Show Navigation Pane Search Bar", True '検索バーの表示 False 非表示 True 表示
End Sub
```

###答え
答えは先ほどのリンク先に書いてある。
https://www.fmsinc.com/microsoftaccess/2007/search-bar/index.asp

答えは検索バー

```vb
Application.SetOption "Show Navigation Pane Search Bar", True
```

このオプションは表示と違うことを書く。確かに検索バーはたくさんありそうで、なんの検索バーかわからなくなる。
こういうSetOptionで使う場合、英語でも表示と異なる場合もあるようだ。


###公式は教えてくれない
そもそもそういうオプションすら記載されていないので、これはまずわからないと思う。

###Hide Object
テーブルをオプションから隠し属性にするか、以下のメソッドで隠し属性にすると、ナビゲーションペインのオプションによって表示されなくなる。
このため、空のテーブルを隠して、テーブルが壊れたら作り直す
郵便番号などを参照するためのテーブルなので編集されたくない。
という場合に設定する。

SetHiddenAttribute メソッド (Access)
https://docs.microsoft.com/ja-jp/office/vba/api/access.application.sethiddenattribute
Application.SetHiddenAttribute(ObjectType、 ObjectName、 fhidden)

SetHiddenAttribute メソッドは、Access オブジェクトの [隠しオブジェクト] 属性を設定します
名前 	必須 / オプション 	データ型 	説明
ObjectType 	必須 	AcObjectType 	Access オブジェクトの種類を、 Acobjecttypeクラスの定数で指定します。
ObjectName 	必須 	String 	Access オブジェクトの名前を指定します。
fHidden 	必須 	Boolean 	Trueに設定すると、隠し属性が設定され、 Falseの場合は属性がクリアされます。

```vb

Application.SetHiddenAttribute acTable,"Customers", True
```

このようにApplicationのメソッドを使う。

####GetHidden
https://docs.microsoft.com/ja-jp/office/vba/api/access.application.gethiddenattribute
Application.GetHiddenAttribute(ObjectType, ObjectName)
名前 	必須 / オプション 	データ型 	説明
ObjectType 	必須 	AcObjectType 	Access オブジェクトの種類を、 Acobjecttypeクラスの定数で指定します。
ObjectName 	必須 	String 	Access オブジェクトの名前を指定します。

####AcObjectType enumeration (Access)
Specifies the type of object.
例によって改善されない

Name 	Value 	Description
acDatabaseProperties 	11 	Database property
acDefault 	-1 	
acDiagram 	8 	Database Diagram (Microsoft Access project)
acForm 	2 	Form
acFunction 	10 	Function
acMacro 	4 	Macro
acModule 	5 	Module
acQuery 	1 	Query
acReport 	3 	Report
acServerView 	7 	Server View
acStoredProcedure 	9 	Stored Procedure (Microsoft Access project)
acTable 	0 	Table
acTableDataMacro 	12 	Data macro