[VBA:Access:]参照設定のDAO 3.6 とMicrosoft Office Access 12.0+ Libraryの違い

#Access2007 実はDAOが新バージョン。
http://isawseashell.blogspot.com/2007/02/attachment-dao-access2007-dao-dao-3.html
>2007/02/23
前回まででAttachment型を見ていってDAOのバージョンが上がっているという事がわかりました。このバージョンというのがちょっと微妙な感じで、明らかにマイナーレベルの数値が上がっても良いぐらいの拡張はされているのに、このAccess2007で採用されたDAOには正式なバージョン番号が付いていないようなんです。

上記のように、ライブラリ名称こそDAOですがその実態は、”Microsoft Office 12.0 Access database engine Object”となっています。略すならADEOとかでしょうか?


>ちなみにDAO3.6だはこんな感じでした。
>今回のDAOの拡張されたポイントですが、オブジェクトブラウザで見た限りオブジェクトで目に付いたのはRecrodset2とField2ぐらいです。Field2に関してはメゾッドして SaveToFileとLoadFromFileが、プロパティとしてComplexTypeとIsComplexが追加されています。Recordset2にはプロパティとしてParentRecordsetが追加されています。

>この他にも定数やEnumerate(列挙型)がいくつか追加されているようですが、大きくはやはり添付ファイル型・複数値型を扱う為の拡張であるこの辺りがメインだと思います。今後Multi-valued filed(複数値型)に関してもう少し突っ込んでみようと思いますが、添付ファイル型は複数値型の一形態なんだって事がここまで分かるかと思います。


この関数をAutoExecマクロを使用して起動時に自動実行させれば、エンドユーザーに操作を意識させることなく定期的なバックアップを実行できるでしょう。

###補足新バージョンはDao12ではなく、Dao.DBEngine.120
Die Suche hat 338 Ergebnisse ergeben.
http://www.office-loesung.de/viewprofileposts0_jensspeedy.php

```vb
Set objDBEngine = CreateObject("DAO.DBEngine.120")
Set objDBEngine = OpenDatabase("C:\z_vorlagen\zzz_db\Datenbank1.accdb")
Set objRS = objDBEngine.OpenRecordset("SELECT * FROM z_adressen " & _
"WHERE D010Nr=" & Nummer & " " ...
```
####Dao36は
http://www.dotnethell.it/forum/messages.aspx?ThreadID=45706

```vb
Dim Daox : SET Daox = CreateObject("DAO.DBEngine.36")
```

#たしかに公式にもAccess2007から追加されたものは記述がある
##ComplexType オブジェクト (DAO)
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/complextype-object-dao
    2015/09/18
適用先: Access 2013、Office 2013
複数値を持つフィールドを表します。
バージョン情報
追加されたバージョン: Access 2007 <:point_left:
注釈
ComplexTypeオブジェクトの***fields*** コレクションを取得するには、 fields プロパティを使用します。

##Field2 オブジェクト (DAO)
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/field2-object-dao
適用先: Access 2013、Office 2013

Field2 オブジェクトは、共通のデータ型およびプロパティの共通セットを持つ、データの列を表します。

###注釈

Field2 オブジェクトには、 Field オブジェクトと共通のすべてのプロパティおよびメソッドが含まれます。 Field2 オブジェクトには、複数値を持つフィールドの種類をサポートするいくつかの新しいプロパティおよびメソッドが含まれます。新しいプロパティおよびメソッドは次のとおりです。
<UL>
<li>AppendOnly プロパティ
<li>ComplexType プロパティ
<li>IsComplex プロパティ
<li>LoadFromFile メソッド
<li>[SaveToFile](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/field2-savetofile-method-dao) メソッド
</UL>

コレクション内で Field2 オブジェクトをそのインデックスまたはその Name プロパティの設定値によって参照するには、次のいずれかの構文形式を使用します。

Fields.0
Fields("name")
****!フィールド Tablename!FieldName [Table Name]![Field Name]

ユーザーが作成して Fields コレクションに追加する Field2 オブジェクトの Value プロパティを、同じ構文を使用して参照することもできます。フィールド参照のコンテキストにより、 Field2 オブジェクトと Field オブジェクトの Value プロパティのいずれを参照するかが決まります。
例

次の例は、複数値フィールドが含まれる Recordset 内を移動する方法を示します。

サンプル コードの提供元: Microsoft Access 2010 Programmer's Reference。

```vb
Sub PrintStudentsAndClasses()
        Dim dbs As DAO.Database
        Dim rsStudents As DAO.Recordset2  'Recordset for students
        Dim rsClasses As DAO.Recordset2  'Recordset for classes
        Dim fld As DAO.Field2
    
        'open the database
        Set dbs = CurrentDb()
    
        'get the table of students
        Set rsStudents = dbs.OpenRecordset("tblStudents")
    
        'loop through the students
        Do While Not rsStudents.EOF
            
            'get the classes field
            Set fld = rsStudents("Classes")
    
            'get the classes Recordset
            'make sure the field is a multi-valued field before
            'getting a Recordset object
            If fld.IsComplex Then
                Set rsClasses = fld.Value
            End If
    
            'access all records in the Recordset
            If Not (rsClasses.BOF And rsClasses.EOF) Then
                rsClasses.MoveLast
                rsClasses.MoveFirst
            End If
    
            'print the student and number of classes
            Debug.Print rsStudents("FirstName") & " " & rsStudents("LastName"), _
                "Number of classes: " & rsClasses.RecordCount
    
            'print the classes for this student
            Do While Not rsClasses.EOF
                Debug.Print , rsClasses("Value")
                rsClasses.MoveNext
            Loop
    
            'close the Classes Recordset
            rsClasses.Close
    
            'get the next student
            rsStudents.MoveNext
    
        Loop
        
        'cleanup
        rsStudents.Close
    
        Set fld = Nothing
        Set rsStudents = Nothing
        Set dbs = Nothing
    
    End Sub


次の例は、添付ファイル型フィールドに含まれるファイル内を移動する方法を示します。各添付ファイルのファイルの種類およびファイル名がイミディエイト ウィンドウに出力されます。
VB

    Sub ListAttachments()
        Dim dbs As DAO.Database
        Dim rst As DAO.Recordset2
        Dim rsA As DAO.Recordset2
        Dim fld As DAO.Field2
        
        'Get the database, recordset, and attachment field
        Set dbs = CurrentDb
        Set rst = dbs.OpenRecordset("tblAttachments")
        Set fld = rst("Attachments")
        
        'Navigate through the table
        Do While Not rst.EOF
        
            'Print the first and last name
            Debug.Print rst("FirstName") & " " & rst("LastName")
            
            'Get the recordset for the Attachments field
            Set rsA = fld.Value
            
            'Print all attachments in the field
            Do While Not rsA.EOF
                Debug.Print , rsA("FileType"), rsA("FileName")
                
                'Next attachment
                rsA.MoveNext
            Loop
            
            rsA.Close
            
            'Next record
            rst.MoveNext
        Loop
        
            
        rst.Close
        dbs.Close
        
        Set fld = Nothing
        Set rsA = Nothing
        Set rst = Nothing
        Set dbs = Nothing
    End Sub
```

次の例は、指定されたフォルダー パスから添付ファイル型フィールドにファイルを追加する方法を示します。

```vb
Public Function LoadAttachments(strPath As String, Optional strPattern As String = "*.*") As Long
        Dim dbs As DAO.Database
        Dim rst As DAO.Recordset2
        Dim rsA As DAO.Recordset2
        Dim fld  As DAO.Field2
        Dim strFile As String
        
        'Get the database, recordset, and attachment field
        Set dbs = CurrentDb
        Set rst = dbs.OpenRecordset("tblAttachments")
        Set fld = rst("Attachments")
        
        'Navigate through the table
        Do While Not rst.EOF
        
            'Get the recordset for the Attachments field
            Set rsA = fld.Value
            
            'Load all attachments in the specified directory
            strFile = Dir(strPath & "\*.*")
            
            rst.Edit
            Do While Len(strFile) > 0
                'Add a new attachment that matches the pattern.
                'Pass "" to match all files.
                If strFile Like strPattern Then
                    rsA.AddNew
                    rsA("FileData").LoadFromFile strPath & "\" & strFile
                    rsA.Update
                    
                    'Increment the number of files added
                    LoadAttachments = LoadAttachments + 1
                End If
                strFile = Dir
            Loop
            rsA.Close
            
            rst.Update
            'Next record
            rst.MoveNext
        Loop
        
        rst.Close
        dbs.Close
        
        Set fld = Nothing
        Set rsA = Nothing
        Set rst = Nothing
        Set dbs = Nothing
    End Function
```

次の例は、添付ファイル型フィールドに保管されているファイルを、指定されたフォルダー パスに保存する方法を示します。


```vb
Public Function SaveAttachments(strPath As String, Optional strPattern As String = "*.*") As Long
        Dim dbs As DAO.Database
        Dim rst As DAO.Recordset2
        Dim rsA As DAO.Recordset2
        Dim fld As DAO.Field2
        Dim strFullPath As String
        
        'Get the database, recordset, and attachment field
        Set dbs = CurrentDb
        Set rst = dbs.OpenRecordset("tblAttachments")
        Set fld = rst("Attachments")
        
        'Navigate through the table
        Do While Not rst.EOF
        
            'Get the recordset for the Attachments field
            Set rsA = fld.Value
            
            'Save all attachments in the field
            Do While Not rsA.EOF
                If rsA("FileName") Like strPattern Then
                    strFullPath = strPath & "\" & rsA("FileName")
                    
                    'Make sure the file does not exist and save
                    If Dir(strFullPath) = "" Then
                        rsA("FileData").SaveToFile strFullPath
                    End If
                    
                    'Increment the number of files saved
                    SaveAttachments = SaveAttachments + 1
                End If
                
                'Next attachment
                rsA.MoveNext
            Loop
            rsA.Close
            
            'Next record
            rst.MoveNext
        Loop
        
        rst.Close
        dbs.Close
        
        Set fld = Nothing
        Set rsA = Nothing
        Set rst = Nothing
        Set dbs = Nothing
    End Function
```

次の例は、添付ファイル型フィールドに保管されたファイルを削除する方法を示します。

```vb
Function RemoveAttachment(strRemoveFile As String, Optional strFilter As String) As Long
        Dim dbs As DAO.Database
        Dim rst As DAO.Recordset2
        Dim rsA As DAO.Recordset2
        Dim fld As DAO.Field2
        
        'Get the database
        Set dbs = CurrentDb
        
        'Open the recordset. If the strFilter is supplied, add it to the WHERE
        'clause for the recordset. Otherwise, any files matching strFileName
        'will be deleted
        If Len(strFilter) > 0 Then
            Set rst = dbs.OpenRecordset("SELECT * FROM tblAttachments WHERE " & strFilter)
        Else
            Set rst = dbs.OpenRecordset("tblAttachments")
        End If
        
        'Get the Attachment field
        Set fld = rst("Attachments")
        
        'Navigate through the recordset
        Do While Not rst.EOF
        
            'Get the recordset for the Attachments field
            Set rsA = fld.Value
            
            'Walk the attachments and look for the file name to remove
            Do While Not rsA.EOF
                If rsA("FileName") Like strRemoveFile Then
                    rsA.Delete
                    
                    'Increment the number of files removed
                    RemoveAttachment = RemoveAttachment + 1
                End If
                rsA.MoveNext
            Loop
                    
            'Cleanup the Attachments recordset
            rsA.Close
            Set rsA = Nothing
            
            'Next record
            rst.MoveNext
        Loop
        
        rst.Close
        dbs.Close
        Set fld = Nothing
        Set rst = Nothing
        Set dbs = Nothing
    End Function
```

##LoadFromFile メソッド (DAO)

    2015/09/18
    共同作成者
        office 365 dev account olprod 
適用先: Access 2013、Office 2013
指定されたファイルをディスクから読み込みます。
バージョン情報

追加されたバージョン: Access 2007
##DAO で添付ファイルを操作する
Docs Office VBA リファレンス >Access >概念 >データ アクセス オブジェクト (DAO) >DAO で添付ファイルを操作する 
https://docs.microsoft.com/ja-jp/office/vba/access/concepts/data-access-objects/work-with-attachments-in-dao
2018/09/21
DAO では、添付ファイル フィールドは他の複数値を持つフィールドとまったく同じように機能します。 添付ファイルを含むフィールドには、テーブルのレコードセットの子であるレコードセットが含まれます。 ***LoadFromFile*** と***SaveToFile*** という2つの新しい DAO メソッドがあり、添付ファイルのみを処理します。
添付ファイルをレコードに追加する

LoadFromFile メソッドはディスクからファイルを読み込み、そのファイルを添付ファイルとして指定されたレコードに追加します。 次のコード例は、LoadFromFile メソッドの構文を示しています。

```vb
Recordset.Fields("FileData").LoadFromFile(<filename>)
```

###注意:Filedataは予約語
FileData フィールドは、バイナリ添付ファイルデータを格納する目的で、Access データベース エンジンによって内部的に予約されています。
<以下リンク先コード参照>

##Version プロパティ (DAO)
https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/database-version-property-dao

|バージョン (リリース年)|Microsoft Access|
|:---|:---|
|4.0 (2000)|2000 (9.0)|
|12.0 (2007)|Access 2007|

##[AcFileFormat 列挙 (アクセス)](https://docs.microsoft.com/ja-jp/office/vba/api/access.acfileformat)
Access ファイルの変換時に使用する Microsoft Access のファイル形式を指定します。

追加された定数とはたとえばこのAcFileFormatのAccess2007形式であろう。
しかし2007以降は現在でも追加されていない。

名前 	値 	説明
acFileFormatAccess12 	12 	Microsoft Access 2007 形式
acFileFormatAccess2002 	10 	Microsoft Access 2002 形式
acFileFormatAccess2000 	9 	Microsoft Access 2000 形式
acFileFormatAccess97 	8 	Microsoft Access 97 形式
acFileFormatAccess95 	7 	Microsoft Access 95 形式
acFileFormatAccess2 	2 	Microsoft Access 2.0 形式

#上記サイトでは失われている図
[Access2010で作成したファイルを以前のバージョンで開いた場合のエラー 2011-09-29 09:00:29 パソコンカレッジ　スタッフのひとりごと](https://blog.goo.ne.jp/pc_college/m/201109)
ここが参考になる。具体的に後方互換させた場合に起きる現象の初歩的な参考事項もある。

##No104021.DAO3.6の参照設定について
この差は2007年には相当混乱をきたしたことがわかる

http://www.accessclub.jp/bbs3/0345/superbeg104021.html


```text
タイトル	： DAO3.6の参照設定について
記事No	： 104021
投稿日	： 2007/04/26(Thu) 17:50
投稿者	： セビル

    OS:WIN-XP
    Access Version:2007
    すみません、大変初歩的な質問なのですが・・・。

    Visual Basic Editor の ツール→参照設定で、
    Microsoft DAO 3.6 Object Library　を参照可能にしたいと思い、
    チェックをつけて、ＯＫボタンをクリックすると、
    「この名前は既にあるモジュール、プロジェクト、オブジェクト
    ライブラリで使われています」というメッセージがあらわれ、
    「ＯＫ」か「ヘルプ」かの選択肢しかなく、いずれを選んでも、
    また　ツール→参照設定の画面を見ると、チェックがはずれて
    しまっています。
    これにチェックを入れるには、どうしたら良いのでしょうか？

タイトル	： Re^4: DAO3.6の参照設定について
記事No	： 104044
投稿日	： 2007/04/27(Fri) 08:55
投稿者	： セビル

    おっ さん、ありがとうございます！

    > 今現在の状態で、DAOのオブジェクト等が使えるのでしたら、
    > 下記のページが参考になると思います。

    とても参考になりました。

    > 　Access2007 実はDAOが新バージョン。
    > 　http://isawseashell.blogspot.com/2007/02/attachment-dao-access2007-dao-dao-3.html

    別名で新バージョンだったんですね。
    今、やろうとして出来ない事が、ＤＡＯを参照設定出来ない事が原因だと思っていましたが、
    そうではないという事が解りましたので、ひとつ糸口が解けました。
    ありがとうございました。
```

##[DAO]新バージョンの違いに関する考察　/　2007年03月17日(土)
###編注
この記述は重要。魔界の仮面弁士のレベルは99Maxくらいなのでそのレベルでもこのバージョンアップがよくわからない。これはこの当時から現在に至るまでまともな情報をマイクロソフトが出していないことを示している。

>https://yaplog.jp/orator/archive/67
コミュニティでの活動の履歴として、自身(Orator/魔界の仮面弁士)が掲示板・Mailing List・Newsgroup等へ発言した内容の中で、再利用できそうな物を拾い出して、掲載しています。

>ようやく Office 2007 を入れたので、今更ながらに Jet 関連を調査。
いつの間にか、DAOのバージョンが大幅に上がっている事に吃驚。


>DAO 3.5 は、Access 97 で使われていて。
それ以降は、DAO 3.6 が Access 2000, 2002, 2003 と長らく使われていたのに。
それが Access 2007 では突然、DAO 12.0 となっている、と。

>そもそも、Microsoft Jet (Joint-Engine Technology) Database Engine 自体が、その後方互換たる ACE (Access Database Engine) に変更されている様子。


>とりあえず、表面的な部分だけ見れば、
　Set engine = CreateObject("DAO.DBEngine.35") 'JET 3.5x
　Set engine = CreateObject("DAO.DBEngine.36") 'JET 3.60
　Set engine = CreateObject("DAO.DBEngine.120") 'ACE 12.0
とか、
　Cn.Provider = "Microsoft.Jet.OLEDB.3.51" 'JET 3.5x
　Cn.Provider = "Microsoft.Jet.OLEDB.4.0" 'JET 3.60
　Cn.Provider = "Microsoft.ACE.OLEDB.12.0" 'ACE 12.0
とか、
　HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\3.5
　HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0
　HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine
という形で切り替えれば済むとは思うのだけれども、チューニング設定のためには、幾つか追調査の余地がありそう。


>たとえば、レジストリにある Engines エントリ。

>\Jet\4.0\Engines キーには、[Jet 2.x]、[Jet 3.x]、[Jet 4.0] のエントリが並んでいるのに、12.0 の方は、[Jet 2.x]、[Jet 3.x] のエントリが残っているのに、何故か [Jet 4.0] のエントリが用意されていない様子。([ACE] はあるのだけれども)

>「もしや、ACE エントリが Jet 4.0 の役目を持っているのか?」とも一瞬思ったのだけれども、その既定値を見ると、実は Jet 4.0 のそれとは微妙に異なっていた(※)ので、実験を重ねないと何とも言い難いところ。

>そうすると、DAO 12.0 で Jet 4.0 データベースを開くときの設定は、どこに書けばよいのだろう…。
まぁ、そういう時は DAO 3.6 を使い続ければ良いのだろうけれども。


>※具体的には、LV ページの再利用フラグ。JET 4.0 までは「オフ」がデフォルトだったのに、12.0 のデフォルトは「オン」にされている様子。