【はめごろし型】CSVからACCESSのテーブルを作る

さて前回前々回と無からテーブルを作り出していたわけですが、世の中そんな無謀ではありません。一番素人が使うというか速攻でDBを作るのは、
「テーブル構造のみ」のテーブルを作ってそこにハメる
というやり方ではないでしょうか。
テーブル構造のみのテーブルを作る方法はEXCELとアクセスがあれば簡単です。
あとはVBAの書き方だけがいつも思い出せないだけです。

##参照設定
今回も相変わらず寄せ集めで作るのでDAOとADOXを参照設定します。

#TEXT Driver
そして今回重要なのがテキストドライバーです。
[Access ODBC ドライバーまたは OLEDB プロバイダーを外部アプリケーションの Office のクイック実行を使用することはできません。](https://support.microsoft.com/ja-jp/kb/2874601)
何を言っているのかよくわからないのですが、簡単にいうとAccess　2010　以降の人は必ずこれを入れろということです。

[Microsoft Access のデータベース エンジン 2010 の再頒布可能](https://www.microsoft.com/en-us/download/details.aspx?id=13255)

というか最初から入れておけよマジで。
 なお64bit版の人は
[64ビット版Windows環境に、32ビット版/64ビット版双方のMicrosoft Access ODBCドライバを共存させる方法 ](http://bitdatasci.blogspot.jp/2014/08/64windows3264microsoft-access-odbc.html)
にしたがってください。
　またこれをインストールするとエクセルからCSVそのものをデータベースとしてクエリを使うことができます。
　だから入れておけよマジで。

##型枠つくり
まず流し込みたいCSVをEXCELで読み込みます。

次にxlsx形式で保存します。
アクセスを起動します。
インポートで造ったファイルをリンクテーブルにします。
リンクテーブルができたらローカル化します。
ここでエラーが出たら修正します。※
表題やデータの不統一が主なものです※
この修正はEXCEL側でもCSVファイルを上書きするなどして、CSVファイルに反映させます。（間違ってもXLSXファイルを修正してはいけません）※
修正が終わったらテーブルが出来上がります。
さてここでこのテーブルをコピーして貼り付けます。(下のプログラムでは型枠と書いています。)
このときテーブルの構造のみを複写します。
これで型枠が出来上がります。
このとき、主キーは設定しない方がいいと思います。。
その分列がずれたり余計な行を削ったりするとキーがずれて面倒だからです。

と簡単に書きましたが、※の部分が結構大変です。この手法自体WEB形式のデータベースからCSVで出力したきれいなCSVを扱う時が一番役立ちます。
特に数GBといったCSVでも作れるのに対し、アクセスは2GBの壁があります。
大量のデータを扱えるデータベースのファイル形式はCSVなのです。
また、CSVはメモ帳でも編集ができるし、訂正も簡単です。枠さえ作っておけばメモ帳さえあればエクセルからアクセスのテーブルまで作れるのですから、この方法はメリットも多いと思います。


##さてここまでで
 テーブルだけの構造のテーブル
 きれいになったCSVファイル
 ができました。
　さて、これらのファイルはたとえばC:\test\にあるとします。
c:\test\filename.csv
c:\test
http://www.accessclub.jp/dao/20.html
これを改造します。

```VB:csvtotable.vb
Sub csvtotabele()

Dim db As Database: Set db = CurrentDb
'Directory, filename and Tablename
Const csvDrive = "C:\test\"
Const CsvFile = "Filename.csv"
Const sTbl = "型枠"
Dim tdf As TableDef
Dim sSQL As String
Dim r As New ADODB.Recordset
Dim r1 As DAO.Recordset:
Dim i As Long

Set tdf = db.TableDefs(sTbl)
’CSVの接続文字列 Connectionstring
c.ConnectionString = "Provider=MSDASQL;" & _
     "Extended Properties=""DRIVER={Microsoft Text Driver (*.txt; *.csv)};" & _
     "DBQ=" & csvDrive & """" 'ここはドライブ名だけ入れる

' SQL
'POINTここでWhere文を追加して絞り込みをかけて流し込むことができる。
'//POINT//そしてここはファイル名のみ入れる。0(^^)0

sSQL = "SELECT * FROM " & CsvFile 
c.Open 'お約束

r.Open sSQL, c 'お約束

Set r1 = db.OpenRecordset("型枠", dbOpenTable) 'お約束 なぜか変数を入れるとエラーが出るのでちゃんと名前を入れる

r.MoveFirst 'お約束

tdf.OpenRecordset

Do Until r.EOF = True '終わるまでやめへんで

  r1.AddNew ’新しいレコード(行)を作る合図
'新しいレコード(行)の作成
  For i = 0 To r.Fields.Count - 1 '0から始まるのでマイナス1
'おまじない(正常なCSVでもなぜかエラーが出るときがあるため) 
   On Error Resume Next
     '列ごとのデータ形式が同一のため、そのままデータを流し込める
     r1.Fields(i).Value = r.Fields(i).Value
   On Error GoTo 0
    If Err.Number <> 0 Then r1.Fields(i) = "": Err.Clear: Debug.Print i
  Next
  r1.Update '流し込んでハメたデータを定着

r.MoveNext '次のレコードセットに移動

Loop

End Sub

```

##これを言葉で言うと
型枠をセットして
接続文字列のおまじないをかけて、ドライブを決める。
SQLのおまじないをかけてCSVファイルを決めて、場合によっては絞り込む。
Cを開いてRを開いて
Do EOF
r.Addnew　新しい行を作る合図をして
　ここでフィールドにデータを入れる for next (チキンなのでOnエラーのおまじない)
r.Update
r.MoveNext　次の行
loop

　まあこんな感じです。接続文字列自体はずっと変わってないらしいけど、誰も使わないのか、うずもれていたようです。なかなか見つからなかった。逆に接続文字列さえ見つかってしまえばこのパターンでxlx*も流し込めるのです。
　あとアクセスの列番号はエクセルと違い、0番から始まります。配列(Array)と似ていますね。というか配列なんでしょうね。
　ちなみに0番から始まっているので、主キーを0番にすると1番から実際のデータが入る。つまり0番は主キー用だとこじつけて覚えておくといいかもしれません。

##出来上がったテーブルは
　名前を変えて保存します。そして、またそれから型枠を複写で造ります。
　そう、一度型枠とマクロが決まればCSVでもきっちりハメてテーブルにできるわけです。