| Access Tips by pPoy |
| etc. | 固定長テキストファイル (全角半角混じり) を正しくテーブルに取り込む方法 《FileSystemObject》 (Access2000〜Access2010) | ||
|---|---|---|---|
|
通常 Access で固定長テキストファイルを取り込む場合は、Access の 「インポート」 機能を使用します。 この機能では、全てが半角の場合は正しくインポートできますが、 特定の全角文字が含まれる場合、桁がずれてしまいます。 例: ギリシャ文字・囲み英数字(丸付き数字)・ローマ数字・単位記号 etc. これを防ぐ為には、レジストリを書き換える方法が、マイクロソフトによって説明されています。 『テキストを Access にインポートした際に 区切り位置がずれる場合の対処方法』 結構危険な方法でもあり、しかも全ての PC に対して行う必要があります。 以下は VBA で固定長テキストファイルを正しくインポートする方法です。 FileSystemObject, Windows Script Host 及び lenbt関数 (ユーザ定義関数) を使用します。 ユーザーのデスクトップパスは、WSH を使用して取得します。 ※ ADO への参照設定が必要です。 | |||
|
≪準備1≫ デスクトップに、以下のような 固定長テキストファイルを置きます。 ファイル名は、「固定長テキストデータ.txt」 です。 ![]() ファイルは 「SJIS 形式」 で保存されています。 各行の末尾は改行マーク (CRLF) で終わっています。 各データは、 10 Byte 20 Byte 30 Byte 10 Byte になるように、半角スペースで調整されています。 |
|
≪テスト≫ このテキストファイルを、一旦インポートウィザードを使用して取り込んでみます。 ![]() ←左は 取り込んだ結果です。 一見正しく取り込まれているように見えますが よく見ると、 12 行目と 28 行目のデータの一部がずれているのがわかります。 「jpg」 の 「j」 の文字が手前の列の後ろにくっついています。 やはり、標準の機能ではうまくいかないようです。 気を取り直して、VBA で取り込む準備をします。 |
|
≪準備2≫ VBA でデータを取り込む前に、空のテーブルを作成します。 ![]() ← テーブルは、取り込むファイルに合わせて作成する必要があります。 今回の例では、以下のテーブルを作成しました。 テーブル名: tbl_Hana2_IN
※ オートナンバー型は使用できません。エラーとなります。 ※ フィールド名はなんでもかまいません。 データの内容にあった名前を付けます。 ※ フィールドの型はすべてテキスト型でも OK です。ただし、文字列が入るだけの長さが必要です。 | |||||||||||||||
|
≪準備3≫ テーブル作成後、こちらの 「lenbt関数」 を標準モジュールに貼り付けてください。 全角半角混じりの文字の Byte数を正しく取得する為に必要な関数です。 |
|
≪準備4≫ 最後に、以下のコードを標準モジュールに貼り付けます。
Sub inFixedLengthData()
'固定長テキストファイル(全角半角混じり)を正しくテーブルに取り込む
'全角文字の取込み不具合解消版 2011/04/03 pPoy
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim stSQL As String
Dim myWSH As Object 'WScript
Dim myDesktopPath As String
Dim objFSO As Object 'FileSystemObject
Dim objFileIn As Object 'File
Dim stFileIn As String 'ファイルのフルパス
Dim stLine As String '1行分のテキスト
Dim myTmp As String '1フィールド分のテキスト
Dim stfld(3) As String '★1行分の文字列格納用
Dim fldSize(3) As Integer '★フィールド毎のサイズ(byte)
Dim maxLEN As Long '1行の文字数
Dim startP As Long '開始位置
Dim i As Long, j As Long
Const ForReading = 1
Const txtFileName = "固定長テキストデータ.txt" '★
Const tblName = "tbl_Hana2_IN" '★
'取り出すデータの各byte数を配列に格納
fldSize(0) = 10 '★ID
fldSize(1) = 20 '★FileName
fldSize(2) = 30 '★myMemo
fldSize(3) = 10 '★etc
'デスクトップパス取得
Set myWSH = CreateObject("WScript.Shell")
myDesktopPath = myWSH.SpecialFolders("Desktop")
Set myWSH = Nothing
'テキストファイルのフルパス
stFileIn = myDesktopPath & "\" & txtFileName
'ファイルの存在確認
Set objFSO = CreateObject("Scripting.FileSystemObject")
If Not objFSO.FileExists(stFileIn) Then
Set objFSO = Nothing
Exit Sub
End If
'既存データ削除
Set cnn = CurrentProject.Connection
stSQL = "delete from " & tblName & ";"
cnn.Execute stSQL
DoEvents
'空のテーブル open
Set rst = New ADODB.Recordset
stSQL = "select * from " & tblName & ";"
rst.Open stSQL, cnn, adOpenKeyset, adLockOptimistic
'取込み開始
Set objFileIn = objFSO.OpenTextFile(stFileIn, ForReading)
Do Until objFileIn.AtEndOfStream
'1行読み込み
stLine = objFileIn.Readline
maxLEN = Len(stLine) '1行の文字数
startP = 1 '読込開始位置
'行内ループ
For i = 0 To UBound(fldSize)
myTmp = ""
'フィールド内ループ
For j = startP To maxLEN
myTmp = myTmp & Mid(stLine, j, 1)
If lenbt(myTmp) = fldSize(i) Then
stfld(i) = myTmp
startP = startP + Len(myTmp)
myTmp = ""
Exit For
End If
Next j
Next i
'テーブルに格納
With rst
.AddNew
For i = 0 To UBound(stfld)
rst(i).Value = stfld(i)
Next i
.Update
End With
Loop
MsgBox "処理修了!", vbOKOnly
rst.Close: Set rst = Nothing: Set cnn = Nothing
Set objFileIn = Nothing: Set objFSO = Nothing
End Sub
|
≪結果≫![]() ← 全てのデータが正しく取り込まれています。 |
≪補足≫
|