スキップしてメイン コンテンツに移動

Access adpのVBAでTransferTextを使いCSVファイルをインポートするとエラーになる場合がある。

タイトルのように、Access adpファイルでVBAに

 

DoCmd.TransferText acImportDelim 

 

を使いCSVファイルをインポートしようとするとエラーになる場合がある。

 

実は、Access2003くらいからずっとこの問題に悩まされていて、インポート中に以下のようなメッセージが出てエラーになることがある。

 

 

 

「バリアント型でない変数にNull値を代入しようとしました」

 

 

 

読み込むCSVのファイルは、毎週1回更新用に提供されるもので、週によって上記のエラーが出たり出なかったりする。

 

よくわからないのは、エラーとなっても、手動でインポートをやるとエラーにならず上手くインポートできてしまうということ。

 

読み込むテーブルの各列の NULLを許容 の属性にチェックを入れてもエラーになる時はなる。

 

何行目のデータでエラーが起きているのかの情報もないのでどのデータが悪いのかもよくわからない。

 

そんなわけで、エラーが出た時は、手動でインポートして対応していました。

 

 

 

ここで、インポート定義を使えばいいのではと思われる方もいるとは思いますが、apd では仕様上インポート定義が使えないようです。

 

 

 

それで、ここからは私の推測なんですが、apd の環境で、DoCmd.TransferText acImportDelim 実行する場合は、コマンド実行に先立って、インポートするCSVのファイルをダミーで読んで各列のデータ型を決めているのでは・・・・。それで実際に読んだ時にダミーの読んだ時の型と不一致なデータが出現した場合にエラーとなるのではないか・・・・。

 

という推測です。間違っていたらご指摘ください。

 

 

 

では、どう解決すればいいのかと、いろいろ調べてみると、やはり、地道にVBAの標準のI/Oを使って読み込むのが確実なようです。

 

以下に、サンプルコードを抜粋しておきますので、参考にしてください。

     Dim txtData As String, FNo As Long, arrData, i As Integer

  Dim StrFilNm As String      ' パス付きファイル名の格納用変数
  Dim conn As New ADODB.Connection
    Dim Rec As New ADODB.Recordset

 

  'カレントデータベースに接続
    Set conn = Application.CurrentProject.Connection

 

    ' 読み込み用テーブルをクリア
    conn.Execute "DELETE [tbl読込先]"

 

    ' 読込み先 Open
    Rec.Open "tbl読込先", conn, adOpenDynamic, adLockOptimistic
   

 

  ' CSVファイルの場所を設定
  StrFilNm = "C:\sample\test.csv" '場所とファイル名を設定

 

 

 

    FNo = FreeFile
    Open StrFilNm For Input As #FNo  'CSVファイルオープン
   
    On Error GoTo エラー処理
   
   ' トランザクション開始
    conn.BeginTrans
   

        ' 指定されたCSVファイルからtxtDataに1行読込、
        ' Split関数でカンマ毎に切り離して、配列arrDataにセット
        ' テーブルの各項目にセットする(この例は項目数15)
       
 
        Do While Not EOF(FNo)
            Line Input #FNo, txtData
            arrData = Split(txtData, ",")
                Rec.AddNew
                    Rec("F1") = arrData(0)
                    Rec("F2") = arrData(1)
                    Rec("F3") = arrData(2)
                    Rec("F4") = arrData(3)
                    Rec("F5") = arrData(4)
                    Rec("F6") = arrData(5)
                    Rec("F7") = arrData(6)
                    Rec("F8") = arrData(7)
                    Rec("F9") = arrData(8)
                    Rec("F10") = arrData(9)
                    Rec("F11") = arrData(10)
                    Rec("F12") = arrData(11)
                    Rec("F13") = arrData(12)
                    Rec("F14") = arrData(13)
                    Rec("F15") = arrData(14)
                    Rec.Update
        Loop

    conn.CommitTrans 'トランザクション コミット
   
    Close #FNo ' CSVファイルクローズ
   
    Rec.Close    '  読み込み先テーブルクローズ

 

 

DoCmd.TransferText acImportDelim コマンドを 行数は多くなりましたが、
上記のようなコードに変更した結果、いまのところ、

 

「バリアント型でない変数にNull値を代入しようとしました」

 

が出ることはなくなりました。

 

 

コメント

このブログの人気の投稿

KVK混合水栓【KF770】の切替弁【PZ669】の交換 

 前の記事にも書いたけれど、家を買ってから10年も経つと、いろいろとガタがくるもので風呂場のKVK混合水栓の切替ハンドルを停止の位置にしてもポタポタと水が止まらなくなりました。       それより、一年前くらいから(もっと前だったかも)、切替ハンドルがスムースではなくなり妙に重くなってきてはいました。これはまあ、実害がなかったのでそのままにしておいたのですが、水漏れとなると話は違います。多分、一晩くらい出続けたら結構な流失量になるはず・・・・。       これは、放置しておけないということで、早速ネットで情報を集めて見ます。   まず、混合水栓の名称と型番は       サーモスタット式シャワー  KF770TN       その結果、切替弁という部品を交換すれば直ると書いてあります。   その部品の名称と型番は       サーモスタットシャワー切替弁ユニット  PZ669 でも、公式よりAmazonのほうが送料無料で安いです。       そして、交換方法はおおまかに こちら に書いてあります。 でも、そこに書いてあるようにすんなりとはいかないので、それを以下に書いておきます。     まず、絶対忘れていけないのは、止水弁をお湯側、水側しっかり締めておきます。さもないと、ずぶ濡れになって、制御不能になるかもしれません。 1.次に、キャップと切替ハンドルの隙間にドライバーを差し込んで、キャップと切替ハンドルを外します。             2.次に切替カラーを外すのですが、これを外すのに結構苦労しました。写真の様にカラーの後ろの部分に切り欠きがあってそれを外すように本体の後ろのプレートを手前側に押しながら外します。私はこれがわからなくてドライバーなどで無理やり外そうとして手こずりました。私は幸運にも割らずに済みましたが、もう少し無理にやったら割っていたかもしれません。   ...

システム管理者が設定したレポート処理ジョブの最大数に達しました

 会社で、後輩が、私が開発した、asp.net のプログラムを使用していた時の事。     急に、エラーが発生して動かなくなったとの事。     直前にどんな事をやっていたか聞いてみると、商品ごとに集計を行っていたのだか、それを連続して、数十回やっていたとのこと。         表示されるメッセージを見ても詳細はわからないので、Webサーバーのイベントビューワーでログを見てみると、以下のようなメッセージが記録されている。         システム管理者が設定したレポート処理ジョブの最大数に達しました。          場所 CrystalDecisions.ReportAppServer.ClientDoc.ReportClientDocumentClass.Open(Object& DocumentPath, Int32 Options)      場所 CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.Open(Object& DocumentPath, Int32 Options)      場所 CrystalDecisions.ReportAppServer.ReportClientDocumentWrapper.EnsureDocumentIsOpened()           このプログラムはCrystalReportsを使って集計と表示をしているので、どうも CrystalReports絡みのエラーのようである。           そこで、いろいろ調べて見ると、どうもCrystalReportsを使ったあとで、ちゃんと Close とか Dispose とかで、ちゃんと後始末をしなくてはいけないらしい。 そこで、以下のように Unload のイ...

Crystal 構文 if文 の 入れ子の例

 Crystal 構文 で if 文は、構造がわかりにくくネスト(入れ子)はできないのか   と思っていましたができるようです。     と言いながらもよく書き方を忘れるので備忘録的に以下に書いておくので   参考にしてください。           if   [条件1] then             // [条件1]が真の時、以下の条件式を判断する                 if [条件2] then                          // ここに [条件1]かつ[条件2]が真の時処理を書く               else                         //   ここに [条件1]が真で[条件2]が偽の時処理を書く         else                  // ここに[条件1]が偽の時の処理を書く