【VBA】ADOを使用してテキストファイル（CSV）をDB操作する方法のまとめ

# はじめに

個人的な備忘として、[ADOライブラリ](https://docs.microsoft.com/ja-jp/sql/ado/microsoft-activex-data-objects-ado?view=sql-server-ver15)を使用して**テキストファイル**（CSV、TSVなど）をデータベースとして操作する方法をまとめておきます。

# 1. テキストファイルの種類（CSV、TSVなど）

まずは、対象となるテキストファイルの種類を表にしておきます。
一般的には、**カンマ区切り**のCSVファイルがほとんどですが、**タブ区切り**、**セミコロン区切り**のファイルなども存在します。

|データ形式|名称|区切り文字|
|---|---|---|
|[CSV](http://e-words.jp/w/CSV.html)|Comma-Separated Values|カンマ (,)|
|[TSV](http://e-words.jp/w/TSV.html)|Tab-Separated Values|タブ (\t)|
|SSV|Space-Separated Values|スペース ( )|
|CSV(EU)|(Comma-Separated Values)|セミコロン (;)|

最後のセミコロン区切りのCSVファイルは、主にヨーロッパで使用されているようです（小数点区切りにカンマを使用しているためその回避策とのこと）。

# 2. ADOを使用した接続方法

ここでは、Excel VBAを使用しますが、Access VBAやWord VBAでも基本的には同じです。

最初に基本的な例として、CSVファイルを読み込むサンプルコードを挙げておきます。
事前の準備として、以下の内容のCSVファイルを、Excelファイルと同じフォルダに入れておきます。

```TestTable.csv
品名,区分,単価,購入数,購入日
にんじん,野菜,70,3,2020/10/20
りんご,果物,150,2,2020/10/22
みかん,果物,40,10,2020/10/30
キャベツ,野菜,180,1,2020/11/1
じゃがいも,野菜,50,5,2020/11/5
バナナ,果物,300,2,2020/11/6
メロン,果物,1500,1,2020/11/8
```

## 2-1. CSVファイルの読み込み（SELECT文）

Excelファイルの標準モジュールに次のコードを記載します。
この例は、[参照設定](https://qiita.com/t-yama-3/items/e79056079ffdcdb79391#1-1-2-%E5%8F%82%E7%85%A7%E8%A8%AD%E5%AE%9A%E3%82%92%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88)に`Microsoft ActiveX Data Object 6.1 Library`を追加している場合です。

**＜ソースコード＞**

```vb:SELECT文の実行
Sub CSVSample_Select()
    'ADOを使用してCSVファイルに接続（参照設定にMicrosoft ActiveX Data Object 6.1 Libraryを適用済み）
    Dim cn As New ADODB.Connection
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Text;HDR=Yes"
    cn.Open ThisWorkbook.Path & "\"
    
    'SELECT文の実行
    Dim rs As New ADODB.Recordset
    rs.Open "SELECT * FROM TestTable.csv WHERE 区分 = '野菜' ORDER BY 単価", cn

    '取得した内容（Recordset）の確認
    Do While Not rs.EOF
        Debug.Print rs("品名") & ", " & rs("区分") & ", " & rs("単価") & ", " & rs("購入数") & ", " & rs("購入日")
        rs.MoveNext
    Loop
    
    'メモリの解放
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub
```

**＜出力結果＞**
次のように、WHERE句による絞り込みと、ORDER BY句による並べ替えを実行した結果が出力されます。

```:イミディエイトウィンドウ
じゃがいも, 野菜, 50, 5, 2020/11/05
にんじん, 野菜, 70, 3, 2020/10/20
キャベツ, 野菜, 180, 1, 2020/11/01
```

以下、拡張プロパティ、Schema.iniファイルについて簡単な説明をしていきます。
その他のADOライブラリの基本事項は、[こちら](https://qiita.com/t-yama-3/items/e79056079ffdcdb79391)などを参照してください。

**＜参考サイト＞**
[エクセルの神髄 - ADOでCSVの読み込み（SQL）](https://excel-ubara.com/excelvba5/EXCEL118.html)

## 2-2. 拡張プロパティ（Extended Properties）

テキストファイルのADO接続で重要なのは**拡張プロパティ**（Extended Properties）を記載した次の1行です。
指定文字列として、`"Text;HDR=Yes"`というようにセミコロンで区切って2つのプロパティを設定しています。

```vb:Microsoft.ACE.OLEDB.12.0における拡張プロパティ
cn.Properties("Extended Properties") = "Text;HDR=Yes"
```

最初の**Text**は[ISAM](https://ja.wikipedia.org/wiki/Indexed_Sequential_Access_Method)の指定で、これにより「カンマ区切りのCSVファイルを読み込むこと」が設定されます。
次の**HDR=Yes**では、「1行目をカラム名で読み込むこと」を指定しています（指定しなくともデフォルトでYes）。
現在のプロバイダ（**Microsoft.ACE.OLEDB.12.0**）の拡張プロパティではこの2つしか指定できないようです（おそらく）。

なお、Office2003以前のプロバイダ（**Microsoft.Jet.OLEDB.4.0**）であれば[次のように](https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/scripting-articles/ms974559(v=msdn.10)?redirectedfrom=MSDN)細かく指定することができました。

```vb:Microsoft.Jet.OLEDB.4.0における拡張プロパティ
cn.Properties("Extended Properties") = "Text;HDR=Yes;FMT=CSVDelimited;TypeGuessRows=12"
```

**FMT**（Formatの略）では区切り文字（カンマやタブなど）を指定して、**TypeGuessRows**ではデータ形式の判定を行う行数を指定しています。

一覧で比較すると次のようになります。

|指定文字列|Microsoft.Jet. OLEDB.4.0|Microsoft.ACE. OLEDB.12.0|指定内容|
|---|---|---|---|
|Text|○ 要指定|○ 要指定|接続対象をテキストファイルとすることを指定|
|HDR=Yes<br>HDR=No|○ 指定可能<br>（デフォルトはYes）|○ 指定可能<br>（デフォルトはYes）|1行目をヘッダーとするか否かを指定|
|FMT=CSVDelimited<br>FMT=TabDelimited<br>FMT=Delimited(x) |○ 要指定|× 指定できない<br>（カンマ区切り固定）|区切り文字を指定|
|TypeGuessRows=[数字]|○ 指定可能|× [指定できない](https://stackoverrun.com/ja/q/12664920)<br>（8行固定）|データ形式の推測を行う行数を指定|

現在の**Microsoft.ACE.OLEDB.12.0**の拡張プロパティでは、区切り文字の指定（FMT）やデータ形式の読取り行数の指定（TypeGuessRows）はできません。
これらの指定が必要な場合は、次に説明するSchema.iniファイルにて行うことになります。

**＜参考サイト＞**
[ADO.NET text file ConnectionString Extended Properties](http://projectsmm.com/technet/ado/adoextprops.shtml)

## 2-3. Schema.iniファイル

テキストファイルの種類（CSV、TSVなど）や読取り方法などの設定は、<font color="red">対象となるテキストファイルと同じフォルダ</font>に、次のような[Schema.iniファイル](https://docs.microsoft.com/ja-jp/sql/odbc/microsoft/schema-ini-file-text-file-driver?view=sql-server-ver15)を作成して行います。

**＜2つのテキストファイルを指定する場合のSchema.iniファイルの例＞**
![2021-03-07 195449.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551412/e2378024-554c-2e01-6ec6-26451d22bb6e.png)
**＜作成方法＞**
・テキストエディタ（メモ帳でOK）でファイル名「Schema.ini」のファイルを作成します。
・対象となるテキストファイル名は角括弧で括って記載します。
・ファイル名に続いてキーワードと設定内容を`=`で結びます。
・同フォルダ内の複数のテキストファイルの設定をする場合は、上記のように2つ並べて記載します。
・記載内容に大文字小文字の区別はないようです（Formatでもformatでも構わない）。

**＜記載内容＞**
1つ目の`TestTable.csv`ファイルの指定内容は以下のようになっています。

```Schema.ini
[TestTable.csv]
Format=CSVDelimited
CharacterSet=932
MaxScanRows=12
Col1=品名 Text
Col2=区分 Text
Col3=単価 Long
Col4=購入数 Text
Col5=購入日 Date
```

簡単に言うと、**Format**は区切り文字の指定（FMTと同じ）、**CharacterSet**は文字コードの指定、**MaxScanRows**はデータ形式の推測を行う行数を指定（TypeGuessRowsと同じ）を行っています。
続く**Col1**から**Col5**は、各カラムのデータを読み込む際の「カラム名の指定」、「データ型の指定」を行っています（1～5の数字はカラムの順番です）。
詳細は、次のとおりです。

### 2-3-1. 指定できる項目の一覧

Schema.iniファイルで指定できる項目は主に次のとおりです。

|項目|指定内容|指定例|
|---|---|---|
|[ファイル名]|テキストファイル名を指定|[Sample.txt]|
|Format|区切り文字を指定|Format=CSVDelimited|
|CharacterSet|テキストファイルの文字コードを指定|CharacterSet=65001|
|MaxScanRows|データ形式の推測を行う行数を指定|MaxScanRows=12|
|ColNameHeader|1行目をヘッダーとするか否かを指定|ColNameHeader=TRUE|
|Col<i>n</i>|カラム名とデータ型を指定（固定長の場合はフィールド幅も指定）|Col1=ID Long|

以下、個別に見ていきます。

**＜参考URL＞**
[Understanding Schema.ini Files](https://docs.microsoft.com/en-us/sql/odbc/microsoft/schema-ini-file-text-file-driver?redirectedfrom=MSDN&view=sql-server-ver15#understanding-schemaini-files)

### 2-3-2. ファイル名の指定

次のようにファイル名と拡張子を指定します。

```ini:Sample
[Sample.txt]
```

拡張子は`.txt`と`.csv`は指定できますが、`.tsv`は指定できませんでした（拡張子を.txtに変えれば読み取れます）。

### 2-3-3. Formatの指定

キーワード**Format**では、読み込むテキストファイルの区切り文字を指定します。

```ini:Sample
# カンマ区切り（CSVファイル）
Format=CSVDelimited

# タブ区切り（TSVファイル）
Format=TabDelimited

# スペース区切り（SSVファイル）
Format=Delimited( )

# セミコロン区切り（CSV(EU)）
Format=Delimited(;)

# 固定長
Format=FixedLength
```

用意されてる値を表にすると次のとおりです

|指定値|区切り文字|説明|
|---|---|---|
|CSVDelimited|カンマ (,)|カンマ区切りのファイル（CSVファイル）の場合に使用|
|TabDelimited|タブ (\t)|タブ区切りのファイル（TSVファイル）の場合に使用|
|Delimited(指定文字)|カスタム|任意の区切り文字を指定できる（二重引用符(")を除く）|
|FixedLength|なし（固定長）|区切り位置は固定長のフィールド幅で判定|

**＜参考URL＞**
[Specifying the File Format](https://docs.microsoft.com/en-us/sql/odbc/microsoft/schema-ini-file-text-file-driver?redirectedfrom=MSDN&view=sql-server-ver15#specifying-the-file-format)

もはや不要だとは思いますが、TSVファイル、SSVファイル、固定長のファイルのサンプルコードを以下書いておきます。

#### 2-3-3-1. タブ区切りファイル（TSV）のサンプルコード

タブ区切りファイル（TSVファイル）を読み取る場合のサンプルコードです。
TSVファイルですが、拡張子は`.txt`としています（`.tsv`が読み込めないため）。

**＜VBAのコード＞**

```vb:SELECT文の実行（TSVファイル）
Sub TSVSample_Select()
    'ADOを使用してテキストファイルに接続（参照設定にMicrosoft ActiveX Data Object 6.1 Libraryを適用済み）
    Dim cn As New ADODB.Connection
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Text;HDR=Yes"
    cn.Open ThisWorkbook.Path & "\"
    
    'SELECT文の実行
    Dim rs As New ADODB.Recordset
    rs.Open "SELECT * FROM TestTableTsv.txt WHERE 区分 = '野菜' ORDER BY 単価", cn

    '取得した内容（Recordset）の確認
    Do While Not rs.EOF
        Debug.Print rs("品名") & ", " & rs("区分") & ", " & rs("単価") & ", " & rs("購入数") & ", " & rs("購入日")
        rs.MoveNext
    Loop
    
    'メモリの解放
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub
```

**＜Schema.iniファイルの記載＞**

```Schema.ini
[TestTableTsv.txt]
Format=TabDelimited
```

#### 2-3-3-2. スペース区切りファイル（SSV）のサンプルコード

スペース区切りファイル（SSVファイル）を読み取る場合のサンプルコードです。
SSVファイルですが、拡張子は`.txt`としているのは[前例](#2-3-3-1-タブ区切りファイルtsvのサンプルコード)と同様です。

**＜VBAのコード＞**

```vb:SELECT文の実行（SSVファイル）
Sub SSVSample_Select()
    'ADOを使用してテキストファイルに接続（参照設定にMicrosoft ActiveX Data Object 6.1 Libraryを適用済み）
    Dim cn As New ADODB.Connection
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Text;HDR=Yes"
    cn.Open ThisWorkbook.Path & "\"
    
    'SELECT文の実行
    Dim rs As New ADODB.Recordset
    rs.Open "SELECT * FROM TestTableSsv.txt WHERE 区分 = '野菜' ORDER BY 単価", cn

    '取得した内容（Recordset）の確認
    Do While Not rs.EOF
        Debug.Print rs("品名") & ", " & rs("区分") & ", " & rs("単価") & ", " & rs("購入数") & ", " & rs("購入日")
        rs.MoveNext
    Loop
    
    'メモリの解放
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub
```

**＜Schema.iniファイルの記載＞**

```Schema.ini
[TestTableSsv.txt]
Format=Delimited( )
```

#### 2-3-3-3. 固定長ファイルのサンプルコード

最後に、データの区分を区切り文字ではなく、フィールドの長さで判定する場合のサンプルコードです。
次のようなテキストファイルを準備します。
なお、半角文字の長さは1、全角文字の長さは2でカウントされるようです（SHIFT_JISファイル及びUTF-8ファイルで確認）。
![2021-03-07 211027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551412/51505b38-45ef-5148-d7f5-d01848a7a2d1.png)
**＜VBAのコード＞**

```vb:SELECT文の実行（固定長データのファイル）
Sub FixedLengthSample_Select()
    'ADOを使用してテキストファイルに接続（参照設定にMicrosoft ActiveX Data Object 6.1 Libraryを適用済み）
    Dim cn As New ADODB.Connection
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Text;HDR=Yes"
    cn.Open ThisWorkbook.Path & "\"
    
    'SELECT文の実行
    Dim rs As New ADODB.Recordset
    rs.Open "SELECT * FROM TestTableFixedLength.txt WHERE 区分 = '野菜' ORDER BY 単価", cn

    '取得した内容（Recordset）の確認
    Do While Not rs.EOF
        Debug.Print rs("品名") & ", " & rs("区分") & ", " & rs("単価") & ", " & rs("購入数") & ", " & rs("購入日")
        rs.MoveNext
    Loop
    
    'メモリの解放
    rs.Close: Set rs = Nothing
    cn.Close: Set cn = Nothing
End Sub
```

**＜Schema.iniファイルの記載＞**

```Schema.ini
[TestTableFixedLength.txt]
ColNameHeader=False
Format=FixedLength
Col1=品名 Text Width 10
Col2=区分 Text Width 10
Col3=単価 Long Width 5
Col4=購入数 Text Width 5
Col5=購入日 Date Width 10
```

### 2-3-4. CharacterSetの指定

キーワード**CharacterSet**では、テキストファイルの文字コードを指定します。
何も指定しないと`SHIFT_JIS`で読み込まれます（現時点の環境では）。

```ini:Sample
# SHIFT_JIS（デフォルト）
CharacterSet=932

# UTF-8
CharacterSet=65001

# Unicode（UTF-16）
CharacterSet=1200

# EUC-JP
CharacterSet=51932
```

文字コードはMicrosoftの定める[コードページ](https://docs.microsoft.com/ja-jp/windows/win32/intl/code-page-identifiers?redirectedfrom=MSDN)（数字）で指定します。
日本語に関係するコードページの主なところは、次のとおりです。

|コードページ|文字コード|サクラエディタの指定|
|---|---|---|
|932|SHIFT_JIS|SJIS|
|1200|UTF-16（Unicode）|Unicode|
|1201|UTF-16BE（Unicode）|UnicodeBE|
|12000|UTF-32（Unicode）|-|
|12001|UTF-32BE（Unicode）|-|
|20932|EUC-JP（JIS 0208-1990 and 0212-1990）|EUC-JP|
|50220|JIS（ISO-2022-JP）|JIS|
|51932|EUC-JP|EUC-JP|
|65000|UTF-7（Unicode）|UTF-7|
|65001|UTF-8（Unicode）|UTF-8, CESU-8|

最後のカラムは**サクラエディタ**（テキストエディタ）で指定できる文字コードとの対応を示しています。

**＜参考サイト＞**
[ADODBでUTF-8のCSVを取り込む](http://my-business-adversaria.blogspot.com/2012/08/adodbutf-8csv.html)
[コードページ識別子](https://docs.microsoft.com/ja-jp/windows/win32/intl/code-page-identifiers?redirectedfrom=MSDN)
[CESU-8（通信用語の基礎知識）](https://www.wdic.org/w/WDIC/CESU-8)

### 2-3-5. MaxScanRowsの指定

キーワード**MaxScanRows**では、データ形式の推測を行う行数を指定を指定します。
何も指定しない場合のデフォルト値は8行です。

```ini:Sample
# 12行分読み取って判定する場合
MaxScanRows=12

#全ての行を読み取って判定する場合
MaxScanRows=0
```

基本的には、指定した数値だけレコードを読み取ってデータ型を判定します。
ただし、`MaxScanRows=0`と指定すると、全てのレコードを読み取ります。
判定されたデータ型に変換できないデータは`Null`となりますので注意が必要です。

なお、カラムごとのデータ型を指定すると（[Col<i>n</i>の指定](#2-3-7-colnの指定)）、MaxScanRowsの指定は反映されません。

### 2-3-6. ColNameHeaderの指定

キーワード**ColNameHeader**では、1行目をカラム名として読み込むか否かを指定します。

```ini:Sample
# 1行目をヘッダーと指定する
ColNameHeader=True

# 1行目をヘッダーと指定しない（全てレコードとして読み取る）
ColNameHeader=False
```

読み込んだデータが指定したデータ型と合わない場合は`Null`となります。
この指定は[Extended PropertiesにおけるHDRの指定](#2-2-拡張プロパティextended-properties)と重複しますがどちらでも指定できます。

### 2-3-7. Col<i>n</i>の指定

キーワード**Col<i>n</i>**では、各カラムのデータを読み込む際の「カラム名の指定」、「データ型の指定」のほか、オプションとして「フィールド長」の指定を行います

```ini:Sample
# 各データのフィールド長を指定しない場合（区切り文字でデータを区分する場合）
Col1=品名 Text
Col2=区分 Text
Col3=単価 Long
Col4=購入数 Short
Col5=購入日 Date

# 各データのフィールド長を指定する場合（固定長字でデータを区分する場合などで使用）
Col1=品名 Text Width 10
Col2=区分 Text Width 10
Col3=単価 Long Width 5
Col4=購入数 Text Width 5
Col5=購入日 Date Width 10
```

各データのフィールド長を指定する場合の例は[2-3-3-3. 固定長ファイルのサンプルコード](#2-3-3-3-固定長ファイルのサンプルコード)を参照してください。

指定できるデータ型は次の表のとおりです。

|データ型|種類|サイズ|扱える範囲|
|---|---|---|---|
|Bit|真偽型|1bit|True(1) / False(0)|
|Byte|(整数型)|1byte|0 ～ 255|
|Short (Integer)|短整数型|2byte|-32,768 ～ 32,767|
|Long|長整数型|4byte|-2,147,483,648 ～ 2,147,483,647|
|Currency|通貨型|8byte|-922337203685477.5808 ～ 922337203685477.5807|
|Single|単精度浮動小数点数型|4byte|有効桁数7桁の実数（おおよそ）|
|Double (Float)|倍精度浮動小数点数型|8byte|有効桁数15桁の実数（おおよそ）|
|DateTime (Date)|日付時刻型|8byte|100-01-01 00:00:00 ～ 9999-12-31 23:59:59|
|Text (Char)|文字列型|-|最大255文字|
|Memo (LongChar)|文字列型|-|（最大65,536文字？）|

データ型の括弧内は`ODBCデータ型`です（このデータ型を記載しても同様に挙動します）。

値の範囲は、解説が見つからなかったので、実際に値を入れて調べました。
Memo型の最大文字数は確認していません（Accessと同様であれば最大65,536文字あたりでしょうか）。

# 3. 各種SQL構文のサンプルコード

以上では、SELECT文でテキストファイルを読み込みましたが、その他のSQL構文も使用できるものがあります。
なお、テキストファイルを更新したり、一部削除する操作はできない仕様のようです。

主なSQL構文の使用の可否をまとめると次のとおりです。

|SQL構文|使用可否|補足|
|---|---|---|
|CREATE TABLE文|○|新しいテキストファイルが作成される|
|INSERT文|○|テキストファイルの末尾にレコードが追加される|
|UPDATE文|×|ファイルの書き換えはできない|
|DELETE文|×|ファイルの内容の一部削除はできない|
|DROP TABLE文|○|テキストファイルが削除される|

## 3-1. CREATE TABLE文

以下のサンプルコードを実行すると、新しいテキストファイルが作成されます。

```vb:CREATE_TABLE文の実行
'CREATE TABLE文（テーブル作成）
Sub CSVSample_CreateTable()
    'ADOを使用してCSVファイルに接続
    Dim cn As New ADODB.Connection
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Text"
    cn.Open ThisWorkbook.Path & "\"
    
    'CREATE TABLE文の実行
    Dim cm As New ADODB.Command
    cm.ActiveConnection = cn
    cm.CommandText = "CREATE TABLE CreateTestTable.csv(" & _
                        "品名 TEXT(20)," & _
                        "区分 TEXT(10)," & _
                        "単価 LONG," & _
                        "購入数 INTEGER," & _
                        "購入日 DATE)"
    cm.Execute
    
    'メモリの解放
    Set cm = Nothing
    cn.Close: Set cn = Nothing
End Sub
```

## 3-2. INSERT文

以下のサンプルコードを実行すると、テキストファイルの末尾にレコードが追加されます。
なお、Recordsetオブジェクトの[AddNewメソッド](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/addnew-method-ado)を使用しても、同様にレコードの追加が可能です。

```vb:INSERT文の実行
'INSERT文（データの追加）
Sub CSVSample_Insert()
    'ADOを使用してCSVファイルに接続
    Dim cn As New ADODB.Connection
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Text"
    cn.Open ThisWorkbook.Path & "\"
    
    'INSERT文の実行
    Dim cm As New ADODB.Command
    cm.ActiveConnection = cn
    cm.CommandText = "INSERT INTO CreateTestTable.csv VALUES ('ほうれんそう', '野菜', 150, 2, '2021-2-25')"
    cm.Execute
    
    'メモリの解放
    Set cm = Nothing
    cn.Close: Set cn = Nothing
End Sub
```


## 3-3. DROP TABLE文

以下のサンプルコードを実行すると、テキストファイルが削除されます。

```vb:DROP_TABLE文の実行
'DROP TABLE文（テーブル削除）
Sub CSVSample_DropTable()
    'ADOを使用してCSVファイルに接続
    Dim cn As New ADODB.Connection
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Text"
    cn.Open ThisWorkbook.Path & "\"
    
    'DROP TABLE文の実行
    Dim cm As New ADODB.Command
    cm.ActiveConnection = cn
    cm.CommandText = "DROP TABLE CreateTestTable.csv"
    cm.Execute
    
    'メモリの解放
    Set cm = Nothing
    cn.Close: Set cn = Nothing
End Sub
```


## 3-4. テーブルが存在するか否かを確認する
テーブル（テキストファイル）が存在するか否かの確認を行うこともできます。

以下の例では、データベースのテーブル一覧を取得するためにADOXオブジェクトを使用するために、事前に`Microsoft ADO Ext. 6.0 for DDL and Security`というライブラリの[参照設定](https://qiita.com/t-yama-3/items/f783527c6463a28ecc63#4-1-adox%E3%81%AE%E4%BD%BF%E7%94%A8)をしています。
なお、このライブラリの[Tablesコレクション](https://docs.microsoft.com/ja-jp/office/client-developer/access/desktop-database-reference/tables-collection-adox)で取得されたファイル名は、ピリオドがシャープに変換されていたため（理由は不明です）、その点の補正もしています。

```vb:テーブルが存在するか否かの確認
'テーブルが存在するかの確認を実行
Sub IsExistCSVTableTest()
    Debug.Print IsExistCSVTable("TestTable_コピー.csv")
End Sub

'テーブルが存在するか否かを確認する関数（戻り値：True=存在する, False=存在しない）
Function IsExistCSVTable(tblName As String) As Boolean
    tblName = Replace(tblName, ".", "#") 'Tablesコレクションでピリオドがシャープに変換されるため
    
    'ADOを使用してCSVファイルに接続
    Dim cn As New ADODB.Connection
    cn.Provider = "Microsoft.ACE.OLEDB.12.0"
    cn.Properties("Extended Properties") = "Text"
    cn.Open ThisWorkbook.Path & "\"
    
    Dim ct As New ADOX.Catalog: ct.ActiveConnection = cn 'Catalogオブジェクトを現在のDBに関連付け
    Dim tbl As Table 'テーブルオブジェクトを格納する変数
    IsExistCSVTable = False '初期値を明示（書かなくともFalse）
    
    For Each tbl In ct.Tables 'CatalogオブジェクトのTablesコレクションを1つずつ取得
        If tbl.Type = "TABLE" And StrComp(tbl.Name, tblName, vbTextCompare) = 0 Then 'TableオブジェクトのTypeプロパティとNameプロパティで一致するかを確認
            IsExistCSVTable = True
            Exit For
        End If
    Next
    
    Set ct = Nothing 'Catalogオブジェクトの解放
    cn.Close: Set cn = Nothing 'Connectionオブジェクトの解放
End Function
```

# さいごに

ADOファイルでテキストファイルを読み込む場合、読み込むデータ型の指定が詳細にできるのが便利です。
Excelファイルでも同様の指定ができると良いのですが。