0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CSVデータの改行ズレを変換するVBAマクロを作成する

Last updated at Posted at 2021-06-20

■経緯

 Redmineサーバーのデータバックアップで、CSV出力する際に、「カラム囲み記号:」を指定できない(ダブルクォーテーションで囲めない)事態が発生し、改行コードが問題となってデータ復旧できなくなってしまった。
 ※MySQLでは「カラム囲み記号:」の指定は可能であるが、今回バックアップしたredmineサーバーはMySQL以外のDBで運用されていた。

■環境:

 ・Redmine3.4
 ・Excel 2019 64bit

■やりたいこと:

 ・改行を含む情報をもつCSVデータを通常の形式に復旧させたい
  ※復旧後に開業コードを含まなくてもとりあえずは良しとする。
 ・修正前
image.png

 ・修正後
image.png

■復旧作業をEXCELのVBA環境で実装

 ・凝ったものは要らないので、最低限EXCELにCSVデータを貼り付けてマクロを実施する程度のオペレーションに留め、
 ・コードを作成し、対象のデータが目的通りに修正されるかを確認する。
 ・文字列の復旧は再帰処理で実装する。

■コード

Module1.vba
Public endsellrow As Long
Public endsellcolumn As Long
Sub Restore()
    Dim chkcolumn As Long
    Dim temp As String
    Dim i As Long
    Dim j As Long
    Dim rst As Long
    rst = 1
    '先頭行と最終行には正しいデータが入っている前提
    endsellrow = Cells(Rows.Count, 1).End(xlUp).Row
    endsellcolumn = Cells(1, Columns.Count).End(xlToLeft).Column
    For i = 2 To endsellrow
        chkcolumn = Cells(i, Columns.Count).End(xlToLeft).Column
        If chkcolumn <> endsellcolumn Then
            temp = Cells(i, chkcolumn) 'データを退避
            rst = i '問題の発生した行(復旧対象)
            i = RecursiveRestore(i, temp)
            Cells(rst, chkcolumn) = temp 'データ修復(改行されたものをまとめる)
            For j = 1 To Cells(i, Columns.Count).End(xlToLeft).Column - 1   'データ修復(復旧先の「,」は飛ばす)
                Cells(rst, chkcolumn + j) = Cells(i, j + 1)
            Next j
            rst = rst + 1
            Rows(Trim(Str(rst)) & ":" & Trim(Str(i))).Select
            Application.CutCopyMode = False
            Selection.ClearContents’復旧後に不要なデータをクリア
        End If
    Next i
End Sub
Function RecursiveRestore(i As Long, temp As String)
    If i < endsellrow Then
        i = i + 1
        chkcolumn = Cells(i, Columns.Count).End(xlToLeft).Column
        If chkcolumn <= 1 Then
            temp = temp + Cells(i, chkcolumn) 'データを退避
            i = RecursiveRestore(i, temp)
        End If
    End If
    RecursiveRestore = i
End Function

■デバッグ:

・実行結果
 動作させるとデータは復旧する。修正して不要になった行は削除しようかと思ったがクリア処理にとどめた。
 ※後で空白行を削除するほうがリスクが少ないと判断した。必要があればクリア処理を各自で削除処理に変更してほしい
image.png

以上です、お疲れ様です。

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?