■固定長ファイル
1行の長さが一定であるファイルを固定長ファイルという。
一般的に桁数や行数でデータ項目を判断し、それぞれ区分けしたデータをインプットとして読み込む。
■固定長ファイル(例)
固定長ファイルの例を示す。
▼INPUTDATA.txt
1202108077
5A00300030
5B00310034
5B00360037
5A00330034
5C00310032
5D00200019
5D00240020
5C00450040
5F00330030
5B00300030
5C00460049
5A00320030
5E00320032
5F00370039
5A00390032
5D00290028
5C00280025
5B00280028
5A00270030
9000000019
■固定長ファイルのレイアウト
一般的に固定長ファイルを扱う場合は、固定長ファイルに対応するファイルレイアウトが存在する。
上記「INPUTDATA.txt」のファイルレイアウトは以下の通り
▼ヘッダー行のレイアウト
項目 | 桁数 | 備考 |
---|---|---|
レコード区分 | 1 | 値が「1」の場合はヘッダーレコード |
日付 | 8 | YYYYMMDD形式 |
曜日 | 1 | 1:日曜日 2:月曜日 3:火曜日 4:水曜日 5:木曜日 6:金曜日 7:土曜日 |
▼データ行のレイアウト
項目 | 桁数 | 備考 |
---|---|---|
レコード区分 | 1 | 値が「5」の場合はデータレコード |
品種 | 1 | – |
高さ | 4 | – |
重さ | 4 | – |
▼フッター行のレイアウト
項目 | 桁数 | 備考 |
---|---|---|
レコード区分 | 1 | 値が「9」の場合はフッターレコード |
データ件数 | 9 | データレコードの件数 |
■固定長ファイル分割ツールの仕様
固定長ファイル分割ツールの仕様を以下の通り示す。
(1)[Main]シートにファイル名(フルパス)を指定し、【分割】ボタン押下で処理を開始する。
(2) ヘッダー/データ/トレーラシートを初期化する。
なお、各シートの1行目は項目説明欄のため、初期化せずに残す。
▼ヘッダーシート
▼データシート
▼フッターシート
(3)レイアウトシートからヘッダー/データ/フッターシートの区切り桁数を取得。
(4)「 INPUTDATA.txt 」を1行ずつループ処理し、各シート(ヘッダー/データ/フッター)へ分割した項目を貼り付けていく。
■サンプルコード
' シート名の定数
Private Const SHTNAME_MAIN As String = "Main"
Private Const SHTNAME_HEADER As String = "ヘッダー"
Private Const SHTNAME_DATA As String = "データ"
Private Const SHTNAME_FOOTER As String = "フッター"
Private Const SHTNAME_LAYOUT As String = "レイアウト"
' Mainシートの定数
Private Const INPUT_LOW As Integer = 3 ' 固定長ファイル名読み込み行
Private Const INPUT_COL As Integer = 4 ' 固定長ファイル名読み込み列
' ヘッダー/データ/フッターシート共通定数
Private Const START_LOW As Integer = 2 ' 分割した固定長ファイル表示開始行
Private Const START_COL As Integer = 1 ' 分割した固定長ファイル表示開始行
' レイアウトシートの定数
Private Const START_BYTE_LOW As Integer = 3 ' 区切りバイト数表示行
Private Const START_BYTE_HCOL As Integer = 3 ' ヘッダー区切りバイト数表示列
Private Const START_BYTE_DCOL As Integer = 5 ' データ区切りバイト数表示列
Private Const START_BYTE_FCOL As Integer = 7 ' フッター区切りバイト数表示列
' ヘッダー/データ/フッターシートの初期化関数
Private Sub Init_Sheets(ShtHeader As Worksheet, ShtData As Worksheet, ShtFooter As Worksheet)
' ヘッダー/データ/フッターシートの初期化
ShtHeader.Range("2:1048576").ClearContents
ShtData.Range("2:1048576").ClearContents
ShtFooter.Range("2:1048576").ClearContents
End Sub
' レイアウトシートから区切り桁数を取得する関数
Private Function InpuFLayOut(ShFLayOut As Worksheet, bunkatsu_col As Integer) As Integer()
Dim layout() As Integer ' 戻り値用の配列
Dim irow As Integer ' 行カウンタ
Dim i As Integer ' 配列用カウンタ
' 初期値をセット
irow = START_BYTE_LOW
i = 0
' レイアウトシートで作業
With ShFLayOut
' 対象(ヘッダー/データ/フッター)の表示区切り桁数分繰り返し
Do Until .Cells(irow, bunkatsu_col).Value = ""
ReDim Preserve layout(i)
' 区切り桁数を配列へ格納
layout(i) = .Cells(irow, bunkatsu_col).Value
' インクリメント
irow = irow + 1
i = i + 1
Loop
End With
' 戻り値を設定
InpuFLayOut = layout()
End Function
' 分割処理
Private Sub Bunkatsu(InputSheet As Worksheet, layout() As Integer, startrow As Integer, strLine As String)
Dim icol As Integer ' 列カウンタ
Dim i As Integer ' 配列用カウンタ
Dim startbyte As Integer ' 区切り開始桁数を格納する変数
Dim bunkatsubyte As Integer ' 区切り桁数を格納する変数
' 作業シートにフォーカス
With InputSheet
' 初期値を設定
icol = START_COL
' 分割区切り桁数開始位置の初期化
startbyte = layout(0)
' 分割区切り桁数の要素数分ループ処理
For i = 0 To UBound(layout)
' 分割区切り桁数表示行の値をセット
bunkatsubyte = layout(i)
' 固定長ファイルの値を分割して、セルに値を入れる
.Cells(startrow, icol).Value = Mid(strLine, startbyte, bunkatsubyte)
' 分割区切り桁数開始位置をインクリメント
startbyte = startbyte + bunkatsubyte
' 列カウンタをインクリメント
icol = icol + 1
Next
End With
End Sub
' 分割ボタン押下時の処理(メイン処理)
Public Sub Click_Btn_Bunkatsu()
' 変数宣言
Dim ShtMain As Worksheet ' Mainシートの変数
Dim ShtHeader As Worksheet ' ヘッダーシートの変数
Dim ShtData As Worksheet ' データシートの変数
Dim ShtFooter As Worksheet ' フッターシートの変数
Dim ShFLayOut As Worksheet ' レイアウトシートの変数
Dim FileName As String ' Mainシートのファイル名を格納する変数
Dim fso As Object ' ファイルオブジェクトの変数
Dim openfile As Object ' ファイルの中身を格納する変数
Dim strLine As String ' ファイルを1行ずつ格納するようの変数
Dim HiRow As Integer ' ヘッダーシート用行カウンタ
Dim DiRow As Integer ' データシート用行カウンタ
Dim FiRow As Integer ' フッターシート用行カウンタ
Dim HLayOut() As Integer ' ヘッダー用区切り桁数を格納する配列
Dim DLayOut() As Integer ' データ用区切り桁数を格納する配列
Dim FLayOut() As Integer ' フッター用区切り桁数を格納する配列
' エラーハンドリング
On Error GoTo Click_Btn_Bunkatsu_ERROR
Set ShtMain = Sheets(SHTNAME_MAIN) ' Mainシートを格納
Set ShtHeader = Sheets(SHTNAME_HEADER) ' ヘッダーシートを格納
Set ShtData = Sheets(SHTNAME_DATA) ' データシートを格納
Set ShtFooter = Sheets(SHTNAME_FOOTER) ' フッターシートを格納
Set ShFLayOut = Sheets(SHTNAME_LAYOUT) ' レイアウトシートを格納
' ヘッダー/データ/フッターシートの初期化
Call Init_Sheets(ShtHeader, ShtData, ShtFooter)
' 初期値の設定
HiRow = START_LOW
DiRow = START_LOW
FiRow = START_LOW
' レイアウトシートからヘッダー/データ/フッターシートの区切り桁数を取得
HLayOut() = InpuFLayOut(ShFLayOut, START_BYTE_HCOL)
DLayOut() = InpuFLayOut(ShFLayOut, START_BYTE_DCOL)
FLayOut() = InpuFLayOut(ShFLayOut, START_BYTE_FCOL)
' ファイル名(フルパスを取得)
FileName = ShtMain.Cells(INPUT_LOW, INPUT_COL).Value
' FileSystemObjectのインスタンス
Set fso = CreateObject("Scripting.FileSystemObject")
' 固定長ファイルを開く
Set openfile = fso.opentextfile(FileName)
' 固定長ファイルの最終行までループ処理
Do Until openfile.AtEndOfStream = True
' 1行を文字列に格納
strLine = openfile.ReadLine
' 1バイト目が「1」ならばヘッダーシートに分割
If Mid(strLine, 1, 1) = 1 Then
' 分割処理呼び出し
Call Bunkatsu(ShtHeader, HLayOut(), HiRow, strLine)
' ヘッダーシート用行カウンタをインクリメント
HiRow = HiRow + 1
' 1バイト目が「5」ならばデーターシートに分割
ElseIf Mid(strLine, 1, 1) = 5 Then
' 分割処理呼び出し
Call Bunkatsu(ShtData, DLayOut(), DiRow, strLine)
' データシート用行カウンタをインクリメント
DiRow = DiRow + 1
' 1バイト目が「9」ならばフッターシートに分割
ElseIf Mid(strLine, 1, 1) = 9 Then
' 分割処理呼び出し
Call Bunkatsu(ShtFooter, FLayOut(), FiRow, strLine)
' フッターシート用行カウンタをインクリメント
FiRow = FiRow + 1
End If
Loop
' 完了メッセージを出力
MsgBox "分割完了"
GoTo Click_Btn_Bunkatsu_EXIT
' エラーハンドリング
Click_Btn_Bunkatsu_ERROR:
' エラーメッセージを出力
MsgBox Err.Description
' 終了時の共通処理
Click_Btn_Bunkatsu_EXIT:
' 終了処理
Set ShtMain = Nothing
Set ShtHeader = Nothing
Set ShtData = Nothing
Set ShtFooter = Nothing
Set fso = Nothing
Set openfile = Nothing
Set ShFLayOut = Nothing
End Sub
■実行結果
▼【分割】ボタン押下時
▼ヘッダーシート
▼データシート
▼フッターシート
コメント