復刻 ADO入門講座 進捗1%

#ActiveX Data Object ： ADO入門講座
ADOは、OLE DBプロバイダを介してデータベースにアクセス（各アプリケーション間を繋ぐ架け橋の技術）するアプリケーションインターフェイスです。Access2000バージョンから登場し 、以前からあるDAOに替わるニューバージョンになります。
##目次
<OL>
<Li>アクティブXデータオブジェクトの概要
<Li>オブジェクトへの参照方法
<Li>オブジェクトの宣言と参照代入
<Li>カレントデータベースに接続する方法
<Li>カレント以外のデータベースに接続する方法
<Li>ADOの基本プログラミング
<Li>レコードセットの概要
<Li>ADOのレコードセットを開く - Openメソッド
<Li>Openメソッドにまつわる考察
<Li>編集可能なレコードセットを作成する
<Li>Supportメソッドの利用
<Li>BOFプロパティ、EOFプロパティの活用
<Li>カレントレコードの移動 - Move系メソッド
<Li>Bookmarkプロパティ
<Li>新規レコードを作成し単一フィールドに値を追加
<Li>新規レコードを作成し複数フィールドに値を追加
<Li>レコードを検索する - Findメソッド
<Li>レコードを検索する - Seekメソッド
<Li>レコードの削除 - Deleteメソッド
<Li>レコードの編集 - Updateメソッド
<Li>レコードの抽出 - Filterプロパティ
<Li>レコードの並び替え - Sortプロパティ
</OL>

##ADOリファレンス
<OL>
<Li>パラメータクエリをADOから実行する-CreateParameterメソッド
<Li>パラメータクエリをADOから実行する-Refreshメソッド
</OL>

##連絡事項
<UL>
<Li>記述内容及びサンプル画像は、Access2003を用いて行っています。
<Li>ADOは、Access2000以降のバージョンでのみ動作します。Access97以下のバージョンをお使いの方はご利用できません。
</UL>

ADOを利用すると、テーブルレコードを直接操作することができます。DAO（Data Access Object）と半ば共通の考え方もありますので、DAOに取り組まれた方は、 割りと簡単にADOの道程もこなされることでしょう。

####編注：補足
#####接続文字列の書き換え
Access2010以降の場合、以下のVBAのコードで

```vb
cn.ConnectionString = "provider=Microsoft.Jet.OLEDB.4.0;" _
                        & "Data Source=C:\Program Files\Sample.mdb"
```
こうした表記はAccess2010再頒布可能コンポーネントをインストール、もしくは最新のバージョンは付加情報に基づきQuietインストールの上、以下のように書き換えること。(QuietインストールはAccessが入っていることが前提。入っていない場合はインストール方法が異なります)

ファイル名は空白に備えて二重ダブルクォーテーションにすること。最後にセミコロンを入れること
ファイル名にはピリオドを使用しないこと。
`住所録.Pro01.mdb`は不可。エラーを起こす可能性が大。

```vb
    CN.ConnectionString = "Provider=Microsoft.ACE.OLEDB.16.0;" _
    & "Data Source=""F:\My Documents\住所録Pro01.mdb"";"
```

[Microsoft Access データベース エンジン 2010 再頒布可能コンポーネント ](https://www.microsoft.com/ja-jp/download/details.aspx?id=13255)
> このダウンロードを実行すると、Microsoft Office system 2010 ファイルと Microsoft Office アプリケーションとの間でデータを転送するのに使用できるコンポーネントがインストールされます。
説明: ここでは、複数のファイルの中から必要なものをダウンロードすることができます。 [ダウンロード] ボタンをクリックすると、一覧が表示されますので、必要なファイルを選んでください
バージョン:
SP2

|ファイル名|ファイル サイズ|
|:---------------------|:------------------------------------------------------------------------|
|AccessDatabaseEngine.exe|25.5 MB|
|AccessDatabaseEngine_X64.exe|27.5 MB|

><font color="RED">32 ビット版の Access データベース エンジンは、Windows XP Service Pack 3 でしか使用できません。 </font>

>公開日:2016/07/01

>このダウンロードを実行すると、Microsoft Office Access 2010 (*.mdb および *.accdb) ファイルや Microsoft Office Excel 2010 (*.xls、*.xlsx、および *.xlsb) ファイルなどの既存の Microsoft Office ファイルと、Microsoft SQL Server などの他のデータ ソースとの間のデータ転送を簡単に行うためのコンポーネントがインストールされます。既存のテキスト ファイルへの接続もサポートされています。 インストールされた ODBC ドライバーおよび OLEDB ドライバーは、アプリケーション開発者が Office ファイル形式に対応したアプリケーションを開発する際に利用できます。
 Access データベース エンジン 2010 再頒布可能コンポーネントは、以下の目的には使用できません。
<OL>
<Li>Jet の全般的な代替としての使用。Jet の全般的な代替が必要な場合は、SQL Server Express Edition (英語版) が必要です。
<Li>サーバー側アプリケーション内での Jet OLEDB プロバイダーとしての使用。
<Li>一般的なワード プロセッサ、スプレッドシート、またはデータベース管理システムとしての使用。 つまり、ファイル作成の手段としての使用。Microsoft Office または Office オートメーションを使うと、Microsoft Office でサポートされるファイルを作成することができます。
<Li>システム サービスまたはサーバー側プログラム (コードがシステム アカウントの下で実行されるもの、複数のユーザー ID を同時に処理するもの、高度に再入可能で動作が不安定になるもの) による使用。これには、ユーザーがログインしていないときにタスク スケジューラーから実行されるプログラムや、ASP.NET などのサーバー側 Web アプリケーションから呼びだされるプログラム、COM+ サービスの元で実行される分散コンポーネントなどがあります。
</OL>
#####サポートされるオペレーティング システム
Windows 7, Windows 8, Windows Server 2003 R2 (32-Bit x86), Windows Server 2003 R2 x64 editions, Windows Server 2008 R2, Windows Server 2008 Service Pack 2, Windows Server 2012 R2, Windows Vista Service Pack 1, Windows XP Service Pack 3

>※当然Windows10もサポートされないだけで稼働する
注: このダウンロードをインストールする前に、コントロール パネルの [プログラムの追加と削除] を使用して、Access データベース エンジンの以前のバージョンをコンピューターからすべて削除しておく必要があります。

>#####インストール手順:
<OL>
<Li>[ダウンロード] ボタンをクリックしてファイルをダウンロードし、ハード ディスクに保存します。
<Li>ハード ディスクにダウンロードした AccessDatabaseEngine.exe をダブルクリックすると、セットアップ プログラムが起動します。
<Li>画面に表示される指示に従って、インストールを完了します。
</OL>
>#####使用方法:

<OL>
<Li>アプリケーションのユーザー: 目的のドライバーを使用する方法については、アプリケーションのドキュメントを参照してください。
<Li>OLEDB を使用するアプリケーション開発者: ConnectionString プロパティのプロバイダー引数を "Microsoft.ACE.OLEDB.12.0" に設定します。
<Li>Microsoft Office Excel データに接続する場合は、Excel ファイル形式に基づいて OLEDB 接続文字列の適切な拡張プロパティを追加します 
</OL>

|ファイル形式 (拡張子)|拡張プロパティ| 
|:---------------------|:----------------------------------------------------| 
|Excel 97-2003 ブック (.xls)|  "Excel 8.0"|
|Excel 2007-2010 ブック (.xlsx)| "Excel 12.0 Xml"|
|Excel 2007-2010 マクロ有効ブック (.xlsm) | "Excel 12.0 Macro"|
|Excel 2007-2010 XML 以外のバイナリ ブック (.xlsb)|"Excel 12.0"|

> 4. ODBC を使用して Microsoft Office Access データに接続するアプリケーション開発者: 接続文字列を "Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=path to mdb/accdb file" に設定します。
 5. ODBC を使用して Microsoft Office Excel データに接続するアプリケーション開発者: 接続文字列を "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=path to xls/xlsx/xlsm/xlsb file" に設定します。
</OL>

>#####アンインストール手順:

<OL>このダウンロード ファイルを削除するには、AccessDatabaseEngine.exe ファイルを削除します。
<Li>[スタート] ボタンをクリックし、[コントロール パネル] をクリックします (クラシック [スタート] メニューでは、[スタート] ボタンをクリックし、[設定] をポイントして [コントロール パネル] をクリックします)。
<Li>[プログラムの追加と削除] をダブルクリックします。
<Li>現在インストールされているプログラムの一覧で [Microsoft Access database engine 2010] をクリックし、[削除] または [変更] をクリックします。ダイアログ ボックスが表示されたら、画面に表示される指示に従ってプログラムを削除します。
<Li>プログラムの削除を確認するメッセージが表示されたら、[はい] または [OK] をクリックします。
</OL>
>#####Office system ドライバーは、以下を含む特定のシナリオ下でのみ、使用がサポートされています。
>
<UL>
<Li>Microsoft Office Access、Microsoft Office Excel、およびテキスト ファイルを含む各種ファイル形式の読み書きを行うデスクトップ アプリケーション。
<Li>サポートされているファイル形式と SQL Server のようなデータベース リポジトリとの間でのデータの転送。たとえば、Excel ワークブックから SQL Server へ、SQL Server インポートおよびエクスポート ウィザードまたは SQL Server Integration Services を使用してデータを転送します (SSIS ジョブの実行は、ログオンしたユーザーが有効な HKEY_CURRENT_USER レジストリ ハイブを持っている場合)。
</UL>

[【SQLServer】（自己責任で）32bitOffice環境で64bitMicrosoft.ACE.OLEDB.12.0プロバイダを導入する方法。](http://plus-sys.jugem.jp/?eid=446%5D)
下記のAce16が出るまではこういう裏技も必要だった。

[Microsoft Access Database Engine 2016 Redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=54920)
>#####Supported Operating System
<font color="red">Windows 10</font> , Windows 7, Windows 8, Windows 8.1, Windows Server 2008 R2, Windows Server 2012, Windows Server 2012 R2
Windows 10, Windows 8.1, Windows 8, Windows 7 Service Pack 1, Windows 10 Server, Windows Server 2012 R2, Windows Server 2012, or Windows Server 2008 R2 

>注：このダウンロードをインストールする前に、まずコントロールパネルの[プログラムの追加と削除]を使用して、以前のバージョンのAccessデータベースエンジンをコンピュータから削除する必要があります。
Office System Driversは、以下のような特定のシナリオでのみサポートされています。
<UL>
<li>Microsoft Office Access、Microsoft Office Excel、テキストファイルなど、さまざまなファイル形式の読み書きを行うデスクトップアプリケーション。
<LI>サポートされているファイル形式とSQL Serverなどのデータベースリポジトリとの間でデータを転送するため。 たとえば、SQL Serverインポート/エクスポートウィザードまたはSQL Server Integration Services（有効なHKEY_CURRENT_USERレジストリハイブを使用してログオンユーザーのコンテキストでSSISジョブを実行する場合）を使用して、ExcelブックからSQL Serverにデータを転送する場合などです。
</UL>

>Office 365が既にインストールされている場合、サイドバイサイド検出によりインストールが続行されません。 代わりに、コマンドラインからこれらのコンポーネントの/ quietインストールを実行してください。 これを行うには、目的のAccessDatabaseEngine.exeまたはAccessDatabaeEngine_x64.exeをPCにダウンロードし、管理コマンドプロンプトを開き、インストールパスを入力して、Ex：C：\ Files \ AccessDatabaseEngine.exe / quietと入力します。

[https://www.connectionstrings.com/](https://www.connectionstrings.com/)
接続文字列の具体例
公式サイトは非常にわかりづらい
[付録 A: プロバイダー](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/appendix-a-providers)
ここから
[Microsoft OLE DB Provider for Microsoft Jet](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/microsoft-ole-db-provider-for-microsoft-jet)
ところが、ここには下記で使う接続文字列の説明がない。
[Microsoft Access 2010 を使用したデータ プログラミング](https://docs.microsoft.com/ja-jp/previous-versions/office/ff965871(v=office.14)#microsoft-access-%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%B3%E3%81%AE%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3)


[“Unexpected error from external database driver (1). (Microsoft JET Database Engine)” after applying October security updates. - 2017/1018](https://blogs.msdn.microsoft.com/dataaccesstechnologies/2017/10/18/unexpected-error-from-external-database-driver-1-microsoft-jet-database-engine-after-applying-october-security-updates/)
このブログではUse Microsoft.ACE.OLEDB.12.0 or Microsoft.ACE.OLEDB.16.0: (Recommended)となっている。

[【なんとか解決】Microsoft.ACE.OLEDB.16.0 プロバイダーはローカルのコンピューターに登録されていません。2018.06.25　2019.02.08](https://you-1.tokyo/microsoft-ace-oledb-16-0/)
しかし依然としてインストールでトラブルが発生する。

#####VBAにおけるSQLとクエリにおけるSQL、ADOにおけるSQLの違いに注意する
[Access SQL: 基本的な概念、用語、および構文](https://support.office.com/ja-jp/article/access-sql-%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E6%A6%82%E5%BF%B5%E3%80%81%E7%94%A8%E8%AA%9E%E3%80%81%E3%81%8A%E3%82%88%E3%81%B3%E6%A7%8B%E6%96%87-444d0303-cde1-424e-9a74-e8dc3e460671)
[Access上のコード内で引用符(")と単引用符(')の使い分けについて](https://hatenachips.blog.fc2.com/blog-entry-508.html)
[同様にピリオドがある場合等はSQLの書き方が変わってくる。以前の記事](https://qiita.com/Q11Q/items/18f2f6c420475314b2b1)
[Access VBA:ADOでLike演算子を使用する場合のワイルドカード文字は”＊”ではなく”％”を使用する](https://selifelog.com/blog-entry-338.html)
[AccessとADOのワイルドカードは違う！](http://ivystar.jp/ms-office/access/wild-card-and-ado-access-is-different/)
ADOのワイルドカードはVBSと同様に'%'になるこれは公式が下記でまとめている。
[Access ワイルドカード文字リファレンス](https://support.office.com/ja-jp/article/Access-%E3%83%AF%E3%82%A4%E3%83%AB%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89%E6%96%87%E5%AD%97%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9-af00c501-7972-40ee-8889-e18abaad12d1)
[AccessのクエリをVBAのSQLに変換する方法 How To Tranform Query SQL to VBA SQL Code](https://qiita.com/Q11Q/items/12c45fb3394609f4b4f8)
[64bit版Windowsでの「Microsoft.Jet.OLEDB.4.0」について](https://qiita.com/yaju/items/86314412741deb806366)

> Access では、構造化照会言語 (SQL) の 2 つの規格である ANSI-89 と ANSI-92 がサポートされているため、2 つのワイルドカード文字セットがサポートされています。通常、Access データベース (.mdb ファイルおよび .accdb ファイル) に対してクエリを実行したり検索と置換の操作を実行したりするときは、ANSI-89 ワイルドカードを使用します。Access プロジェクト、つまり Microsoft SQL Server データベースに接続された Access ファイルに対してクエリを実行するときは、ANSI-92 ワイルドカードを使用します。Access プロジェクトでは、SQL Server で使用される規格に合わせて ANSI-92 規格が使用されます。
ただし、Access のその規則には例外もあります。次の表は、データの検索と置換に使用できるメソッドまたはツールと、各ツールで使用される既定の ANSI 規格についてまとめたものです。

#####SQLのLikeは単なるワイルドカードではない
[Like 抽出条件を使ってデータを探す](https://support.office.com/ja-jp/article/Like-%E6%8A%BD%E5%87%BA%E6%9D%A1%E4%BB%B6%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E6%8E%A2%E3%81%99-65b07c8a-b314-435a-8b48-2b911856d4f9)
[ワイルドカード文字の例](https://support.office.com/ja-jp/article/%E3%83%AF%E3%82%A4%E3%83%AB%E3%83%89%E3%82%AB%E3%83%BC%E3%83%89%E6%96%87%E5%AD%97%E3%81%AE%E4%BE%8B-939e153f-bd30-47e4-a763-61897c87b3f4)
`[a-z]`のような正規表現に近い使い方も可能。

#####ファイル名にドット/ピリオドを使用しない
[Accessデータベース作業の際使用すべきではない特殊文字](https://support.microsoft.com/ja-jp/help/826763/error-message-when-you-use-special-characters-in-access-databases)

#####Excelとの接続
[Office Space: ADO を使用して Excel ワークシートにクエリを実行する](https://docs.microsoft.com/ja-JP/previous-versions//ee692882(v=technet.10))[Archive](https://archive.fo/0ndQn#selection-801.0-801.107)

<UL>
<li>Excel 8.0 は実行しているバージョンの Excel ではなく、Excel へのアクセスに使用される ADO プロバイダを指します。プロバイダを Excel 8.0 のままにしておくことで、すべてがうまくいきます。
<li>ワークシートへのパスに空白が含まれていたらどうなるでしょう。空白は、テキスト ファイルを操作する ADO スクリプトで問題になる可能性があります。詳細については、Hey, Scripting Guy! のコラムを参照してください。この場合は、まったく問題がないので、次のようにファイル パス全体を空白なども一緒に記述します。
<li>コードの "HDR=Yes" は単にワークシートにヘッダー行があることを示しています。つまり、ワークシートにヘッダー行がなかったら、HDR には No を設定します。
</UL>

```vb

Do Until objRecordset.EOF 
    Wscript.Echo objRecordset.Fields.Item("Name"), _　
        objRecordset.Fields.Item("Number") 
    objRecordset.MoveNext　
Loop 
 
```
 
```vb
objConnection.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=C:\Scripts\Test.xls;" & _　 
        "Extended Properties=""Excel 8.0;HDR=Yes;"";" 
```

```vb

objRecordset.Open "Select * FROM [Sheet1$]", _
    objConnection, adOpenStatic, adLockOptimistic, adCmdText
'Select * FROM [Sheet1$] '標準的なSQLクエリ(選択クエリ)　
 
```

<UL>
<li>なぜ ADO を使用するのでしょう。その答えは、SQL クエリを使用すると、ワークシート内の情報のサブセットを簡単に返すことができるからです。そういうわけで、Excel ファイルにアクセスするには ADO を使用することをお勧めします。
<li>ワークシート名が角かっこで囲まれていること、および実際の名前 Sheet1 に $ が付加されていること
</UL>

[ADO.NETでExcelファイルに接続する](https://qiita.com/unarist/items/6cc35bb9fe502ced332f)
Office2010
`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\12.0\Access Connectivity Engine\Engines\Excel`
Office 2016 64bit
`HKLM:\SOFTWARE\Microsoft\Office\16.0\Access Connectivity Engine\Engines\ACE`
access Connectivity Engine\Enginesの詳しい公式の解説は
[概念>0 データベース エンジン ドライバー](https://docs.microsoft.com/ja-jp/office/vba/access/concepts/miscellaneous/0-database-engine-driver)[概念>5 データベース エンジン ドライバー (1/2)-access Connectivity Engine\Engines\Jet 3. x](https://docs.microsoft.com/ja-jp/office/vba/access/concepts/miscellaneous/5-database-engine-driver-1-of-2)[概念>5 データベース エンジン ドライバー (2/2)-microsoft Jet バージョン 2.5 Engine データベースドライバー](https://docs.microsoft.com/ja-jp/office/vba/access/concepts/miscellaneous/5-database-engine-driver-2-of-2)
が説明している。なお、1から4はなく、0の次は5である。この説明は読まなくていい。なぜなら接続文字列またはDAOのSetOption、およびSchema.iniでこのレジストリの値を一時的に変更することができるためである。

######レジストリには2種類ある
Excelやテキストの接続文字列はレジストリを一時的に変更するものだが、このレジストリは2か所に分かれている。EngenesとISAM Formatsである。
`\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\XX.0\Access Connectivity Engine\Engines\`
`\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\XX.0\Access Connectivity Engine\ISAM Formats\`

[ADO.NET入門記-027 (Excelに接続してデータを取得・追加・更新)(Excel,OleDb,HDR,Extended Properties,xlsx)](https://devlights.hatenablog.com/entry/20091116/p1)
[DAOでExcelデータを読み込みテキストボックスに表示　](http://hanatyan.sakura.ne.jp/vbhlp/dao_002.htm)
ここにあるシートが複数ある場合、シートの範囲を決める場合の方法は必読
上記のDistribustionの解説のExcelのバージョンによる接続文字列の違いは、Extended Propertiesに記載するもの
`"Extended Properties"="Excel 12.0;HDR=YES";`
HDR(FirestROWHasName)ヘッダー(列の見出しになる行があるかないか。)
######Excelドライバーの設定と接続文字列
[Microsoft Office Excel ドライバーの初期化](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/initializing-the-microsoft-excel-driver?tabs=office-2016)という公式の解説は実は接続文字列の解説だが、一般の解説におけるIMEXと説明が違う。IMEXはTextかMajrityTypeのどちらかとなっている。

######Excelの接続文字列におけるIMEXについて
IMEX(ImportMixedType) 列の中に数字と文字など違うデータ型が混在している場合、テキストとして解釈するか。省略すると自動的に判断。 Imex=1 テキスト　Imex=2 リンクモード IMEX=0はExport
組合せによる表示状態（※テキストボックスに表示した場合）

|　IMEXの値　　|　　HDR=NO 　　|　　　　HDR=YES|
|:------------:|:-----------|:--------------|
|　省略　　|　１行目を読込まない |　１行目を読込む|
|　　0 　　|　１行目を読込まない |　１行目を読込まない|
|　　1 　　|　１行目を読込まない |　１行目を読込む|
|　　2 　　|　１行目を読込まない |　１行目を読込む|

通常はHDR=Yes Imex=1を使う。これは混在している場合テキストとして解釈される。***(私見)Imex=1を入れない場合、MajorityTypeになるのだろう。***
このIMEXはレジストリをみると、テキスト形式の場合と意味が違うようにかいてあるが、結論から言うと同じ意味のようだ(修正)。
MaxScanRows(TypeGuessRows)読み込むときにその列(フィールド）を何行読んで判断するか。0-16が指定可能。ただし0は全行。標準は8
このExtended Propertiesはレジストリの設定を一時的に変更している。
[Microsoft Access データベース エンジン用の Windows レジストリ設定のカスタマイズ](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/customizing-windows-registry-settings-for-the-microsoft-access-database-engine)
[.NET>FrameworkData and Modeling in the .NET Framework>ADO.NET>Connection String Syntax](https://docs.microsoft.com/en-us/dotnet/framework/data/adonet/connection-string-syntax)
公式の発言も揺れているが

>Connecting to Excel
The Microsoft Jet provider is used to connect to an Excel workbook. In the following connection string, the Extended Properties keyword sets properties that are specific to Excel. "HDR=Yes;" indicates that the first row contains column names, not data, and "IMEX=1;" tells the driver to always read "intermixed" data columns as text.
「IMEX = 1」を示します。 常に "混在する"データ列をテキストとして読み込むようにドライバに指示します。

```vb
Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\MyExcel.xls;Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1""
```

#####Text(csv,txt)との接続
######Schema.iniの解説はどこか
[テキスト データ ソース ドライバーを初期化しています。](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/initializing-the-text-data-source-driver)このへんてこなタイトルのところにSchema.ini の説明がある。

#####AccessClub掲示板に関するヒント

>フォーラムは閉鎖されたようだがwww.accessclub.jp/bbs3/0001/のようにして過去ログを見ることは可能。

---
#012.BOFプロパティ、EOFプロパティの活用 ： ADO入門講座
DAOのRecordsetオブジェクトと同じく、ADOのRecordsetオブジェクトにもBOF プロパティ（Begin Of Fileの略）とEOF（End Of Fileの略）のプロパティが用意されています。
これらのプロパティは、レコードセットの移動範囲の中で境界を越えていないかどうかを調べるプロパティです。
###解説
以下に述べる特徴があります。
<UL><li>カレントレコードが最初のレコードより更に前に移動した場合、BOFプロパティはTrueの状態になります。</li><li>カレントレコードが最後のレコードより更に後ろに移動した場合、EOFプロパティはTrueの状態になります。</li><div>:close :BOF または EOFプロパティがTrueの状態である場合、カレントレコードは存在しないことになります。</div<li>レコードを持たないRecordsetを開くと、BOFプロパティと EOFプロパティはTrueの状態に設定されます。</li><li>
        少なくとも 1 つのレコードが格納された Recordsetオブジェクトを開くと、最初のレコードがカレントレコードになり、BOFプロパティとEOFプロパティはFalseの状態になります。
    Recordsetオブジェクトで最後に残ったレコードを削除しても、カレントレコードの位置を移動するまでBOFおよびEOFプロパティはFalseの状態のままです。

---
#013. カレントレコードの移動 - Move系メソッド ： ADO入門講座

レコードの操作とは、接続したレコードセットに対してメソッドなどを実行し対象となっているレコードの値を参照したり、削除、更新を行なうことをいいます。 ここでは、対象となっているレコードを前後左右に移動させるテクニックをご紹介します。
#####カレントレコード
Recordsetオブジェクト内のレコードは、必ず1つのレコードを参照されている状態になっています。この参照されているレコードのことをカレントレコードといいます。

:closed_book:レコードセットを取得した直後は、最初（先頭）のレコードがカレントレコードになります。

#####カレントレコードの移動

レコードセットを用いてテーブルレコードを操作することができます。しかし、この操作は1つのレコードであるカレントレコードのみの操作になりますので、全部、または特定のレコードを操作するにはカレントレコードを移動させる必要があります。

ADOでは、レコードセット内のカレントレコードを移動するのに、以下のメソッドを用います。
#####Move系メソッドの 構文
各メソッドとも、Recordsetオブジェクト + .（ドット） + Move系のメソッド の組み合わせになります。

|メソッド|利用方法|意味|
|:-----:|:-------|:------|
|MoveFirst|Recorsdet.MoveFirst|先頭（最初）のレコードに移動|
|MovePrevious|Recorsdet.MovePrevious|1つ前のレコードに移動|
|MoveNext|Recorsdet.MoveNext|次のレコードに移動|
|MoveLast|Recorsdet.MoveLast|最後のレコードに移動|

/＊Recordsetは、開いているRecordsetオブジェクトのことです。

######補足

:zap:これらMove系のメソッドは、BOFまたはEOFプロパティと共に利用されるケースが多いです。
:zap:これらMove系のメソッドは、レコードの編集、削除といった操作を行なう際にカレントレコードを移動させる手段として利用されます。

#####売上げ管理テーブルの作成

以下のようなサンプルテーブルを作成します。

売上日 	社員名 	性別 	売上額 	職種
2004/01/23 	橘　修平 	男性 	52100 	一般職
2004/02/04 	柴田 喜一 	男性 	654100 	技能職
2004/02/04 	柴田 喜一 	男性 	7892510 	技能職
2004/03/25 	正道　良一 	男性 	4875210 	薬剤師
2004/04/30 	田中　邦子 	女性 	785100 	一般職
2004/04/30 	田中　邦子 	女性 	4789210 	一般職
2004/07/29 	草薙　良子 	女性 	120310 	医師
2004/08/10 	田中　幸恵 	女性 	7986620 	一般職
2004/09/30 	中村　幸三 	男性 	477123 	技能職
Subプロシージャの作成

MoveNextメソッドを用いて、先頭レコードから最後のレコードまでカレントレコードを移動させていきます。

```vb
Sub ADORecordsetMoveNext()

    Dim cn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Set cn = CurrentProject.Connection
    Set rs = New ADODB.Recordset
    
    rs.Open "T_売り上げ管理", cn, adOpenKeyset, adLockOptimistic
    
    Do Until rs.EOF ' --- A
        Debug.Print rs!売上日, rs!社員名, rs!性別, rs!売上額
        rs.MoveNext ' --- B
    Loop
    
    rs.MoveFirst ' --- C
    Debug.Print rs!売上日, rs!社員名, rs!性別, rs!売上額

    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">解説</font>


    EOFプロパティを用いて先頭のレコードから最後のレコードまでを対象にします。
    MoveNextメソッドを用いて、次のレコードにカレントレコードを移動させていきます。
    Loop処理を抜けると、先頭レコードにカレントレコードを移動させます。

###<font color="Bronwn">実行結果</font>

イミディエイト画面上で実行すると、下記のレコードが表示されます。EOF、FOFプロパティを用いた後はカレントレコードが未定義の状態になるので、MoveFirstメソッドで先頭レコードに移動させています。

###関連ページ
BOFプロパティ、EOFプロパティの活用 ： ADO入門講座
2004/09/10

---
#014. Bookmarkプロパティ ： ADO入門講座
Recordsetオブジェクトを作成すると、各レコードには固有の識別コードが付与され、この識別コードがブックマークと呼ばれます。
###<font color="RED">留意点</font>
<UL>
<Li>Bookmarkプロパティは、Recordsetオブジェクトで管理されています。
<Li>Bookmarkプロパティは、値の代入、値の参照が可能です。
<Li>Bookmarkプロパティのデータ型は、バリアント型（Variant）になります。
<Li>Bookmarkプロパティを利用すると、元のレコードに戻ることが可能です。
<Li>このことからも、日本語で「しおり」と訳されます。
</UL>
#####構文
$\style{background-color:DodgerBlue;}{AddNewメソッドの構文}$

```vb
Recordsetオブジェクト + .（ドット） + Bookmarkプロパティ = Value の組み合わせになります。
```

|項目|意味|
|:--:|:------|
|Recordsetオブジェクト|	開いているRecordsetオブジェクト|
|Value|ブックマーク|

補足
<UL>
<Li>Bookmarkプロパティの使い方は、プロシージャ内で該当レコードのBookmarkを保存します。
<Li>保存したBookmarkをBookmarkプロパティに代入することで、カレントレコードを該当レコードに移動せることができます。
</UL>
#####売上げ管理テーブルの作成

以下のようなサンプルテーブルを作成します。

|売上日|社員名|性別|売上額|職種|
|:------:|:----:|:-----:|-----:|:-----:|
|2004/01/23|橘　修平|男性|52100|一般職|
|2004/02/04|柴田 喜一|男性|654100|技能職|
|2004/02/04|柴田 喜一|男性|7892510|技能職|
|2004/03/25|正道　良一|男性|4875210|薬剤師|
|2004/04/30|田中　邦子|女性|785100|一般職|
|2004/04/30|田中　邦子|女性|4789210|一般職|
|2004/07/29|草薙　良子|女性|120310|医師|
|2004/08/10|田中　幸恵|女性|7986620|一般職|
|2004/09/30|中村　幸三|男性|477123|技能職|


#####Subプロシージャの作成

先頭のレコードデータをBookMarkプロパティを用いて変数に保存します。

```vb
Sub ADORecordsetBookmark()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim varBM As Variant
Dim mySQL As String

Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

mySQL = "SELECT 売上げ管理.* FROM 売上げ管理 " _
& "ORDER BY 売上額 DESC;" ' --- A

rs.Open mySQL, cn, adOpenKeyset, adLockOptimistic
varBM = rs.Bookmark ' --- B

Debug.Print "売上げ一覧表"
Do Until rs.EOF
Debug.Print rs!売上日, rs!社員名, rs!性別, rs!売上額
rs.MoveNext
Loop

rs.MovePrevious ' --- C
rs.Bookmark = varBM ' --- D
Debug.Print "No1の売上げ、" & rs!売上日 & "の" & _
 rs!売上額 & "円です。"

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">解説</font>

A.売上額フィールドの降順に並び替えた選択クエリのSQLを定義します。
B.Bookmarkプロパティを用いて先頭レコード（カレントレコード）を登録します。
C.EOFプロパティがFalseに一旦変化したので、カレントレコードを有効にしています。
D.登録してある、Bookmarkプロパティから値を引き出します。

###<font color="Bronwn">実行結果</font>

イミディエイト画面上で実行すると、下記のレコードが表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/1762e1fe-b70a-285a-b9d2-043271206d49.png)

$\style{background-color:DodgerBlue;}{関連ページ}$
<uL>
<Li>BOFプロパティ、EOFプロパティの活用 ： ADO入門講座
</UL>

\2004/09/10

---
#015. 新規レコードを作成し単一フィールドに値を追加 - AddNewメソッド ： ADO入門講座
http://accessclub.jp/ado/15.html

レコードセットを用いて、新規レコードをテーブルに追加することができます。この場合は、RecordsetオブジェクトのAddNewメソッドを用います。

###<font color="RED">留意点</font>
<UL>
<Li>AddNewメソッドを実行した後は、そのレコードがカレントレコードになります。
<Li>開いているRecordsetオブジェクトのLockTypeプロパティの値がadLockReadOnlyの場合は、新しいレコードを追加できません。
</UL>

#####構文
$\style{background-color:DodgerBlue;}{AddNewメソッドの構文}$

AddNewメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + AddNewメソッド  + Fields + ,（カンマ） + Values
```

|項目|意味|
|:--|:------|
|Recordsetオブジェクト |開いているRecordsetオブジェクト|
|Fields|レコードを追加するフィールド名|
|Value|	代入する値|

###<font color="Bronwn">解説</font>
<UL>
<Li>代入する値がテキスト型の場合は、ダブルクォーション（"）で囲みます。
<Li>代入する値が日付/時刻型の場合は、シャープ（#）で囲みます。
<Li>代入する値が数値の場合は、そのまま記述します。
</UL>
$\style{background-color:DodgerBlue;}{単一フィールドに値を追加する}$

AddNewメソッドを用いる際に、以下の注意点があります。

<UL>
<Li>複数のフィールドを持っているテーブルであっても、1つのフィールドに1つの値のみしか追加できません。
<Li>複数のフィールドで、Nullを許可しない設定（値要求をはい）になっている場合はエラーが発生します。これを回避するには、何かしらの値を代入するしか手がありません。
</UL>

具体的な検証

この注意点を具体的に検証していきましょう。AddNewメソッドを用いて、新規レコードを追加します。以下のテーブルレコードを想定します。

1. 売上日フィールドに2004/12/31を代入します。 <br> 
 ・AddNewメソッドは、1つのフィールドに1つの値しか追加できない決まりがあります。

#####サンプルテーブル

|売上日|社員名|性別 |売上額|職種|
|:------:|:----|:-----:|:----|:------|
|2004/01/23 |橘　修平|男性|52100|一般職|
|2004/02/02|柴田 喜一|男性|654100|技能職|
|2004/12/31 |　|  |  |  |
　 	　 	　
#####Subプロシージャの作成

全ての複数フィールドでNullを許可している場合は、以下のようなサンプルプロシージャを作成します。

```vb
Sub ADORecordsetAddNew()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim varBM As Variant
Dim mySQL As String

Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_sample", cn, adOpenKeyset, adLockOptimistic
rs.AddNew "売上日", #12/31/2004#

Debug.Print "追加レコード一覧" 'ここから
Do Until rs.EOF
Debug.Print rs!売上日, rs!社員名, rs!性別, rs!売上額
rs.MoveNext
Loop　'ここまでが表示させるプログラミングです。

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">実行結果</font>

このプロシージャをイミディエイト画面上で実行すると、以下のレコードがイミディエイト画面に表示されます。

```vb

ADORecordsetAddNew '実行する
```
追加レコード一覧
|`2004/12/31`|`Null`|`Null`|`Null`|

####事例

フィールド名 社員名 のプロパティを以下に変更して、プロシージャ ADORecordsetAddNew を実行する。
<UL>
<Li>値要求 →　なし
<Li>空文字列の許可 → なし
<Li>インデックス → はい (重複なし)
</UL>
追加レコード一覧
2004/12/31|Null|  Null|  Null

<Li>値要求 →　あり
<Li>空文字列の許可 → なし
<Li>インデックス → はい (重複なし)

下図のエラーメッセージが表示され、AddNewメソッドを実行できません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/330af85d-4d42-75cc-e801-196e2f3d110c.png)

社員名フィールドに何がしかの値を代入する必要があります。ここで、以下のようにプロシージャを変更してみましょう。

```vb
Sub ADORecordsetAddNew()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim varBM As Variant
Dim mySQL As String

Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_sample", cn, adOpenKeyset, adLockOptimistic
rs.AddNew "売上日", #12/31/2004#
rs.AddNew "社員名", "松井雄二"

Debug.Print "追加レコード一覧"
Do Until rs.EOF
Debug.Print rs!売上日, rs!社員名, rs!性別, rs!売上額
rs.MoveNext
Loop

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">解説</font>

売上日フィールドに続いて、社員名フィールドにもAddNewメソッドを用いて文字列を代入する構文です。

```vb
rs.AddNew "売上日", #12/31/2004#
rs.AddNew "社員名", "松井雄二"
```

###<font color="Bronwn">実行結果</font>

このプロシージャをイミディエイト画面上で実行すると、以下の結果を得ることができます。

```vb
?ADORecordsetAddNew '実行する
```

追加レコード一覧
|`Null`|`松井雄二`|`Null`|`Null`|

売上日フィールドに代入した値が消えてなくなっています。Recordset.AddNew構文では、追加できるフィールドは1つに限定されることが証明されたわけです。
####<font color="Bronwn">対策</font>

AddNewメソッドを用いて複数フィールドに値を代入する場合は、Updateメソッドを組み合わせる必要があります。詳細は、次頁を参照してください。
$\style{background-color:DodgerBlue;}{関連ページ}$
<UL>
<Li>新規レコードを作成し複数フィールドに値を追加 - AddNewメソッド ： ADO入門講座
</UL>

/2004/12/31

---
#16.新規レコードを作成し複数フィールドに値を追加 - AddNewメソッド ： ADO入門講座
http://accessclub.jp/ado/16.html

前頁では、単一のフィールドにデータを追加するAddNewメソッドをご紹介しました。今回は、新規レコードを作成し同時に複数のフィールドにデータを追加する方法をご紹介します。ポイントは、AddNewメソッドとUpdateメソッドを組み合わせることです。
###<font color="RED">留意点</font>
<UL>
<Li>AddNewメソッドを実行した後は、そのレコードがカレントレコードになります。
<Li>開いているRecordsetオブジェクトのLockTypeプロパティの値がadLockReadOnlyの場合は、新しいレコードを追加できません。
<Li>Updateメソッドを実行しないと、レコードが追加されません。
</UL>
$\style{background-color:DodgerBlue;}{AddNewメソッドの構文}$

AddNewメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + AddNewメソッド
```

|項目|意味|
|:--:|:------|
|Recordsetオブジェクト|開いているRecordsetオブジェクト|

###<font color="Bronwn">解説</font>
<UL>
<Li>Updateメソッドと共に使用する場合、引数は不要です。
</UL>
$\style{background-color:DodgerBlue;}{Updateメソッドの構文}$

Updateメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + Updateメソッド
```

|項目|意味|
|:--:|:------|
|Recordsetオブジェクト|開いているRecordsetオブジェクト|

###<font color="Bronwn">解説</font>
<UL>
<Li>AddNewメソッドと共に使用する場合、引数は不要です。
</UL>
$\style{background-color:DodgerBlue;}{複数フィールドに値を追加する}$

#####サンプルテーブル
サンプルテーブルを以下のように仮定します。
サンプルテーブル

|売上日|社員名|性別|売上額|職種|
|2004/01/23|橘　修平|男性|52100|一般職|
|2004/02/02|柴田 喜一|男性|654100|技能職|
|2004/12/31|　|　|　|　|


$\style{background-color:DodgerBlue;}{Subプロシージャの作成}$

全ての複数フィールドでNullを許可している場合は、以下のようなサンプルプロシージャを作成します。 このプロシージャを実行すると、T_sampleテーブルに新規レコードが追加され、各フィールドに設定した値が代入されます。

```vb

Sub ADORecordsetAddNew()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim varBM As Variant
Dim mySQL As String

Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_sample", cn, adOpenKeyset, adLockOptimistic
rs.AddNew
rs!売上日 = Date 'Date関数で本日の日付を代入します。
rs!社員名 = "町田純一"
rs!性別 = "男性"
rs!売上額 = 144200
rs.Update

Debug.Print "追加レコード一覧"
Do Until rs.EOF '追加レコードを表示します。
Debug.Print rs!売上日, rs!社員名, rs!性別, rs!売上額
rs.MoveNext
Loop

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">実行結果</font>

このプロシージャをイミディエイト画面上で実行すると、以下のレコードがイミディエイト画面に表示されます。

ADORecordsetAddNew '実行する

追加レコード一覧

2005/01/01 町田純一　男性　144200 

$\style{background-color:DodgerBlue;}{ちょっと一服}$

####<font color="Bronwn">質問</font>

イミディエイト画面に追加したフィールドだけが表示されるのは何故か、分かりますか?
####<font color="Bronwn">回答</font>

AddNewメソッドを実行すると、新規レコードは一番最後に追加されます。そして、このレコードがカレントレコードになります。よって、このレコードの後ろには既存のレコードがないので、表示されるのは追加されたレコードのみになる訳です。
####<font color="Bronwn">対策</font>

全てのレコードデータを表示させたい場合は、以下のようにrs.MoveFirstの一行を追加します。

```vb
rs.Open "T_sample", cn, adOpenKeyset, adLockOptimistic
rs.AddNew
rs!売上日 = Date 'Date関数で本日の日付を代入します。
rs!社員名 = "町田純一"
rs!性別 = "男性"
rs!売上額 = 144200
rs.Update

rs.MoveFirst

Debug.Print "追加レコード一覧" 'ここから
Do Until rs.EOF '追加レコードを表示します。
Debug.Print rs!売上日, rs!社員名, rs!性別, rs!売上額
rs.MoveNext
Loop
```

$\style{background-color:DodgerBlue;}{関連ページ}$
<uL>
<li>編集可能なレコードセットを作成する - Updateメソッド： ADO入門講座
<li>新規レコードを作成し単一フィールドに値を追加 - AddNewメソッド ： ADO入門講座
</UL>

\2005/01/01
---
#17.レコードを検索する - Findメソッド ： ADO入門講座
http://www.accessclub.jp/ado/17.html

Findメソッドは、指定した条件に一致するレコードを検索し、そのレコードをカレントレコードにします。しかし、カレントレコードに対する操作は全く行いません。 また、Do～Loopを用いて複数のレコードを求めることも可能です。

###<font color="RED">留意点</font>
<UL>
<Li>Findメソッドを呼び出す前にカレント行の位置が設定されていない場合は、エラーが発生します。この場合は、Findメソッドを呼び出す前に、Move系メソッドなどで行を特定していなくてはいけません。
<Li>Findメソッドを実行し該当レコードが見つかった場合、そのレコードがカレントレコードになります。
<Li>該当レコードが見つからなかった場合、RecordsetオブジェクトのBOF、またはEOFが未定義の状態になります。
</UL>

#####構文
$\style{background-color:DodgerBlue;}{Findメソッドの構文}$

Findメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + Findメソッド+ ,（カンマ） + 検索条件+ ,（カンマ） + SkipRows+ ,（カンマ） +SearchDirection+ ,（カンマ） +Stat+ ,（カンマ） +
```
|項目|意味|
|:--:|:------|
|Recordsetオブジェクト |開いているRecordsetオブジェクト|
|検索条件 |検索に使用するフィールド、比較演算子、文字列式など</LI>
|SkipRows |省略可能です。<br> 検索を開始する、カレント行または Start ブックマークからの行のオフセットを指定する長整数型 の値を指定します。|
|SearchDirection| 既定値は 0 です。既定では、カレント行から検索が開始されます。 <br> <UL> <Li>adSearchForwardを指定した場合</LI> <Li>検索に成功しなかった時、Recordset の終わりで停止します。</LI> <Li>adSearchBackwardを指定した場合</LI><Li>検索に成功しなかった時、Recordset の先頭で停止します。</LI></UL> |
|Stat|省略可能です。<br>検索の開始位置として使用するバリアント型 (Variant) のブックマークを指定します。 |

#####サンプルテーブル
$\style{background-color:DodgerBlue;}{サンプルテーブルの作成}$
サンプルテーブルを以下のように作成します。テーブル名は、T_sampleテーブルです。
編注：このテーブルはID列がない。

|売上日|社員名|性別|売上額|
|:------|:------|:------|------:|
|2004/01/23|橘 修平|男性 |52100|
|2004/01/29|橋本 佳代 |女性|151100|
|2004/02/02|柴田 喜一|男性|654100|

$\style{background-color:DodgerBlue;}{単一レコードを求めるFindメソッドの作成}$

このプロシージャは、T_Sampleテーブルから社員名が「柴田喜一」のレコードをFindメソッドを用いて求め、イミディエイトウィンドウに表示します。

```vb
Sub ADO_Find()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim varBM As Variant
Dim mySQL As String
Dim strcriteria As String

Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_sample", cn, adOpenKeyset, adLockOptimistic

'検索条件を変数に代入します。
strcriteria = "社員名 = '柴田 喜一'" ' --- A
rs.Find strcriteria, 0, adSearchForward

If rs.EOF Then ' --- B
MsgBox "該当レコードが見つかりません"
Else
Debug.Print "社員名 ： " & rs!社員名 & "、売上額 ： \" & rs!売上額
End If

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```
###<font color="Bronwn">解説</font>

A.検索式は、フィールド名 = 文字列 Or 数値 Or 日時 の形式をとります。検索式を"（ダブルクォーション）で囲む必要があります。また、文字列は'（シングルクォーション）、日時は#（シャープ）で併せて囲みます。
B.該当レコードがない場合は、EOF及びBOFがTrueになります。
###<font color="Bronwn">実行結果</font>

このプロシージャをイミディエイト画面上で実行すると、以下のレコードが表示されます。

ADO_Find '実行する
社員名 ： 柴田 喜一、売上額 ： \52100

$\style{background-color:DodgerBlue;}{複数レコードを求めるFindメソッドの作成}$

このプロシージャは、T_Sampleテーブルから性別が「男性」のレコード全てをFindメソッドを用いて求め、イミディエイトウィンドウに表示します。

```vb
Sub ADO_Find2()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim varBM As Variant
Dim mySQL As String
Dim strcriteria As String

Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_sample", cn, adOpenKeyset, adLockOptimistic

'検索条件を変数に代入します。
strcriteria = "性別 = '男性'"
rs.Find strcriteria, 0, adSearchForward

Do Until rs.EOF

	If rs.EOF Then
	MsgBox "該当レコードが見つかりません"
	Else
	Debug.Print "社員名 ： " & rs!社員名 & "、売上額 ： \" & rs!売上額
	rs.Find strcriteria, adSearchForward ' --- A
	End If

Loop

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">解説</font>

A.Findメソッドの引数にadSearchForwardを指定することで、次々と条件に合致するレコードを検索していきます。

###<font color="Bronwn">実行結果</font>

このプロシージャをイミディエイト画面上で実行すると、以下のレコードが表示されます。

ADO_Find2 '実行する
社員名 ： 柴田 喜一、売上額 ： \52100
社員名 ： 柴田 喜一、売上額 ： \654100

$\style{background-color:DodgerBlue;}{ちょっと一服}$

####<font color="Bronwn">DAO</font>

DAO には 4 つの検索メソッドである FindFirst、FindLast、 FindNext、及び FindPrevious があります。先頭レコード、最終レコード、または現在レコードのどこから検索を開始するか、前方、後方のどちらに向かって検索するかに基づいて、使用するメソッドを選択することができます。

####<font color="Bronwn">ADO</font>

ADO には 1 つのメソッド Find だけしかありません。検索は、常に現在レコード（カレントレコードではありません）から開始されます。Find メソッドは、検索方向と検索を開始する現在レコードからのオフセット (SkipRows) を指定できるパラメータを持っています。

####<font color="Bronwn">DAOとADOの対比表</font>

次の表は 4 つの DAO のメソッドに相当する ADO の機能を示しています。

|DAO メソッド|ADO Findの <br> SkipRows |ADO 検索方向|
|:-----|:---:|:-----------|
|FindFirst|0|adSearchForward|
|FindLast|0|adSearchBackward|
|FindNext|1|adSearchForward|
|FindPrevious|1|adSearchBackward|

$\style{background-color:DodgerBlue;}{関連ページ}$
<UL>
<li>カレントレコードの検索_テーブルタイプ ： DAO入門講座
<li>カレントレコードの検索_スナップ、ダイナセットタイプ ： DAO入門講座
</UL>
2005/02/16
レコードを検索する - Findメソッド ： ADO入門講座
-Microsoft Access Club-
---
#018.レコードを検索する - Seekメソッド ： ADO入門講座
Seekメソッドは、Findメソッドと同じく指定した条件に一致するレコードを検索し ます。Findメソッドとの相違点は、<b>検索するテーブルフィールドにインデックスが設定されていること</b>が条件になります。
###<font color="RED">留意点</font>
<UL>
<li>RecordsetオブジェクトのOpenメソッドの引数OptionにadCmdTabledirectを指定する必要があります。
<li>検索方法を事前に指定することができます。
</UL>
[CommandTypeEnum コマンド引数の解釈方法を表します。](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/commandtypeenum)
[ExecuteOptionEnum プロバイダーによるコマンドの実行方法を表します。](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/executeoptionenum)

|定数|値|説明|
|:--:|:------:|:------|
|adCmdTableDirect|512|CommandTextを指定された列は、返されたすべてのテーブル名として評価します。 Recordset.OpenまたはRequeryとのみに使用します。 Seekメソッドを使用するには、 adCmdTableDirectにレコード セットを開く必要があります。 この値は、ExecuteOptionEnum の値 adAsyncExecute と組み合わせて使用できません。|
|adAsyncExecute|0x10|コマンドを非同期に実行することを示します。 この値は、CommandTypeEnum の値 adCmdTableDirect と組み合わせて使用できません。|

#####構文
$\style{background-color:DodgerBlue;}{Seekメソッドの構文}$

Seekメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + Seekメソッド+ （半角） + Keyvalues + ,（カンマ） + Seekoption
```

|項目|意味|
|:--:|:------|
|Recordsetオブジェクト|開いているRecordsetオブジェクトです。|
|Keyvalues|インデックスの各列と照合するための値を指定します。|
|Seekoption|インデックスの各列とそれに対応する KeyValues を比較するときの、比較の種類を SeekEnum 値で指定します|

####<font color="Bronwn">SeekEnum 値</font>

|定数|値|説明|
|:--:|:------:|:------|
|adSeekFirstEQ|1|KeyValues と一致する最初のキーを検索します。|
|adSeekLastEQ|2|KeyValues と一致する最後のキーを検索します。|
|adSeekAfterEQ|4|KeyValues と一致するキー、またはその直後のキーのどちらかを検索します。|
|adSeekAfter|8|KeyValues と一致するキーの直後のキーを検索します。|
|adSeekBeforeEQ|16|KeyValues と一致するキー、またはその直前のキーのどちらかを検索します。|
|adSeekBefore|32|KeyValues と一致するキーの直前のキーを検索します。|

[SeekEnum](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/seekenum)

$\style{background-color:DodgerBlue;}{サンプルテーブルの作成}$
#####サンプルテーブル
サンプルテーブルを以下のように作成します。テーブル名は、T_sampleテーブルです。

|ID|売上日|社員名|性別|売上額|
|:--:|:------|:------|:------|------:|
|6|2004/01/23|橘修平|男性|52100|
|1|2004/07/29|草薙良子|女性|120310|
|4|2004/04/30|中村静子|女性|785100|
|9|2004/04/30|田中邦子|女性|4789210|

$\style{background-color:DodgerBlue;}{テーブルのデザインビュー}$

テーブルのデザインビューは以下のようになっています。主キーは社員名フィールドに設定しています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/ec5f22d0-6931-0949-8b7e-a0b894e6f402.png)

$\style{background-color:DodgerBlue;}{Seekメソッドを用いた検索方法}$

このプロシージャは、T_Sampleテーブルから社員名が「田中邦子」のレコードをSeekメソッドを用いて求め、メッセージボックスに表示します。

```vb
Sub ADO_Seek()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim vardat As Variant
Dim strmsg As String
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic, adCmdTableDirect

vardat = InputBox("検索する社員名を入力して下さい。") ' --- A
If vardat = "" Then Exit Sub ' --- B
rs.Index = "PrimaryKey"
rs.Seek vardat, adSeekFirstEQ

If rs.EOF Then
strmsg = "該当データがありません。" ' --- B
Else
strmsg = strmsg & rs!売上日 & " ： " & rs!社員名 & " ： " & _
					rs!性別 & " ： " & rs!売上額 & "円"
End If

MsgBox strmsg

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">解説</font>
A.InputBoxを用いてユーザーに検索語を入力させます。
B.ユーザーが検索後を入力しなかった場合は、以降の処理をキャンセルします。
C.EOFプロパティがTrueになった場合、つまり最後まで検索が終了した場合はメッセージを表示させます。

###<font color="Bronwn">実行結果</font>

 1. プロシージャを実行します。
 2. InpuBoxが開きますので、田中邦子と入力します。<br>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/048ddc03-b011-6a65-a37a-bf00da4f7599.png)
 3. 以下の検索が実施され、メッセージボックスが開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/e3be68ba-98d9-be6c-01d1-fb4af39c14b3.png)

$\style{background-color:DodgerBlue;}{関連ページ}$
<UL>
<Li>カレントレコードの検索_テーブルタイプ ： DAO入門講座
<Li>Supportメソッドの利用 ： ADO入門講座
</UL>
2005/06/25
---

＃019.レコードの削除 - Deleteメソッド ： ADO入門講座

http://www.accessclub.jp/ado/19.html

レコードを追加すれば、当然削除する機能も必要になります。ここでは、ADOのDeleteメソッドを用いてレコード（カレントレコード）を削除する方法をご紹介します。

###<font color="RED">留意点</font>
<UL>
<Li>Deleteメソッドでレコードを削除できるのは、カレントレコードのみです。
<Li>目的のレコードを削除する場合は、Move系やFind系メソッドでカレントレコードに移動させる必要があります。
<Li>レコードを削除する際に警告メッセージ等は表示されません。
<Li><b>:red_car:削除したレコードを元に戻すことはできません。</B>
</UL>

#####構文
$\style{background-color:DodgerBlue;}{Deleteメソッドの構文}$

Deleteメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + Deleteメソッド
```

|項目|意味|
|:--|:------|
|Recordsetオブジェクト|開いているRecordsetオブジェクト|

　
###<font color="Bronwn">解説</font>
<OL>
<Li>Deleteメソッドで削除を行った後はカレントレコードが未定義になっています。よって、カレントレコードを参照しようとした場合はエラーが発生します。
<Li>これを防ぐには、Move系メソッドでカレントレコードを移動する必要があります。
</OL>

$\style{background-color:DodgerBlue;}{複数フィールドに値を追加する}$
#####サンプルテーブル
サンプルテーブルを以下のように作成します。レコード数は9件あります。
サンプルテーブル（T_sample）

|ID|売上日|社員名|性別|売上額|
|:--:|:------|:------|:------|------:|
|6|2004/01/23|橘修平|男性|52100|
|5|2004/02/04|柴田喜一|男性|654100|
|8|2004/03/25|正道良一|男性|4875210|
|1|2004/07/29|草薙良子|女性|120310|

$\style{background-color:DodgerBlue;}{Subプロシージャの作成}$

汎用的に利用するためにSubプロシージャを作成します。

$\style{background-color:DodgerBlue;}{1レコードの削除}$

カレントレコードを確認しながら、1件のレコードを削除します。

```vb
Sub ADO_Delete()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim vardat As Variant
Dim strmsg As String
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic
strmsg = rs!売上日 & vbNewLine & _
 rs!社員名 & " のレコードを削除します。"

If MsgBox(strmsg, vbCritical + vbOKCancel) = vbOK Then
rs.Delete
MsgBox "削除を完了しました。"
Else
MsgBox "削除を中止しました。"
End If

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">実行結果</font>
<ol>
<li>このプロシージャをイミディエイト画面上で実行します。
<li>以下の削除確認のメッセージが表示されます。
<li>[OK]をクリックします。
<li>以下のように先頭のレコードが削除されています。
</OL>
<br> ![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/465e22bc-d530-7223-7dae-04d1b6f96f30.png) <br>

|ID|売上日|社員名|性別|売上額|
|:--:|:------|:------|:------|------:|
|5|2004/02/04|柴田喜一|男性|654100|
|8|2004/03/25|正道良一|男性|4875210|
|1|2004/07/29|草薙良子|女性|120310|

$\style{background-color:DodgerBlue;}{全レコードの削除}$

全レコードを削除します。Loopを用いて全てのレコードを一旦カレントレコードに切り替え、削除しています。

```vb
Sub ADO_AllDelete()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim vardat As Variant
Dim strmsg As String
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic
strmsg = rs.RecordCount & " 件の全レコードを削除します。"
If MsgBox(strmsg, vbCritical + vbOKCancel) = vbOK Then
Do Until rs.EOF
rs.Delete
rs.MoveNext
Loop
MsgBox "削除を完了しました。"
Else
MsgBox "削除を中止しました。"
End If

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">実行結果</font>
<OL>
<Li>このプロシージャをイミディエイト画面上で実行します。
<Li>削除確認のメッセージが表示されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/258e4c42-a80e-19b8-5536-50b7a768fd1f.png)

<Li>[OK]をクリックします。
<Li>全てのテーブルレコードが削除されます。
</OL>

$\style{background-color:DodgerBlue;}{削除てきないレコード}$

RecordsetオブジェクトのLockTypeプロパティの値が、adLockReadOnlyとなっている場合は、レコードを削除することはできません。

2005/06/30
---
#20.レコードの編集 - Updateメソッド ： ADO入門講座
http://accessclub.jp/ado/20.html

Updateメソッドを用いて、開いたRecordsetオブジェクト内のカレントレコードの内容を編集し更新することができます。編集できるのはカレントレコードだけですから、目的のレコードをMoveメソッドやFindメソッドを用いてカレントレコードに移動させる必要があります。

###<font color="RED">留意点</font>
<UL>
<li>Updateメソッドを用いて編集できるのは、カレントレコードだけです。
<li>編集時に警告メッセージ等は表示されません。
</UL>
##### 構文
$\style{background-color:DodgerBlue;}{Updateメソッドの構文}$

Updateメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + Updateメソッド+ （半角） + Fields+ ,（カンマ） + Values
```

|項目|意味|
|:--:|:------|
|Recordsetオブジェクト|開いているRecordsetオブジェクトです。|
|Fields|編集するフィールド名を指定します。|
|Values|フィールドに代入する値を指定します。|

###<font color="RED">留意点</font>
<UL>
<li>Fieldsにはフィールド名を指定しますが、"（ダブルクォーテーション）で囲みます。
<li>Valuesが、数値型ではそのまま、文字列であれば"（ダブルクォーテーション）、日付/時刻型では#（シャープ）で囲みます。
</UL>

$\style{background-color:DodgerBlue;}{サンプルテーブルの作成}$
#####サンプルテーブル
サンプルテーブルを以下のように作成します。テーブル名は、T_sampleテーブルです。

|ID|売上日|社員名|性別|売上額|
|:--:|:------|:------|:------|------:|
|6|2004/01/23|橘修平|男性|52100|
|5|2004/02/04|柴田喜一|男性|654100|
|8|2004/03/25|正道良一|男性|4875210|
|1|2004/07/29|草薙良子|女性|120310|

#####単一のフィールドを更新

$\style{background-color:DodgerBlue;}{1つのフィールドの値を変更するプロシージャ}$

このプロシージャは、T_Sampleテーブルの売上額フィールドの値が500,000以上の場合は、5%加算します。

```vb
Sub ADO_Update()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strmsg As String
Dim lngRet As Long
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic

Do Until rs.EOF
If rs!売上額 >= 500000 Then
lngRet = rs!売上額 * 1.05
rs.Update "売上額", lngRet
End If
strmsg = strmsg & rs!売上日 & " ： " & rs!社員名 & _
" ： " & rs!性別 & " ： " & rs!売上額 & "円" & vbNewLine
rs.MoveNext
Loop

MsgBox strmsg

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">実行結果</font>
<OL>
<li>プロシージャを実行します。
<li>Updateメソッドを用いてフィールドデータ値を編集します。
<li>以下のメッセージボックスが表示されます。
</ol>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/e5192900-a4d7-bbbb-8632-07915cc44721.png)

#####複数のフィールドを更新
$\style{background-color:DodgerBlue;}{複数フィールドの値を変更するプロシージャ}$

このプロシージャは、T_Sampleテーブルの売上額フィールドの値が500,000以上の場合は、元データに5%加算し、社員名の前に■を付加します。
:red_car:編注:<font color="Grey">個人的見解だが、名前のような参照整合性が重視される要素に記号を付けるのは、実務上は好ましくない。別のフィールド(Bit/Boolean/YesNO)をもうけ、そこをTrueにする、クエリで抜き出す、という手法が好ましい。テーブルの「氏名」のような重要なフィールドは絶対にこのようなことをしてはならない。</font>

```vb
Sub ADO_UpdateS()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strmsg As String
Dim lngRet As Long
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic

Do Until rs.EOF
If rs!売上額 >= 500000 Then
lngRet = rs!売上額 * 1.05
rs.Update "売上額", lngRet
rs.Update "社員名", "■" & rs!社員名
End If
strmsg = strmsg & rs!売上日 & " ： " & rs!社員名 & _
" ： " & rs!性別 & " ： " & rs!売上額 & "円" & vbNewLine
rs.MoveNext
Loop

MsgBox strmsg

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```


###<font color="Bronwn">実行結果</font>
<OL>
<li>プロシージャを実行します。
<li>Updateメソッドを用いてフィールドデータ値を編集します。
<li>以下のメッセージボックスが表示されます。
</OL>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/8edd92bb-eb1b-5d7a-dc2a-d38ac39dbd38.png)

###<font color="Bronwn">ちょっとお耳を・・・</font>
<UL>
<li>:green_book:プロシージャの記述方法として、まずフィールドに値を代入したのち、値をまとめて最後にUpDateメソッドを実行します。
<li>:green_book:このような場合は、Updateメソッドの引数は不要です。
</UL>
#####編注:補足
この場合上記の例だと次のようになる。なお可読性と正確性のため`RS!売上額`ではなく`RS.Fileds("売上額").Value`と表記している。

```vb
Do Until rs.EOF
  If rs!売上額 >= 500000 Then
    lngRet = rs!売上額 * 1.05
    rs.Fields("売上額").value=lngRet
    rs.Fields("社員名").value= "■" & rs.Fields("社員名").value
    rs.Update 'ここで引数がない
  End If
  strmsg = strmsg & rs!売上日 & " ： " & rs!社員名 & _
  " ： " & rs!性別 & " ： " & rs!売上額 & "円" & vbNewLine
  rs.MoveNext
Loop
```

2005/06/25

---

#021.レコードの抽出 - Filterプロパティ ： ADO入門講座
http://www.accessclub.jp/ado/21.html

RecordsetオブジェクトのFilterプロパティを用いて、抽出条件に該当するレコードを抽出することができます。Filterプロパティで設定した抽出条件に該当するレコードがなき場合は、RecordsetオブジェクトのRecordCountプロパティの値が 0 になります。
抽出条件式には、OR　または AND を用いて複数条件を指定することができます。また、LIKE演算子の利用も可能です。

###<font color="RED">留意点</font>
<UL>
<li>該当レコードが見つからなかった場合、RecordCountプロパティは 0 を返します。
<li>Filterプロパティを解除する場合は、長さ0の文字列（""）またはadFilterNone定数をFilterプロパティに代入します。
</UL>


###構文
$\style{background-color:DodgerBlue;}{Filterプロパティの構文}$

Updateメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + Filterプロパティ  = 条件式
```

|項目|意味|
|:-----|:----------|
|Recordsetオブジェクト|開いているRecordsetオブジェクトです。|
|条件式|抽出条件式を記述します。複数条件を指定する場合は、OR　または AND を用います。|


###<font color="RED">留意点</font>

    抽出する値がテキスト型の場合は、その値自体をシングルクォーテーション（'）で囲みます。

$\style{background-color:DodgerBlue;}{サンプルテーブルの作成}$
#####サンプルテーブル
サンプルテーブルを以下のように作成します。テーブル名は、T_sampleテーブルです。

|ID|売上日|社員名|性別|売上額|
|:--:|:------|:------|:------|------:|
|6|2004/01/23|橘修平|男性|52100|
|5|2004/02/04|柴田喜一|男性|654100|
|8|2004/03/25|正道良一|男性|4875210|
|1|2004/07/29|草薙良子|女性|120310|

$\style{background-color:DodgerBlue;}{500,000以上のデータを抽出するプロシージャ}$

このプロシージャは、T_Sampleテーブルの売上額フィールドの値が500,000以上のレコードを抽出しメッセージボックスに表示します。

```vb
Sub ADO_Filter()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strmsg As String
Dim lngRet As Long
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic
rs.Filter = "売上額 >= 500000"

If rs.RecordCount = 0 Then
MsgBox "該当するレコードは見つかりませんでした。"
Else
Do Until rs.EOF
strmsg = strmsg & rs!売上日 & " ： " & rs!社員名 & _
" ： " & rs!性別 & " ： " & rs!売上額 & "円" & vbNewLine
rs.MoveNext
Loop
End If

MsgBox strmsg

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">実行結果</font>
<OL>
<li>プロシージャを実行します。
<li>Filterプロパティを用いて売上額フィールドで500,000以上のデータを抽出します。
<li>以下のメッセージボックスが表示されます。
</OL>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/cef58cf3-a03c-dfb8-9c48-ac009ceca42b.png)

####Like 演算子
$\style{background-color:DodgerBlue;}{あいまい抽出（LIKE演算子の利用）}$

LIKE演算子を用いてあいまい抽出を行うことができます。以下のプロシージャは、社員名フィールドに良という漢字を持つ社員データを抽出します。

```vb

Sub ADO_Filter2()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strmsg As String
Dim lngRet As Long
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic
rs.Filter = "社員名 LIKE '*良*'"

If rs.RecordCount = 0 Then
MsgBox "該当するレコードは見つかりませんでした。"
Else
Do Until rs.EOF
strmsg = strmsg & rs!売上日 & " ： " & rs!社員名 & _
" ： " & rs!性別 & " ： " & rs!売上額 & "円" & vbNewLine
rs.MoveNext
Loop
End If

MsgBox strmsg

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">実行結果</font>

<OL>
<li>プロシージャを実行します。
<li>Filterプロパティを用いて社員名フィールドに良という漢字を持つ社員データを抽出します。
<li>以下のメッセージボックスが表示されます。
</OL>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/4453f41c-4772-158f-c940-86db05cde996.png)
2005/07/05
---
#022.レコードの並び替え - Sortプロパティ ： ADO入門講座
http://www.accessclub.jp/ado/22.html
RecordsetオブジェクトのSortプロパティを用いて、レコードセット内のレコードを 昇順、または降順に並び替えることができます。但し、RecordsetオブジェクトのCursorLocationプロパティの値がadUseClientである場合に限り，Sortプロパティを用いてレコードの並べ替えが可能になります。

###<font color="RED">留意点</font>

テーブルやクエリを用いてRecordsetオブジェクトは，CursorLocationプロパティの値がadUseServerとなっているためレコードを並べ替えることができません。
Openメソッドを用いてRecordsetオブジェクトを開く前にCursorLocationプロパティの値を設定する必要があります。

$\style{background-color:DodgerBlue;}{Sortプロパティの構文}$

Updateメソッドの構文は、以下のような組み合わせになります。

```vb
Recordsetオブジェクト + .（ドット） + Sortプロパティ  = "フィールド名 + .（半角）  並び順の指定"
```

|項目|意味|
|:-----|:----------|
|Recordsetオブジェクト |開いているRecordsetオブジェクトです。|
|フィールド名|Recordsetオブジェクトに含まれるフィールド名です。|
|並び順|昇順に並べ替える場合はASCキーワード、降順に並べ替える場合はDESCキーワードを記述します。|


<OL>
<li>並び順の既定値は昇順です（ASCが既定値）。
<li>フィールド名と並び順の指定の間には空白が必要です。
</OL>

 $\style{background-color:DodgerBlue;}{サンプルテーブルの作成}$

サンプルテーブルを以下のように作成します。テーブル名は、T_sampleテーブルです。

|ID|売上日|社員名|性別|売上額|
|:--:|:------|:------|:------|------:|
|6| 2004/01/23 | 橘修平|男性|52100|
|5| 2004/02/04 | 柴田喜一|男性|654100|
|8| 2004/03/25 | 正道良一|男性|4875210|
|1| 2004/07/29 | 草薙良子|女性|120310|

$\style{background-color:DodgerBlue;}{1つのフィールドの並び替え}$

このプロシージャは、T_SampleテーブルのIDフィールドを昇順で並び替え、メッセージボックスに表示します。

```vb
Sub ADO_Sort()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strmsg As String
Dim lngRet As Long
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.CursorLocation = adUseClient ' --- A
rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic
rs.Sort = "ID ASC" '昇順で並び替えます。

Do Until rs.EOF
strmsg = strmsg & rs!id & " ： " & rs!売上日 & " ： " & rs!社員名 & _
" ： " & rs!性別 & " ： " & rs!売上額 & "円" & vbNewLine
rs.MoveNext
Loop

MsgBox strmsg

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

$\style{background-color:DodgerBlue;}{1つのフィールドの並び替え}$

###<font color="Bronwn">解説</font>

A.CursorLocationプロパティをOpenメソッドでRecordsetオブジェクトを開く前にadUseClient（クライアント側カーソル ライブラリ）に設定します。

###<font color="Bronwn">実行結果</font>

<OL>
<Li>プロシージャを実行します。
<Li>Sortプロパティを用いてIDフィールドで昇順に並び替えます。
<Li>以下のメッセージボックスが表示されます。
</OL>

####<font color="RED">留意点</font>

<OL>
<Li>並び替えは、Recordsetオブジェクト内でのみ行われます。
<Li>テーブルレコードの並び替えには影響を与えません。
</OL>

編注：原本は１のみで改行して「テーブルレコード．．．」と続くが１，２の誤りと思われる

$\style{background-color:DodgerBlue;}{複数フィールドでの並び替え}$
複数のフィールドで並び替えを行うこともできます。以下のプロシージャは、性別フィールド を昇順、売上日フィールドを降順に並び替え、メッセージボックスに表示します。

```vb
Sub ADO_Sort2()

Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strmsg As String
Dim lngRet As Long
Set cn = CurrentProject.Connection
Set rs = New ADODB.Recordset

rs.CursorLocation = adUseClient
rs.Open "T_Sample", cn, adOpenKeyset, adLockOptimistic
rs.Sort = "性別 ASC,売上日 DESC" ' --- A

Do Until rs.EOF
strmsg = strmsg & rs!id & " ： " & rs!売上日 & " ： " & rs!社員名 & _
" ： " & rs!性別 & " ： " & rs!売上額 & "円" & vbNewLine
rs.MoveNext
Loop

MsgBox strmsg

rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub

```
###<font color="Bronwn">解説</font>

A.複数フィールドで並べ替えを行う場合、カンマ（，）で区切って指定します。この場合，先に指定した並べ替え設定が優先されます。

###<font color="Bronwn">実行結果</font>
<ol>
<Li>プロシージャを実行します。
<Li>Sortプロパティを用いて性別フィールドを昇順、売上日フィールドを降順に並び替えます。
<Li>以下のメッセージボックスが表示されます。
</ol>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/8b2e57a6-0a8e-6007-b92a-a930fcbfc12b.png)

#####解除
$\style{background-color:DodgerBlue;}{並べ替えの解除}$
<OL>
<Li>並び替えを解除する場合は、Sortプロパティに長さ0の文字列（""）を代入します。
<Li>並べ替え順序が解除され，元の並びに戻ります。
</OL>

---

#パラメータクエリをADOから実行する-CreateParameterメソッド ： ADO入門講座
DAOからパラメータクエリを呼び出し実行するには、SQLのPARAMETER宣言を利用したSQLを実行しました。今回は、PARAMETER宣言を用いず、ADOのCreateParameterメソッドを利用 する方法をご紹介します。
###<font color="RED">留意点</font>
<UL>
<li>DAOと同じくADOでもパラメータクエリを実行する場合、入力を促すダイアログボックスが表示されません。よって、InputBox関数で代用する必要があります。
</UL>

$\style{background-color:DodgerBlue;}{CreateParameterメソッド}$

CreateParameterメソッドの構文は、以下のような組み合わせになります。Parameter オブジェクトを返します。

```vb
Set parameter = command.CreateParameter (Name, Type, Direction, Size, Value)
```

|項目|意味|
|:--|:---|
|Name|省略可能です。 <br> Parameter オブジェクト名を含む文字列型 (String) の値を指定します。|
|Type|省略可能です。 <br> Parameter オブジェクトのデータ型を指定します。|
|Direction|省略可能です。 <br> Parameter オブジェクトのデータ型を 以下のリスト値から指定します。
|Size|省略可能です。パラメータ値の最大長を文字数またはバイト数で指定する長整数型 (Long) の値を指定します。|
|Value|省略可能です。Parameter オブジェクトの値を指定するバリアント型 (Variant) の値を指定します。|

|定数|値|説明|
|:--|:---|:---|
|adParamInput|1|既定値です。パラメータが入力パラメータであることを表します。|
|adParamInputOutput|3|パラメータが入出力パラメータであることを表します。|
|adParamOutput|2|パラメータが出力パラメータであることを表します。|
|adParamReturnValue|4|パラメータが戻り値であることを表します。|
|adParamUnknown|0|パラメータの使用方法が不明であることを表します。|


###<font color="RED">留意点</font>

CreateParameterメソッドを実行するだけでは、戻り値であるParameterオブジェクトは、Command オブジェクトの Parameters コレクションに追加されませんので、Appendメソッドを用いて追加する必要があります。

####サンプルテーブルの作成

サンプルテーブルを以下のように作成します。テーブル名は、社員管理です。

|ID|売上日|社員名|性別|売上額|職種|
|:--:|:--:|:---:|:--:|:-----:|:--:|
|1|2004/07/29|草薙　良子|女性|120310|医師|
|2|2004/08/10|田中　幸恵|女性|7986620|一般職|
|3|2004/09/30|中村　幸三|男性|477123|技能職|
|4|2004/04/30|田中　邦子|女性|785100|一般職|
|5|2004/02/04|柴田 喜一|男性|654100|医師|
|6|2004/01/23|橘　修平|男性|52100|一般職|
|7|2004/02/04|柴田 喜一|男性|7892510|技能職|
|8|2004/03/25|正道　良一|男性|4875210|薬剤師|
|9|2004/04/30|田中　邦子|女性|4789210|一般職|
|10|2004/09/10|内田　信二|男性|478622|医師|

###CreateParameterメソッドを用いたパラメータクエリの実行

SubプロシージャMyCreateParaを作成します。このプロシージャでは、性別フィールド、職種フィールドにパラメータを設定します。

```vb
Sub MyCreatePara()

Dim cn As ADODB.Connection
Dim cmd As New ADODB.Command
Dim rs As New ADODB.Recordset
Dim param As ADODB.Parameter
Dim mySQL As String
Dim strmsg As String
Dim strmsg2 As String
Dim strback As String

strmsg = "抽出する性別を入力します。"
strmsg2 = "抽出する職種を入力します。"
mySQL = "SELECT * FROM 社員管理 WHERE 性別=" & strmsg & _
							" AND 職種=" & strmsg2

Set cn = CurrentProject.Connection
Set cmd.ActiveConnection = cn

With cmd
.CommandText = mySQL
.CommandType = adCmdText
.Prepared = True
End With

Set param = New ADODB.Parameter

'---------パラメータ1個ごとに必要-----------------
Set param = cmd.CreateParameter("性別", adVarChar, adParamInput, 10)
cmd.Parameters.Append param
strback = InputBox(Trim(strmsg))
cmd.Parameters("性別") = strback
'-----------------ここまで------------------------

'---------パラメータ1個ごとに必要-----------------
Set param = cmd.CreateParameter("職種", adVarChar, adParamInput, 10)
cmd.Parameters.Append param
strback = InputBox(Trim(strmsg2))
cmd.Parameters("職種") = strback
'-----------------ここまで------------------------

Set rs = New ADODB.Recordset
Set rs = cmd.Execute

Do Until rs.EOF
  Debug.Print rs!ID, rs!社員名, rs!性別, rs!売上額 & "円"
  rs.MoveNext
Loop

Set cmd = Nothing
rs.Close: Set rs = Nothing
cn.Close: Set cn = Nothing

End Sub
```

###<font color="Bronwn">解説</font>
CreateParameterメソッドを用いたプロシージャの流れは以下のようになっています。
<ol>
<Li>.ADODB.Commandオブジェクトのインスタンスを作成します。
<Li>ADODB.Connectionオブジェクト使ってDBに接続します。
<Li>ADODB.CommandオブジェクトのActiveConnectionプロパティに、ADODB.Connectionオブジェクトを結びつけます。
<Li>ADODB.Commandオブジェクトがデータベースと接続済みとなります。
<Li>CommandTextプロパティにSQLを指定します。
<Li>ADODB.CommandオブジェクトのCreateParameterメソッドを用いて引数を作成します。
<Li>CreateParameterオブジェクトをAppendメソッドでADODB.Commandオブジェクトに追加します。
<li>ADODB.CommandオブジェクトのExecuteメソッドを用いて実行します。
</OL>
###<font color="Bronwn">実行結果</font>

1.プロシージャを実行します。
2.InputBoxダイアログボックスが開きますので、男性と入力します。 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/4b399848-849a-f88c-7574-0ce6bf037aee.png)

3.再度、InputBoxダイアログボックスが開きますので、医師と入力します。 <BR> 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/f7f5db1d-2150-4800-17ca-8227f4e46589.png) <br>

4.イミディエイトウィンドウに以下の結果が表示されます。 <BR> 
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/87e023b5-9758-ca5f-baac-ef43317deb18.png) <br>


2005/07/27
パラメータクエリをADOから実行する-CreateParameterメソッド ： ADO入門講座
-Microsoft Access Club-
---
#パラメータクエリをADOから実行する-Refreshメソッド ： ADO入門講座
http://accessclub.jp/ado/refresh.html

ADOからパラメータクエリを呼び出し実行するにはCreateParameterメソッドを利用し、AppendメソッドでADODB.Commandオブジェクトに追加する方法 以外に、今回はRefreshメソッドを用いてパラメータ情報を取得する方法をご紹介します。

###<font color="RED">留意点</font>
<UL>
<Li>ADOを利用してパラメータクエリを実行する場合、入力を促すダイアログボックスが表示されません。よって、InputBox関数で代用する必要があります。
<Li>Refreshメソッドは、CommandTextプロパティに設定されているSQL構造を元に､自動的にParameterコレクションを作成します。
<Li>データベースに対する複雑な問い合わせが発生することで、CreateParameterメソッドを比較し処理スピードが遅くなります。
</UL>

#####Refreshメソッド
Refreshメソッドの構文は、以下のような組み合わせになります。Parameter オブジェクトを返します。

```vb
collection.Refresh
```

|項目|意味|
|:--:|:------|
|collection|省略不可です。各collectionを指定します。

###<font color="RED">留意点</font>
<UL>
<Li>Refresh メソッドを呼び出す前に、Command オブジェクトの ActiveConnection プロパティを有効な Connection オブジェクトに、CommandText プロパティを有効なコマンドに、および CommandType プロパティを 正しく設定する必要があります。
</UL>

#####サンプルテーブルの作成

サンプルテーブルを以下のように作成します。テーブル名は、社員管理です。

|ID|売上日|社員名|性別|売上額|職種|
|:--:|:------|:------|:------|------:|:--:|
|1|2004/07/29|草薙　良子|女性|120310|医師|
|2|2004/08/10|田中　幸恵|女性|7986620|一般職|
|3|2004/09/30|中村　幸三|男性|477123|技能職|
|4|2004/04/30|田中　邦子|女性|785100|一般職|
|5|2004/02/04|柴田 喜一|男性|654100|医師|
|6|2004/01/23|橘　修平|男性|52100|一般職|
|7|2004/02/04|柴田 喜一|男性|7892510|技能職|
|8|2004/03/25|正道　良一|男性|4875210|薬剤師|
|9|2004/04/30|田中　邦子|女性|4789210|一般職|
|10|2004/09/10|内田　信二|男性|478622|医師|

#####Refreshメソッドを用いたパラメータクエリの実行

SubプロシージャMyRefreshを作成します。このプロシージャでは、性別フィールド、職種フィールドにパラメータを設定します。

```vb
Sub MyRefresh()

Dim cnn As New ADODB.Connection
Dim cmd As New ADODB.Command
Dim rs As New ADODB.Recordset
Dim mySQL As String
Dim strmsg As String
Dim strmsg2 As String
Dim strback As String

strmsg = "抽出する性別を入力します"
strmsg2 = "抽出する職種を入力します"
mySQL = "SELECT * FROM 社員管理 WHERE 性別=" & strmsg & _
							" AND 職種=" & strmsg2

' 接続を確立します。
Set cnn = CurrentProject.Connection
' コマンドを実行する接続先を指定します。
cmd.ActiveConnection = cnn

With cmd
.CommandText = mySQL
.CommandType = adCmdText
.Prepared = True
End With

cmd.Parameters.Refresh ' パラメータをリフレッシュします。

strback = InputBox(Trim(strmsg)) ' InputBoxの戻り値を求めます。
cmd.Parameters(0).Value = strback ' パラメータの値を指定します。

strback = InputBox(Trim(strmsg2)) ' InputBoxの戻り値を求めます。
cmd.Parameters(1).Value = strback ' パラメータの値を指定します。

Set rs = cmd.Execute 'パラメータクエリを実行します。

Do Until rs.EOF
  Debug.Print rs!ID, rs!社員名, rs!性別, rs!売上額 & "円"
  rs.MoveNext
Loop

Set cmd = Nothing
rs.Close: Set rs = Nothing
cnn.Close: Set cnn = Nothing

End Sub
```

###<font color="Bronwn">解説</font>

Refreshメソッドを用いたプロシージャの流れは以下のようになっています。
<OL>
<Li>.ADODB.Commandオブジェクトのインスタンスを作成します。
<Li>ADODB.Connectionオブジェクト使ってDBに接続します。
<Li>ADODB.CommandオブジェクトのActiveConnectionプロパティに、ADODB.Connectionオブジェクトを結びつけます。
<Li>ADODB.Commandオブジェクトがデータベースと接続済みとなります。</li>
<Li>CommandTextプロパティにSQLを指定します。</li>
<Li>ParametersコレクションからRefreshメソッドを呼び出します。</li>
<Li>Parameters コレクションの引数に定数を記述する場合は、0から始まります。</li><br>:green_book:`cmd.Parameters(0).Value`は、`cmd.Parameters("性別").Value`に置き換えが可能です。<br>:green_book:`cmd.Parameters(1).Value`は、`cmd.Parameters("職種").Value`に置き換えが可能です。
<Li>ADODB.CommandオブジェクトのExecuteメソッドを用いて実行します。</li>
</OL>
###<font color="Bronwn">実行結果</font>
1.プロシージャを実行します。
2.InputBoxダイアログボックスが開きますので、男性と入力します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/2d9e6130-6bcc-938e-297b-fcf405c00900.png)
3.再度、InputBoxダイアログボックスが開きますので、医師と入力します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/a58186cc-9c6c-3e60-f4e0-8fbb16f5c9b1.png)
4.イミディエイトウィンドウに以下の結果が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/126919/ff9fd2d0-10e4-b7c7-20d1-e0cf0d6d25a4.png)


2005/07/28
--
#公式/<UL>

<UL>
<LI> [Access デスクトップ データベース リファレンス](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/) </LI>
<li>[Access VBA リファレンス](https://docs.microsoft.com/ja-jp/office/vba/api/overview/access)</li>
<UL>
<li>[概念/concepts](https://docs.microsoft.com/ja-jp/office/vba/access/concepts/miscellaneous/concepts-access-vba-reference)</li>
<li>[object-model](https://docs.microsoft.com/ja-jp/office/vba/api/overview/access/object-model)</li>
</UL>
<li>ドキュメントOffice クライアントの開発AccessAccess デスクトップ データベース リファレンスMicrosoft ActiveX データ オブジェクト リファレンスADO プログラマ ガイドセクション I: ActiveX データ オブジェクト


<li>[Access 定数の概要](https://docs.microsoft.com/ja-jp/office/vba/access/concepts/miscellaneous/microsoft-access-constantsoverview)
>組み込み定数には、定数を定義するオブジェクト ライブラリを識別する 2 文字のプレフィックスがあります。 Access ライブラリの定数の先頭には "ac" が、ADO ライブラリの定数の頭には "ad" が、Visual Basic ライブラリの定数の先頭には "vb" が付いています。 
</li>
<li>[Microsoft Active X データ オブジェクト (ADO) リファレンス]()</li>
<li>[ACC2000: Error When You Try to Use Schema.ini to Import or Export with the TransferText Method](https://support.microsoft.com/ja-jp/help/241477/acc2000-error-when-you-try-to-use-schema-ini-to-import-or-export-with) <br> ここのDAOの無茶苦茶な接続文字列とTranphertextを使え。かつその時はSchema.iniを使えとしている。 <br> <br> 

```vb
Sub ImportSchemaTable()
Dim db As DAO.Database
    Set db = CurrentDb()
    db.Execute _
    "SELECT * INTO NewContact FROM [Text;FMT=Delimited;HDR=Yes;DATABASE=C:\My documents;].[Contacts#txt];", _
    dbFailOnError
    db.TableDefs.Refresh
End Sub
```
 <br>
 <br>
</li>
<li></li>
</UL>
</UL>
#非公式
[external-data-mixed-data-types](http://dailydoseofexcel.com/archives/2004/06/03/external-data-mixed-data-types/)
[Microsoft Access Developer and VBA Programming Help Center](http://www.fmsinc.com/MicrosoftAccess/developer/)
[レジストリキーの種類](https://www.itmedia.co.jp/help/tips/windows/w0547.html)
[ADO (ActiveX Data Object) NYORO PRESS](http://nyoro2.net/wp/?p=23)
接続文字列の例。
[ADOを使用してExcelからデータを取り込む際の取りこぼし対策](https://cvyan.hateblo.jp/entry/20070516/1179315052)
このような場合こそレジストリをいじってMaxScanrowsを拡大する案件かもしれない。