Help us understand the problem. What is going on with this article?

ORACLE用INSERT文生成Excelマクロ

More than 1 year has passed since last update.

テストデータ作るときにあると便利なので、
VBAの復習も兼ねて自作してみました。
Excelがあればどこでも動くはず。

●Excelシート構成

1.Mainシート
B2セル:スキーマ名
B3セル:テーブル名
B4セル:出力先シート名
B5~XFD5セル:DB項目名
B6~XFD6セル:データ型(文字列、NUMBER、日付、TIMESTAMPのみ)
B7~XFD1048576セル:登録するデータ
2.結果出力シート
MainシートB4セルで指定したシート名でシートを作る

●VBA内容

Option Base 1
Option Explicit
'***********************
'*Main処理
'***********************
Sub main()
    Dim scmName As String
    Dim tblName As String
    Dim tblClmName As Variant
    Dim dataType As Variant
    Dim dataVal As Variant
    Dim clmLen As Long
    Dim valRowLen As Long
    Dim head As String
    Dim sql() As String
    Dim i, j As Long
    Dim typeErr As Long
    Dim strTblClmName As String
    Dim strDataType As String
    Dim strDataVal As String


    typeErr = 0

    'スキーマ名を取得する
    scmName = getSchName()

    'テーブル名を取得する
    tblName = getTblName

    '対象項目の項目名を配列で取得する
    tblClmName = getTblClmName
    clmLen = UBound(tblClmName, 2)

    '対象項目のデータ型を配列で取得する
    dataType = getDataType

    '対象項目のデータを配列で取得する
    dataVal = getDataVal
    valRowLen = UBound(dataVal, 1)

    'SQL文を作成する
    ReDim sql(valRowLen)

    head = "INSERT INTO " + scmName + "." + tblName + "("
    For i = 1 To clmLen
        If i <> 1 Then
            head = head + ", "
        End If
        head = head + tblClmName(1, i)
    Next
    head = head + ")"

    For i = 1 To valRowLen
        sql(i) = head + " values ("
        For j = 1 To clmLen
            If j <> 1 Then
                sql(i) = sql(i) + ", "
            End If

            If IsEmpty(dataType(1, j)) Then
                strDataType = ""
            Else
                strDataType = dataType(1, j)
            End If
            If IsEmpty(dataVal(i, j)) Then
                strDataVal = ""
            Else
                strDataVal = dataVal(i, j)
            End If

            Select Case True
                Case strDataType Like "*CHAR*"
                    sql(i) = sql(i) + "'" + strDataVal + "' "
                Case strDataType Like "*NUMBER*"
                    If Trim(strDataVal) = "" Then
                        sql(i) = sql(i) + "NULL"
                    Else
                        sql(i) = sql(i) + strDataVal + " "
                    End If
                Case strDataType = "TIMESTAMP"
                    If Trim(strDataVal) = "SYSTIMESTAMP" Then
                        sql(i) = sql(i) + "SYSTIMESTAMP"
                    ElseIf strDataVal <> "" Then
                        sql(i) = sql(i) + "TO_TIMESTAMP('" + strDataVal + "','" + getTimeStampFormat + "')"
                    Else
                        sql(i) = sql(i) + "NULL"
                    End If
                Case strDataType = "DATE"
                    If Trim(strDataVal) = "SYSDATE" Then
                        sql(i) = sql(i) + "SYSDATE"
                    ElseIf Trim(strDataVal) <> "" Then
                        sql(i) = sql(i) + "TO_DATE('" + strDataVal + "','" + getDateFormat + "')"
                    Else
                        sql(i) = sql(i) + "NULL"
                    End If
                Case Else
                    typeErr = -1
            End Select


        Next
        sql(i) = sql(i) + ");"
    Next

    '作成したSQLを結果を出力する
    Dim ws As Worksheet
    Dim wsRst As Worksheet
    Dim outebleflg As Long
    outebleflg = 0
    For Each ws In Sheets
        If ws.name = ThisWorkbook.ActiveSheet.Range("B4").Value Then
            outebleflg = 1
        End If
    Next
    If outebleflg = 1 Then
        Set ws = ThisWorkbook.ActiveSheet
        Set wsRst = ThisWorkbook.Sheets(ws.Range("B4").Value)


        For i = 1 To UBound(sql)
            wsRst.Cells(i, 1).Value = sql(i)
        Next

        If typeErr = -1 Then
            MsgBox "データ型に不備有?問題なければ実行可能。"
        End If
    Else
        MsgBox "出力先シートがない"
    End If

End Sub

'***********************
'スキーマ取得用
'***********************
Function getSchName() As String
    Dim ws As Worksheet
    Set ws = ThisWorkbook.ActiveSheet
    getSchName = ws.Range("B2").Value

End Function

'***********************
'テーブル名取得用
'***********************
Function getTblName() As String
    Dim ws As Worksheet
    Set ws = ThisWorkbook.ActiveSheet
    getTblName = ws.Range("B3").Value

End Function

'***********************
'テーブル項目名取得用
'配列の要素番号は1始まり
'***********************
Function getTblClmName() As Variant
    Dim ws As Worksheet
    Set ws = ThisWorkbook.ActiveSheet
    Dim MaxCol As Long
    MaxCol = ws.UsedRange.Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column
    With ws.UsedRange
        getTblClmName = .Range(.Cells(5, 2), .Cells(5, MaxCol))
    End With

End Function

'***********************
'データ型取得用
'***********************
Function getDataType() As Variant
    Dim ws As Worksheet
    Set ws = ThisWorkbook.ActiveSheet
    Dim MaxCol As Long
    MaxCol = ws.UsedRange.Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column
    With ws.UsedRange
        getDataType = .Range(.Cells(6, 2), .Cells(6, MaxCol))
    End With

End Function

'***********************
'データ取得用
'***********************
Function getDataVal() As Variant
    Dim wb As Workbook
    Set wb = ThisWorkbook
    Dim ws As Worksheet
    Set ws = wb.ActiveSheet
    Dim UsRng  As Range
    Set UsRng = ws.UsedRange
    Dim MaxRow As Long
    Dim MaxCol As Long
    With UsRng
        MaxRow = .Find("*", , xlFormulas, , xlByRows, xlPrevious).row
        MaxCol = .Find("*", , xlFormulas, , xlByColumns, xlPrevious).Column
    End With
    With ws
        getDataVal = .Range(.Cells(7, 2), .Cells(MaxRow, MaxCol))
    End With


End Function


Function getDateFormat() As String
    getDateFormat = "YYYYMMDD"
End Function


Function getTimeStampFormat() As String
    getTimeStampFormat = "YYYYMMDDHH24MISS"
End Function


Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away