ACCESSでCSV出力ツール作ってみた(その1)

 とりあえずCSV制御部分の備忘録
テーブルで入力するファイルを定義し、出力したいテーブルと出力項目を
テーブルで設定します。
 テーブルは別途用意する必要があります。(笑)


Function FromCSV(strTableName As String, strImportTableName As String, strCsvFileName As String, strMode As String) As String
On Error GoTo ERROR_SUB
'====================================================================
' テーブルからCSVの定義を取得してインポートする。
' 可変CSV(カラム追加の可能性のあるテーブル)インポート関数
' 2010.02.02 Created By M.Nishimura
'*使い方
'  str_rtn = FromCSV(定義テーブル名,取込テーブル名,CSVファイル名)
'*戻り値
' True:処理正常終了
' False:処理失敗
'
'====================================================================
    Const COLUMCNT = 256                            'カラム数
   
    Dim db_Dao(1) As DAO.Database
    Dim Rst_Dao(1) As DAO.Recordset
    Dim Qdf_Dao As DAO.QueryDef
    Dim strTname As String                     'テーブル名
   
    Dim dbsCurrent As DAO.Database
    Dim strSQL As String
    Dim tdfNew As DAO.TableDef
    Dim tdffld(COLUMCNT) As DAO.Field

    Dim strClum(COLUMCNT) As String
    Dim strFieldName(COLUMCNT) As String       'フィールド名(カラム数分の配列)
    Dim strFieldSize(COLUMCNT) As String       'フィールドサイズ(カラム数分の配列)
    Dim intFieldSize(COLUMCNT) As Integer      'フィールドサイズ(カラム数分の配列)
    Dim striTname As String                    'インポートテーブル名
    Dim balRetTableExists As Boolean
   
    Dim i As Integer                'レコードカウント用
    Dim j As Integer                'カラム数
    Dim k As Integer                'カラム比較用
    Dim F As Integer                'CSV先頭行除外用
   
    Const CSVTOP = 0
    Dim strC As String              '区切文字
    Dim Swork As String
   
    'テキストの場合はタブ区切り(条件分岐させれば区切文字可変可能)
    strC = vbTab

    i = 0
    j = 0
    k = 0
    strTname = strTableName
    striTname = strImportTableName
    FromCSV = "False"
    strFlName = strCsvFileName
    
'ワークテーブルの存在を確認した後,ワークテーブルが存在すればワークテーブル削除
    balRetTableExists = TableOparate.TableExists(striTname)
    If balRetTableExists = True Then
        DoCmd.DeleteObject acTable, striTname
    End If
    
'呼出しテーブル定義
    strSQL = ""
    strSQL = strSQL & " SELECT " & strTname & ".*"
    strSQL = strSQL & " FROM "
    strSQL = strSQL & strTname & ";"
    strSQL = strSQL & ""

    Set db_Dao(0) = CurrentDb
    Set Qdf_Dao = db_Dao(0).CreateQueryDef("", strSQL)
    Set Rst_Dao(0) = Qdf_Dao.OpenRecordset()
   
'新規テーブル作成用
    Set dbsCurrent = CurrentDb
    Set tdfNew = dbsCurrent.CreateTableDef(striTname)

    i = Rst_Dao(0).RecordCount
   
'レコード数取得
    If i <> 0 Then
        Rst_Dao(0).MoveLast
        j = Rst_Dao(0).RecordCount
        Rst_Dao(0).MoveFirst
    End If
       
    k = 0
'//** テーブル作成(テーブルを新規作成<カラムは可変(全てテキスト型)>) **
    Do Until k = j
        strFieldName(k) = Nz(Rst_Dao(0).Fields(2))  'フィールド名
        strFieldSize(k) = Nz(Rst_Dao(0).Fields(3))  'フィールドサイズ
        intFieldSize(k) = CInt(strFieldSize(k))
       
        Set tdffld(k) = tdfNew.CreateField(strFieldName(k), dbText, intFieldSize(k))
        tdffld(k).AllowZeroLength = True '空文字列の許可
        tdfNew.Fields.Append tdffld(k)
       
        Rst_Dao(0).MoveNext
        k = k + 1
    Loop

    tdfNew.Fields.Refresh
    dbsCurrent.TableDefs.Append tdfNew
    dbsCurrent.TableDefs.Refresh
    dbsCurrent.Close
   
    Set db_Dao(1) = CurrentDb
    Set Rst_Dao(1) = db_Dao(1).OpenRecordset(striTname, dbOpenTable)

'//** CSVデータ取込 ****
'//** ファイル拡張子において区分けしている。CSV以外はsplitで処理
    Open strFlName For Input As #1
    F = 0
    Select Case strMode
        '//* CSV(カンマ区切)の処理
        Case Is = ".csv"
            Do Until EOF(1)
                k = 0
                Do Until k = j
                    Input #1, strClum(k)
                    k = k + 1
                Loop
                '先頭1行は表題なのでテーブルに書き込まない
                If F <> CSVTOP Then
                    k = 0
                    Rst_Dao(1).AddNew
                    Do Until k = j
                        Rst_Dao(1).Fields(k) = Nz(strClum(k))
                        k = k + 1
                    Loop
                    Rst_Dao(1).Update
                End If
                F = F + 1
            Loop
        '//* txtファイルの処理
        Case Is = ".txt"
            Do Until EOF(1)
                k = 0
                Line Input #1, Swork
                If F <> CSVTOP Then
                    Rst_Dao(1).AddNew
                    Do Until k = j
                    'タブ区切でないTXTだとエラーとなるため処理を中止する。
                        If Swork <> "" Then
                            strClum(k) = Split(Swork, strC)(k)
                            Rst_Dao(1).Fields(k) = Nz(strClum(k))
                            k = k + 1
                        Else
                            GoTo ERROR_SUB
                        End If
                    Loop
                    Rst_Dao(1).Update
                End If
                F = F + 1
            Loop
        Case Else
            GoTo ERROR_SUB
    End Select
   
    Close #1

'* DBのクローズ
    Rst_Dao(0).Close
    db_Dao(0).Close
    Rst_Dao(1).Close
    db_Dao(1).Close

    FromCSV = "True"
    Exit Function


'//* エラー処理 *//
ERROR_SUB:

    'エラー処理
'    Call MsgBox(CStr(Err.Number) & "," & Err.Description)  '*デバッグ用
   
    MsgBox "TXTファイルはタブ区切、CSVファイルはカンマ区切です。" & Chr(13) & _
           "ファイル形式に誤りがある可能性があります。取込ファイルを修正してください。" & Chr(13) & _
           "ファイルを修正してもエラーが続く場合は、定義テーブルを確認してください。" & Chr(13) & _
           "それでもエラーが解消されない場合はシステム管理者に連絡してください。"
          
    Close #1
    FromCSV = "False"
    Exit Function

End Function
Function ToCsv(StrDataName As String, StrFileName As Variant, strMode As String) As String
'====================================================================
' CSVデータエクスポート
' 2010.05.18 Created By M.Nishimura
'*使い方
'  str_rtn = ToCSV(出力元テーブル名,出力先CSVファイル)
'*戻り値
' True:処理正常終了
' False:処理失敗
'
'====================================================================
On Error GoTo err_a
   
    Dim db_Dao As DAO.Database
    Dim Rst_Dao As DAO.Recordset
   
    Dim strMsg As String
    Dim intmsg As Integer
    Dim varinput1, varinput2 As Variant
   
   
    Dim outi As Integer            '出力テーブルフィールドカウント用
    Dim lasti As Integer           '最終フィールド数
    Const CORUM = 0                'データ部フィールドカウンタの初期値
    Dim strF As String             '「"」表現用
    Dim strC As String             '区切記号用
   
    Dim strOutput As String        'CSV出力用文字列
    Dim balRetTableExists As Boolean
   
   
   
    strMsg = "CSVファイルへデータを出力しますか ?"
    intmsg = MsgBox(strMsg, 17, "管理者")

    ToCsv = "False"

    '出力用テーブルチェック
    balRetTableExists = TableOparate.TableExists(StrDataName)
    If balRetTableExists = False Then
        Exit Function
    End If

    If intmsg = 1 Then
        Set db_Dao = CurrentDb
        '出力元のテーブルまたはクエリ名です。
        varinput2 = StrDataName
       
        If varinput2 <> "" Then
            Set Rst_Dao = db_Dao.OpenRecordset(varinput2)
        Else
            Exit Function
        End If
        'ファイル名指定
        varinput1 = StrFileName
        If IsNull(varinput1) Then End
               
       'CSVファイルの場合は「"",""」形式、テキストの場合はタブ区切り
       '***** CSVファイルを「,」のみ形式にしたいときはstrFを""に書替
       If strMode = ".csv" Then
          strF = Chr(34)
          strC = Chr(44)
       Else
          strF = ""
          strC = vbTab
       End If
               
       lasti = Rst_Dao.Fields.Count
       Rst_Dao.MoveFirst
       
       
'// CSVデータ出力
        Open varinput1 For Append As #1  '出力ファイルを開く
       
        '* タイトル出力
        outi = CORUM
        Do Until outi = lasti
           If outi = lasti - 1 Then
                strOutput = strOutput & strF & Rst_Dao.Fields(outi).Name & strF                          '最終レコードはカンマなし
           Else
                strOutput = strOutput & strF & Rst_Dao.Fields(outi).Name & strF & strC
           End If
           outi = outi + 1
        Loop
        Print #1, strOutput
       
        '* データ本体出力
        Do Until Rst_Dao.EOF
                outi = CORUM                  'フィールドを1列目にセット
                strOutput = ""
                Do Until outi = lasti         'フィールド出力
                   If outi = lasti - 1 Then
                        strOutput = strOutput & strF & Rst_Dao.Fields(outi).Value & strF
                   Else
                        strOutput = strOutput & strF & Rst_Dao.Fields(outi).Value & strF & strC
                   End If
                   outi = outi + 1
                Loop
                Print #1, strOutput
                Rst_Dao.MoveNext
        Loop
       
        Rst_Dao.Close
        Close #1 '出力ファイルを閉じる
          
        Set Rst_Dao = Nothing
        Set db_Dao = Nothing
        ToCsv = "True"
    Else
        MsgBox "処理を中止しました", 1, "管理者"
        Set Rst_Dao = Nothing
        Set db_Dao = Nothing
    End If
   
    Exit Function
   
err_a:

    MsgBox "Error番号:" & Err.Number & vbNewLine & _
            "Error内容:" & Err.Description, 16, "管理者"
               
    Close #1
    ToCsv = "False"

End Function

コメント

このブログの人気の投稿

証券外務員1種勉強(計算式暗記用メモ)

GASでGoogleDriveのサブフォルダとファイル一覧を出力する

マクロ経済学(IS-LM分析)