SAPシステムからのデータ取得(2)

昨日の続きです。RFC_READ_TABLEの引数と返却値を調べておきます。SAPの汎用モジュールでは、汎用モジュールから見て、受け取るパラメータをIMPORTパラメータ、返却するパラメータをEXPORTパラメータと呼びます。また、双方(送るし、受ける)の役割を行えるテーブルというパラメータもあります。

引数は以下の5つです。割とわかりやすいです。

項目名 説明
QUERY_TABLE 目的のテーブル名(T001は会社コードマスタ)
DELIMITER 返却値"DATA"の区切り文字
NO_DATA データがないときの扱い
ROWSKIPS スキップする行数(デフォルト:スキップしない)
ROWCOUNT 取得する行数(デフォルト:制限しない)

テーブルは以下の3つです。

項目名 説明
OPTIONS WHERE句に相当する部分を設定(デフォルト:指定なし=WHERE句なし)
FIELDS SELECT句に相当する部分を設定(デフォルト:指定なし=全項目取得)
DATA これまでの条件でヒットしたデータ



実行するとこんな感じの画面になります。

FIELDSに77Entry, DATAに57Entryとあります。これは、T001のテーブルには列項目が77あって、データが57件ありますよという意味です。

下の図は、テーブルの項目です。上の図の77Entryの左のアイコンを押下すると中味を見ることができます。

下の図は、取得できたテーブルの内容です。

良く見ると、取得できたデータには区切り文字がありません。DELIMITERに文字を指定すると取得したデータに区切り文字が入ります。よってDELIMITERを指定して、DATAの値を指定したDELIMITERで分割してデータを取得する方法が1つあります。もうひとつの方法としては、FIELDSを見てみるとOFFSETとLENGTHという項目も一緒に渡されてきています。これを使用してDATAの値を分割してゆく方法があります。どちらでもうまくいきますが、前者はデータ内にDELIMITERが入らないように気をつける必要がありますね。

Private Sub rfc_read_tab(tname As String, tfields As String, twhere As String)

    'IMPORTパラメータ
    Dim QUERY_TABLE As Object
    Dim DELIMITER   As Object
    Dim NO_DATA     As Object
    Dim ROWSKIPS    As Object
    Dim ROWCOUNT    As Object
    '条件式
    Dim OPTIONS As Object
    Dim FIELDS  As Object
    'データ
    Dim DATA    As Object
    
    '結果保持用
    Dim ROW As Object
    Dim Result As Boolean
    Dim iRow, iColumn, iStart, iStartRow, iField, iLength As Integer
    
    '*****************************************************
    'RFC_READ_TABLEを指定します
    '*****************************************************
    Set MyFunc = R3.Add("RFC_READ_TABLE")
    Set QUERY_TABLE = MyFunc.exports("QUERY_TABLE")
    Set DELIMITER = MyFunc.exports("DELIMITER")
    Set NO_DATA = MyFunc.exports("NO_DATA")
    Set ROWSKIPS = MyFunc.exports("ROWSKIPS")
    Set ROWCOUNT = MyFunc.exports("ROWCOUNT")
    Set DATA = MyFunc.Tables("DATA")
    Set OPTIONS = MyFunc.Tables("OPTIONS")
    Set FIELDS = MyFunc.Tables("FIELDS")
    
    QUERY_TABLE.Value = tname
    DELIMITER.Value = " "
    NO_DATA = " "
    ROWSKIPS = 0
    ROWCOUNT = 0

    Result = MyFunc.Call
    
    If Result = True Then
      Set DATA = MyFunc.Tables("DATA")
      Set FIELDS = MyFunc.Tables("FIELDS")
      Set OPTIONS = MyFunc.Tables("OPTIONS")
    Else
        MsgBox MyFunc.EXCEPTION
        Exit Sub
    End If
    
    '列名をExcelシートに出力
    For iField = 1 To FIELDS.ROWCOUNT
        NewSheet.Cells(1, iField).Value = FIELDS(iField, "FIELDNAME")
    Next
    
    'データをExcelシートに出力
    iField = 1
    For iRow = 1 To DATA.ROWCOUNT
        For iField = 1 To FIELDS.ROWCOUNT
            iStart = FIELDS(iField, "OFFSET") + 1
            iLength = FIELDS(iField, "LENGTH")
    
            If iStart > Len(DATA(iRow, "WA")) Then
                vField = Null
            Else
                vField = Mid(DATA(iRow, "WA"), iStart, iLength)
            End If
            NewSheet.Cells(iRow + 1, iField).Value = vField
        Next
    Next
    
    ' ****************************************************
    ' Release Object
    ' ****************************************************
    Set MyFunc = Nothing
    Set QUERY_TABLE = Nothing
    Set DELIMITER = Nothing
    Set NO_DATA = Nothing
    Set ROWSKIPS = Nothing
    Set ROWCOUNT = Nothing
    Set OPTIONS = Nothing
    Set FIELDS = Nothing
    
End Sub

Private Function Split(ByVal inp As String, Optional delim As String = ",") As Variant
    
    Dim outarray() As Variant
    Dim arrsize As Integer
    While InStr(inp, delim) > 0
        ReDim Preserve outarray(0 To arrsize) As Variant
        outarray(arrsize) = Left(inp, InStr(inp, delim) - 1)
        inp = Mid(inp, InStr(inp, delim) + 1)
        arrsize = arrsize + 1
    Wend
    
    ReDim Preserve outarray(0 To arrsize) As Variant
    outarray(arrsize) = inp
    Split = outarray

End Function

結構面倒ですが、一度書いておけば使いまわせるのでお勧めです。